librarylibs/Geometry/src/Geometry.xtl
Geometry: plane geometry -- points as 2-row matrices, distances, polygon area and centroid, rotation, scaling and moves, convex hulls, pictures. Import it with an alias of your choice: "ge:" u_se< "Geometry". Put libs/Geometry/src on XETAL_PATH ("just path"); the reference is libs/Geometry/docs. Names with l: are exported; those under h: are private to this file.
Points are a matrix of 2 rows, x over y, one point per column, as X_eTaL's []P_ATH takes them; a polygon is its corners in order. Results are Floats.
Distance and area
ˡd̲istances : Num a => a -> Float
d_istances p: the distance between every pair of points (a matrix).
ˡd̲istances ← { p → dx ← (ʰx̲s p) '− t̲able ʰx̲s p dy ← (ʰy̲s p) '− t̲able ʰy̲s p ((dx × dx) + dy × dy) ^ 0.5 }
ʰs̲igned : Num a => a -> Float
The polygon's area, signed: positive when the corners go round anticlockwise (the shoelace formula).
ʰs̲igned ← { p → x ← ʰx̲s p◆ y ← ʰy̲s p◆ 0.5 × '+ r̲/ (x × 1 o̲- y) − y × 1 o̲- x }
ˡa̲rea : Num a => a -> Float
a_rea p: the area of the polygon.
ˡa̲rea ← { p → a̲bs ʰs̲igned p }
Moves
ˡc̲entroid : Num a => a -> Float
c_entroid p: the polygon's center of mass, x and y.
ˡc̲entroid ← { p → 0.000000000001 > a̲bs ʰs̲igned p ? @ p̲anic< "the polygon has no area (its corners are in a line): its centroid is undefined" x ← ʰx̲s p y ← ʰy̲s p c ← (x × 1 o̲- y) − y × 1 o̲- x k ← 1.0 ÷ 6.0 × ʰs̲igned p (k × '+ r̲/ c × x + 1 o̲- x) c̲at k × '+ r̲/ c × y + 1 o̲- y }
p̲anic< expands to
(⎕P̲ANIC ("the polygon has no area (its corners are in a line): its centroid is undefined"))
ˡr̲otate : (Num a, Num b) => a -> b -> Float
angle r_otate p: the points turned anticlockwise about the origin by angle (radians).
ˡr̲otate ← { a p → c ← c̲os a s ← s̲in a x ← ʰx̲s p y ← ʰy̲s p (2 c̲at t̲ally x) r̲eshape ((c × x) − s × y) c̲at (s × x) + c × y }
ʰc̲olumn : (Num a, Num b) => a -> b -> Float
Two numbers (or one, used twice) as a column for every point.
ʰc̲olumn ← { d p → o̲\ ((t̲ally ʰx̲s p) c̲at 2) r̲eshape f̲loat d }
ˡs̲cale : (Num a, Num b) => a -> b -> Float
f s_cale p: the points scaled by f about the origin (one factor, or two: x and y).
ˡs̲cale ← { f p → (f̲loat p) × f ʰc̲olumn p }
ˡm̲ove : (Num a, Num b) => a -> b -> Float
d m_ove p: the points moved by d, two numbers dx dy.
ˡm̲ove ← { d p → (f̲loat p) + d ʰc̲olumn p }
Polygons
ʰc̲ross : Num a => a -> Int -> Float
The cross product of (q - c) and (r - c) for every candidate q and every point r: positive where r is left of the line from c to q.
ʰc̲ross ← { p i → x ← ʰx̲s p y ← ʰy̲s p dx ← x − f̲irst i s̲elect x dy ← y − f̲irst i s̲elect y (dx '× t̲able dy) − dy '× t̲able dx }
ʰn̲ext : Num a => a -> Int -> Int
The hull's next corner after corner i: the point with no point to the left of the line to it (the farthest, when several are in line).
ʰn̲ext ← { p i → ok ← ('∧ r̲/₂ 0.000000001 ≥ p ʰc̲ross i) ∧ (r̲ange t̲ally ʰx̲s p) ≠ i d ← i s̲elect ˡd̲istances p f̲irst g̲rade n̲eg d × f̲loat ok }
ʰw̲alk : Num a => a -> Int -> Int -> Int -> Int
The corners from i round to the start s, in order.
ʰw̲alk ← { p s i acc → j ← p ʰn̲ext i j = s ? acc ((((p ʰw̲alk s)_ j)_ acc c̲at j)) }
ˡh̲ull : Num a => a -> a
h_ull p: the convex hull, its corners in order (clockwise from the lowest of the leftmost points), as a polygon.
ˡh̲ull ← { p → x ← ʰx̲s p y ← ʰy̲s p left ← w̲here x = 'm̲in r̲/ x s ← f̲irst (g̲rade (left s̲elect y)) s̲elect left (((p ʰw̲alk s)_ s)_ 1 r̲eshape s) s̲elect₂ p }