sourcedemos/sphere-hello/sphere-hello.xtl
1⍝!/usr/bin/env xetal
2⍝│ Sphere hello: a handful of points on the unit sphere. Two ways to
3⍝│ measure how far apart two of them are, the straight line through
4⍝│ the sphere and the great circle along it, order every point's
5⍝│ neighbors the same way; and the plain average of the points is not
6⍝│ on the sphere, where the mean along it is.
7"mf:" u̲se< "Manifold"
8"ch:" u̲se< "Check"
9
10⍝━━ The points
11
12⍝│ Six directions in three dimensions, chosen by hand (nothing is
13⍝│ random), each put onto the unit sphere: one point per row.
14P ← ᵐᶠs̲phereProject 6 3 r̲eshape 1.0 0.2 0.1 0.9 0.5 0.0 0.3 1.0 0.2 -0.4 0.8 0.5 0.1 0.3 1.0 -0.6 -0.5 0.6
15P
16"every point is on the sphere" ᶜʰt̲est (6 r̲eshape 0.0) ᶜʰn̲ear ᵐᶠs̲phereOff P
17
18⍝━━ Two distances
19
20⍝│ The straight line through the sphere (the chord) between every
21⍝│ pair: the length of the difference, summed one coordinate at a time.
22ᵘc̲hords ← { Q →
23 n ← f̲irst s̲hape Q
24 (D, _) ← (2 s̲elect s̲hape Q) '{ (d, k) → c ← k s̲elect₂ Q◆ (d + (c '− t̲able c) ^ 2.0, k + 1) } p̲ower ((n c̲at n) r̲eshape 0.0, 1)
25 s̲qrt D
26}
27chord ← ᵘc̲hords P
28chord
29
30⍝│ The great circle along the sphere between every pair: the angle,
31⍝│ in radians (Manifold).
32arc ← ᵐᶠs̲phereDistances P
33arc
34
35⍝│ The two agree on a formula: a chord is 2 sin of half its arc, so
36⍝│ the arc can be read off the chord and back. Checked on every pair.
37"chord = 2 sin (arc / 2)" ᶜʰt̲est chord ᶜʰn̲ear 2.0 × s̲in arc ÷ 2.0
38⍝│ And the arc is never the shorter: along the sphere is the long way
39⍝│ round, by a little for near points and by more for far ones.
40"arc >= chord" ᶜʰt̲est 1 ᶜʰn̲ear '∧ r̲/ r̲avel arc ≥ chord
41⍝│ The widest gap between the two, over all the pairs, and the widest arc.
42'm̲ax r̲/ r̲avel arc − chord
43'm̲ax r̲/ r̲avel arc
44
45⍝━━ The same neighbors
46
47⍝│ Each point's neighbors, nearest first (itself first of all, at
48⍝│ distance 0): one row per point, the points' numbers in order of
49⍝│ that row of the distance matrix.
50ᵘo̲rders ← { D →
51 n ← f̲irst s̲hape D
52 (R, _) ← n '{ (acc, i) → (acc c̲at (1 c̲at n) r̲eshape g̲rade i s̲elect D, i + 1) } p̲ower ((0 c̲at n) r̲eshape 0, 1)
53 R
54}
55byChord ← ᵘo̲rders chord
56byChord
57byArc ← ᵘo̲rders arc
58"the chord and the arc order every point's neighbors the same way" ᶜʰt̲est byChord ᶜʰi̲s byArc
59
60⍝━━ Two means
61
62⍝│ The plain mean of the points, coordinate by coordinate: it lies
63⍝│ inside the sphere, and its length says how far in.
64plain ← ('+ r̲/ P) ÷ 6.0
65plain
66s̲qrt '+ r̲/ plain × plain
67"the plain mean is off the sphere" ᶜʰt̲est 1 ᶜʰi̲s 0.0 < ᵐᶠs̲phereOff plain
68
69⍝│ The mean on the sphere (Manifold): the point along the sphere
70⍝│ whose summed squared arcs to the points is least. It is on the
71⍝│ sphere, and it is not the plain mean put onto it.
72onSphere ← ᵐᶠs̲phereMean P
73onSphere
74"the mean on the sphere is on the sphere" ᶜʰt̲est 0.0 ᶜʰn̲ear ᵐᶠs̲phereOff onSphere
75(ᵐᶠs̲phereProject plain) ᵐᶠs̲phereDistance onSphere