11d3 . geo . greatArc = function ( ) {
2- var source = d3_geo_greatArcSource ,
3- target = d3_geo_greatArcTarget ,
4- precision = 6 * d3_geo_radians ;
2+ var source = d3_geo_greatArcSource , p0 ,
3+ target = d3_geo_greatArcTarget , p1 ,
4+ precision = 6 * d3_geo_radians ,
5+ interpolate = d3_geo_greatArcInterpolator ( ) ;
56
67 function greatArc ( ) {
7- var a = typeof source === "function" ? source . apply ( this , arguments ) : source ,
8- b = typeof target === "function" ? target . apply ( this , arguments ) : target ,
9- i = d3_geo_greatArcInterpolate ( a , b ) ,
10- dt = precision / i . d ,
8+ var d = greatArc . distance . apply ( this , arguments ) , // initializes the interpolator, too
119 t = 0 ,
12- coordinates = [ a ] ;
13- while ( ( t += dt ) < 1 ) coordinates . push ( i ( t ) ) ;
14- coordinates . push ( b ) ;
15- return {
16- type : "LineString" ,
17- coordinates : coordinates
18- } ;
10+ dt = precision / d ,
11+ coordinates = [ p0 ] ;
12+ while ( ( t += dt ) < 1 ) coordinates . push ( interpolate ( t ) ) ;
13+ coordinates . push ( p1 ) ;
14+ return { type : "LineString" , coordinates : coordinates } ;
1915 }
2016
2117 // Length returned in radians; multiply by radius for distance.
2218 greatArc . distance = function ( ) {
23- var a = typeof source === "function" ? source . apply ( this , arguments ) : source ,
24- b = typeof target === "function" ? target . apply ( this , arguments ) : target ;
25- return d3_geo_greatArcInterpolate ( a , b ) . d ;
19+ if ( typeof source === "function" ) interpolate . source ( p0 = source . apply ( this , arguments ) ) ;
20+ if ( typeof target === "function" ) interpolate . target ( p1 = target . apply ( this , arguments ) ) ;
21+ return interpolate . distance ( ) ;
2622 } ;
2723
28- greatArc . source = function ( x ) {
24+ greatArc . source = function ( _ ) {
2925 if ( ! arguments . length ) return source ;
30- source = x ;
26+ source = _ ;
27+ if ( typeof source !== "function" ) interpolate . source ( p0 = source ) ;
3128 return greatArc ;
3229 } ;
3330
34- greatArc . target = function ( x ) {
31+ greatArc . target = function ( _ ) {
3532 if ( ! arguments . length ) return target ;
36- target = x ;
33+ target = _ ;
34+ if ( typeof target !== "function" ) interpolate . target ( p1 = target ) ;
3735 return greatArc ;
3836 } ;
3937
4038 // Precision is specified in degrees.
41- greatArc . precision = function ( x ) {
39+ greatArc . precision = function ( _ ) {
4240 if ( ! arguments . length ) return precision / d3_geo_radians ;
43- precision = x * d3_geo_radians ;
41+ precision = _ * d3_geo_radians ;
4442 return greatArc ;
4543 } ;
4644
@@ -55,26 +53,56 @@ function d3_geo_greatArcTarget(d) {
5553 return d . target ;
5654}
5755
58- function d3_geo_greatArcInterpolate ( a , b ) {
59- var x0 = a [ 0 ] * d3_geo_radians , cx0 = Math . cos ( x0 ) , sx0 = Math . sin ( x0 ) ,
60- y0 = a [ 1 ] * d3_geo_radians , cy0 = Math . cos ( y0 ) , sy0 = Math . sin ( y0 ) ,
61- x1 = b [ 0 ] * d3_geo_radians , cx1 = Math . cos ( x1 ) , sx1 = Math . sin ( x1 ) ,
62- y1 = b [ 1 ] * d3_geo_radians , cy1 = Math . cos ( y1 ) , sy1 = Math . sin ( y1 ) ,
63- d = interpolate . d = Math . acos ( Math . max ( - 1 , Math . min ( 1 , sy0 * sy1 + cy0 * cy1 * Math . cos ( x1 - x0 ) ) ) ) ,
64- sd = Math . sin ( d ) ;
56+ function d3_geo_greatArcInterpolator ( ) {
57+ var x0 , y0 , cy0 , sy0 , kx0 , ky0 ,
58+ x1 , y1 , cy1 , sy1 , kx1 , ky1 ,
59+ d ,
60+ k ;
6561
66- // From http://williams.best.vwh.net/avform.htm#Intermediate
6762 function interpolate ( t ) {
68- var A = Math . sin ( d - ( t *= d ) ) / sd ,
69- B = Math . sin ( t ) / sd ,
70- x = A * cy0 * cx0 + B * cy1 * cx1 ,
71- y = A * cy0 * sx0 + B * cy1 * sx1 ,
72- z = A * sy0 + B * sy1 ;
63+ var B = Math . sin ( t *= d ) * k ,
64+ A = Math . sin ( d - t ) * k ,
65+ x = A * kx0 + B * kx1 ,
66+ y = A * ky0 + B * ky1 ,
67+ z = A * sy0 + B * sy1 ;
7368 return [
7469 Math . atan2 ( y , x ) / d3_geo_radians ,
7570 Math . atan2 ( z , Math . sqrt ( x * x + y * y ) ) / d3_geo_radians
7671 ] ;
7772 }
7873
74+ interpolate . distance = function ( ) {
75+ if ( d == null ) k = 1 / Math . sin ( d = Math . acos ( Math . max ( - 1 , Math . min ( 1 , sy0 * sy1 + cy0 * cy1 * Math . cos ( x1 - x0 ) ) ) ) ) ;
76+ return d ;
77+ } ;
78+
79+ interpolate . source = function ( _ ) {
80+ var cx0 = Math . cos ( x0 = _ [ 0 ] * d3_geo_radians ) ,
81+ sx0 = Math . sin ( x0 ) ;
82+ cy0 = Math . cos ( y0 = _ [ 1 ] * d3_geo_radians ) ;
83+ sy0 = Math . sin ( y0 ) ;
84+ kx0 = cy0 * cx0 ;
85+ ky0 = cy0 * sx0 ;
86+ d = null ;
87+ return interpolate ;
88+ } ;
89+
90+ interpolate . target = function ( _ ) {
91+ var cx1 = Math . cos ( x1 = _ [ 0 ] * d3_geo_radians ) ,
92+ sx1 = Math . sin ( x1 ) ;
93+ cy1 = Math . cos ( y1 = _ [ 1 ] * d3_geo_radians ) ;
94+ sy1 = Math . sin ( y1 ) ;
95+ kx1 = cy1 * cx1 ;
96+ ky1 = cy1 * sx1 ;
97+ d = null ;
98+ return interpolate ;
99+ } ;
100+
79101 return interpolate ;
80102}
103+
104+ function d3_geo_greatArcInterpolate ( a , b ) {
105+ var i = d3_geo_greatArcInterpolator ( ) . source ( a ) . target ( b ) ;
106+ i . distance ( ) ;
107+ return i ;
108+ }
0 commit comments