Skip to main content
added 105 characters in body
Source Link
Jonathan Allan
  • 115.9k
  • 8
  • 69
  • 294

A dyadic Link that accepts the longitudes on the left and the latitudes, in the same order, on the right and yields the two distances, [direct, surface] in kilometres.

A dyadic Link that accepts the longitudes on the left and the latitudes, in the same order, on the right and yields the two distances, [direct, surface].

A dyadic Link that accepts the longitudes on the left and the latitudes, in the same order, on the right and yields the two distances, [direct, surface] in kilometres.

added 105 characters in body
Source Link
Jonathan Allan
  • 115.9k
  • 8
  • 69
  • 294

Jelly, 2625 bytes

ạ/;°ḊÆSI;°ḊÆS,ÆẠƲP€SÆAHÆSḤ,Ʋ×⁽ßx

Try it online!Try it online!

Note: Since \$\cos\$ is symmetric around the y-axis, we can use \$\lambda_2-\lambda_1\$ in place of \$|\lambda_1-\lambda_2|\$.

The shortest distance between two points in Euclidean space is a straight line, so we have an isosceles triangle with the equal side lengths being the sphere's radius, \$r=6371\$ kilometres, so the direct path in space is (using \$\text{opposite}=\text{hypotenuse}\sin\alpha\$):

ạ/;°ḊÆSI;°ḊÆS,ÆẠƲP€SÆAHÆSḤ,Ʋ×⁽ßx - Link: Longitudes; Latitudes
ạ/I                         - reduceforward difference {Longitudes} by-> absolute[l2 difference
- l1]
 ;                        - concatenate {Latitudes}
  -> [l2 - l1, p1, p2]
  °                       - convert from degrees to radians
          Ʋ                - last four links as a monad f(X=that):
    Ḋ                      -   dequeue {X} -> Latitudes
[p1, p2]
    ÆS                    -   sine -> [sin(p1), sin(p2)]
        ÆẠ                 -   cosine {X} -> [cos(|l1l2 -l2| l1), cos(p1), cos(p2)]
       ,                   -   pair -> [[sin(p1), sin(p2)],
                                       [cos(|l1l2 -l2| l1), cos(p1), cos(p2)]]
           P€              - product of each
             S             - sum
              ÆA           - arccosine -> the central angleCentralAngle
                     Ʋ     - last four links as a monad - f(CentralAngle):
                H          -   halve
                 ÆS        -   sine
                   Ḥ       -   double
                    ,      -   pair -> [2 × sin(CentralAngle / 2),
                                        CentralAngle]
                       ⁽ßx - 6371
                      ×    - multiply -> [6371 × 2 × sin(CentralAngle / 2),
                                          6371 × CentralAngle]
                                       = [direct, surface]

Jelly, 26 bytes

ạ/;°ḊÆS,ÆẠƲP€SÆAHÆSḤ,Ʋ×⁽ßx

Try it online!

The shortest distance between two points in Euclidean space is a straight line, so we have an isosceles triangle with the equal side lengths being the sphere's radius, \$r=6371\$ kilometres, so the direct path in space is (using \$\text{opposite}=\text{hypotenuse}\sin\alpha\$):

ạ/;°ḊÆS,ÆẠƲP€SÆAHÆSḤ,Ʋ×⁽ßx - Link: Longitudes; Latitudes
ạ/                         - reduce {Longitudes} by absolute difference
  ;                        - concatenate {Latitudes}
    °                       - convert from degrees to radians
          Ʋ                - last four links as a monad f(X=that):
    Ḋ                      -   dequeue -> Latitudes
     ÆS                    -   sine -> [sin(p1), sin(p2)]
        ÆẠ                 -   cosine {X} -> [cos(|l1-l2|), cos(p1), cos(p2)]
       ,                   -   pair -> [[sin(p1), sin(p2)], [cos(|l1-l2|), cos(p1), cos(p2)]]
           P€              - product of each
             S             - sum
              ÆA           - arccosine -> the central angle
                     Ʋ     - last four links as a monad - f(CentralAngle):
                H          -   halve
                 ÆS        -   sine
                   Ḥ       -   double
                    ,      -   pair -> [2 × sin(CentralAngle / 2),
                                        CentralAngle]
                       ⁽ßx - 6371
                      ×    - multiply -> [6371 × 2 × sin(CentralAngle / 2),
                                          6371 × CentralAngle]
                                       = [direct, surface]

Jelly, 25 bytes

I;°ḊÆS,ÆẠƲP€SÆAHÆSḤ,Ʋ×⁽ßx

Try it online!

Note: Since \$\cos\$ is symmetric around the y-axis, we can use \$\lambda_2-\lambda_1\$ in place of \$|\lambda_1-\lambda_2|\$.

The shortest distance between two points in Euclidean space is a straight line, so we have an isosceles triangle with the equal side lengths being the sphere's radius, \$r=6371\$ kilometres, so the direct path in space is (using \$\text{opposite}=\text{hypotenuse}\sin\alpha\$):

I;°ḊÆS,ÆẠƲP€SÆAHÆSḤ,Ʋ×⁽ßx - Link: Longitudes; Latitudes
I                         - forward difference {Longitudes} -> [l2 - l1]
 ;                        - concatenate {Latitudes} -> [l2 - l1, p1, p2]
  °                       - convert from degrees to radians
         Ʋ                - last four links as a monad f(X=that):
   Ḋ                      -   dequeue {X} -> [p1, p2]
    ÆS                    -   sine -> [sin(p1), sin(p2)]
       ÆẠ                 -   cosine {X} -> [cos(l2 - l1), cos(p1), cos(p2)]
      ,                   -   pair -> [[sin(p1), sin(p2)],
                                       [cos(l2 - l1), cos(p1), cos(p2)]]
          P€              - product of each
            S             - sum
             ÆA           - arccosine -> CentralAngle
                    Ʋ     - last four links as a monad - f(CentralAngle):
               H          -   halve
                ÆS        -   sine
                  Ḥ       -   double
                   ,      -   pair -> [2 × sin(CentralAngle / 2),
                                       CentralAngle]
                      ⁽ßx - 6371
                     ×    - multiply -> [6371 × 2 × sin(CentralAngle / 2),
                                         6371 × CentralAngle]
                                      = [direct, surface]
Source Link
Jonathan Allan
  • 115.9k
  • 8
  • 69
  • 294

Jelly, 26 bytes

ạ/;°ḊÆS,ÆẠƲP€SÆAHÆSḤ,Ʋ×⁽ßx

A dyadic Link that accepts the longitudes on the left and the latitudes, in the same order, on the right and yields the two distances, [direct, surface].

Try it online!

How?

Labelling the two longitudes as \$\lambda_i\$ and the two latitudes as \$\phi_i\$, the angle between the lines from each of the two points and the centre of the sphere, the central angle, is[1]:

$$\Delta\sigma = \arccos{(\cos{|\lambda_1-\lambda_2|}\cos{\phi_1}\cos{\phi_2}+\sin{\phi_1}\sin{\phi_2})}$$

The shortest distance between two points in Euclidean space is a straight line, so we have an isosceles triangle with the equal side lengths being the sphere's radius, \$r=6371\$ kilometres, so the direct path in space is (using \$\text{opposite}=\text{hypotenuse}\sin\alpha\$):

$$d = 2r \sin \frac{\Delta\sigma}{2}$$

The shortest distance between two points on a sphere is the minor arc of the great circle on which they lie. This is the arc projected by the angle \$\Delta\sigma\$ and thus has length:

$$s = r \Delta\sigma$$

The code takes \$(\lambda_1, \lambda_2)\$ on the left and \$(\phi_1, \phi_2)\$ on the right and produces \$(d, s)\$:

ạ/;°ḊÆS,ÆẠƲP€SÆAHÆSḤ,Ʋ×⁽ßx - Link: Longitudes; Latitudes
ạ/                         - reduce {Longitudes} by absolute difference
  ;                        - concatenate {Latitudes}
   °                       - convert from degrees to radians
          Ʋ                - last four links as a monad f(X=that):
    Ḋ                      -   dequeue -> Latitudes
     ÆS                    -   sine -> [sin(p1), sin(p2)]
        ÆẠ                 -   cosine {X} -> [cos(|l1-l2|), cos(p1), cos(p2)]
       ,                   -   pair -> [[sin(p1), sin(p2)], [cos(|l1-l2|), cos(p1), cos(p2)]]
           P€              - product of each
             S             - sum
              ÆA           - arccosine -> the central angle
                     Ʋ     - last four links as a monad - f(CentralAngle):
                H          -   halve
                 ÆS        -   sine
                   Ḥ       -   double
                    ,      -   pair -> [2 × sin(CentralAngle / 2),
                                        CentralAngle]
                       ⁽ßx - 6371
                      ×    - multiply -> [6371 × 2 × sin(CentralAngle / 2),
                                          6371 × CentralAngle]
                                       = [direct, surface]