toolkit/exemples/couple/javascript/d3/src/geo/greatArc.js
changeset 47 c0b4a8b5a012
equal deleted inserted replaced
46:efd9c589177a 47:c0b4a8b5a012
       
     1 d3.geo.greatArc = function() {
       
     2   var source = d3_geo_greatArcSource,
       
     3       target = d3_geo_greatArcTarget,
       
     4       precision = 6 * d3_geo_radians;
       
     5 
       
     6   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,
       
    11         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     };
       
    19   }
       
    20 
       
    21   // Length returned in radians; multiply by radius for distance.
       
    22   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;
       
    26   };
       
    27 
       
    28   greatArc.source = function(x) {
       
    29     if (!arguments.length) return source;
       
    30     source = x;
       
    31     return greatArc;
       
    32   };
       
    33 
       
    34   greatArc.target = function(x) {
       
    35     if (!arguments.length) return target;
       
    36     target = x;
       
    37     return greatArc;
       
    38   };
       
    39 
       
    40   // Precision is specified in degrees.
       
    41   greatArc.precision = function(x) {
       
    42     if (!arguments.length) return precision / d3_geo_radians;
       
    43     precision = x * d3_geo_radians;
       
    44     return greatArc;
       
    45   };
       
    46 
       
    47   return greatArc;
       
    48 };
       
    49 
       
    50 function d3_geo_greatArcSource(d) {
       
    51   return d.source;
       
    52 }
       
    53 
       
    54 function d3_geo_greatArcTarget(d) {
       
    55   return d.target;
       
    56 }
       
    57 
       
    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);
       
    65 
       
    66   // From http://williams.best.vwh.net/avform.htm#Intermediate
       
    67   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;
       
    73     return [
       
    74       Math.atan2(y, x) / d3_geo_radians,
       
    75       Math.atan2(z, Math.sqrt(x * x + y * y)) / d3_geo_radians
       
    76     ];
       
    77   }
       
    78 
       
    79   return interpolate;
       
    80 }