sourcelib/Geometry3D.xtl

1⍝# Geometry3D: points in space as arrays (a standard library, built into 2⍝# xetal). Import it with an alias of your choice: "g:" u_se< "Geometry3D". 3⍝# Points are a 3-row matrix, x over y over z, one column per point, as 4⍝# []P_ATH takes 2 rows; a rotation is a 3 x 3 matrix, and turning the 5⍝# points is one inner product. A face is a 3 x 4 matrix of corners, 6⍝# and a solid is faces stacked along a new first axis (F x 3 x 4), so 7⍝# one expression orders them far to near for painting. 8⍝# Names with l: are exported; the others are private to this file. 9 10r̲adians ← { (f̲loat ⍵) × (p̲i @) ÷ 180 } ⍝ private 11 12⍝# The rotation of d degrees about the x axis (y toward z), 3 x 3. 13⍝# >> "g:" u_se< "Geometry3D" 14⍝# >> f_loor 0.5 + g:r_otX 90 15⍝# 1 0 0 16⍝# 0 0 -1 17⍝# 0 1 0 18ˡr̲otX ← { d → 19 c ← c̲os r̲adians d 20 s ← s̲in r̲adians d 21 3 3 r̲eshape 1.0 0.0 0.0 0.0 c̲at c c̲at (n̲eg s) c̲at 0.0 c̲at s c̲at c 22} 23 24⍝# The rotation of d degrees about the y axis (z toward x), 3 x 3. 25⍝# >> "g:" u_se< "Geometry3D" 26⍝# >> f_loor 0.5 + g:r_otY 90 27⍝# 0 0 1 28⍝# 0 1 0 29⍝# -1 0 0 30ˡr̲otY ← { d → 31 c ← c̲os r̲adians d 32 s ← s̲in r̲adians d 33 3 3 r̲eshape c c̲at 0.0 c̲at s c̲at 0.0 1.0 0.0 c̲at (n̲eg s) c̲at 0.0 c̲at c 34} 35 36⍝# The rotation of d degrees about the z axis (x toward y), 3 x 3. 37⍝# >> "g:" u_se< "Geometry3D" 38⍝# >> f_loor 0.5 + g:r_otZ 90 39⍝# 0 -1 0 40⍝# 1 0 0 41⍝# 0 0 1 42ˡr̲otZ ← { d → 43 c ← c̲os r̲adians d 44 s ← s̲in r̲adians d 45 3 3 r̲eshape c c̲at (n̲eg s) c̲at 0.0 c̲at s c̲at c c̲at 0.0 0.0 0.0 1.0 46} 47 48⍝# The points turned by a rotation (or moved by any 3 x 3 matrix): 49⍝# m ᵍt̲urn points. Rotations compose by g:t_urn too, the rightmost 50⍝# applied first: (ᵍr̲otX 30) ᵍt̲urn ᵍr̲otY 45. 51⍝# >> "g:" u_se< "Geometry3D" 52⍝# >> f_loor 0.5 + (g:r_otZ 90) g:t_urn 3 1 r_eshape 1 0 0 53⍝# 0 54⍝# 1 55⍝# 0 56ˡt̲urn ← { m points → m '+ '× i̲nner points } 57 58⍝# The points as seen by a viewer at distance d up the z axis, looking 59⍝# at the origin, as 2 rows (x over y) for []P_ATH: a nearer point (a 60⍝# larger z) is drawn farther from the center. d ᵍp̲roject points. 61⍝# >> "g:" u_se< "Geometry3D" 62⍝# >> 10 g:p_roject 3 2 r_eshape 1 1 1 1 0 5 63⍝# 1.0 2.0 64⍝# 1.0 2.0 65ˡp̲roject ← { d points → 66 scale ← (f̲loat d) ÷ (f̲loat d) − 3 s̲elect points 67 (2 t̲ake points) × (2 c̲at t̲ally scale) r̲eshape scale 68} 69 70⍝# How near each face of a solid is to the viewer: the mean z of its 71⍝# corners, one number per face (F x 3 x 4 to F); larger is nearer. 72⍝# >> "g:" u_se< "Geometry3D" 73⍝# >> g:f_ar 2 3 1 r_eshape 0 0 -3 0 0 2 74⍝# -3.0 2.0 75ˡf̲ar ← { faces → (f̲loat '+ r̲/ o̲\ 3 s̲elect₂ faces) ÷ f̲loat 1 s̲elect r̲ev s̲hape faces } 76 77⍝# The faces of a solid from the farthest to the nearest, as positions 78⍝# (the order to draw them in, so nearer faces cover farther ones). 79⍝# >> "g:" u_se< "Geometry3D" 80⍝# >> g:o_rder 2 3 1 r_eshape 0 0 2 0 0 -3 81⍝# 2 1 82ˡo̲rder ← { faces → g̲rade ˡf̲ar faces } 83 84⍝# The 8 corners of a cube of side s centered on the origin, 3 x 8, in 85⍝# the order near face (z = s/2, toward the viewer) then far face, each 86⍝# anticlockwise from the top left. 87⍝# >> "g:" u_se< "Geometry3D" 88⍝# >> s_hape g:c_ube 2 89⍝# 3 8 90ˡc̲ube ← { s → 91 h ← (f̲loat s) ÷ 2 92 h × 3 8 r̲eshape -1 1 1 -1 -1 1 1 -1 1 1 -1 -1 1 1 -1 -1 1 1 1 1 -1 -1 -1 -1 93} 94 95⍝# The six faces of the cube corners g:c_ube gives, as corner positions, 96⍝# 6 x 4: front, back, top, bottom, left, right. 97⍝# >> "g:" u_se< "Geometry3D" 98⍝# >> 1 s_elect g:c_ubeFaces @ 99⍝# 1 2 3 4 100ˡc̲ubeFaces ← { @ → 6 4 r̲eshape 1 2 3 4 5 6 7 8 1 2 6 5 4 3 7 8 1 4 8 5 2 3 7 6 } 101 102⍝# One face of a solid's points: the corners at the given positions, 103⍝# as a 3 x n matrix. positions ᵍf̲ace points. 104⍝# >> "g:" u_se< "Geometry3D" 105⍝# >> 1 2 g:f_ace g:c_ube 2 106⍝# -1.0 1.0 107⍝# 1.0 1.0 108⍝# 1.0 1.0 109ˡf̲ace ← { positions points → positions s̲elect₂ points } 110 111⍝# Every face of a solid as corners: F x 3 x n from the points and the 112⍝# F x n positions of g:c_ubeFaces. faces ᵍs̲olid points. 113⍝# >> "g:" u_se< "Geometry3D" 114⍝# >> s_hape (g:c_ubeFaces @) g:s_olid g:c_ube 2 115⍝# 6 3 4 116ˡs̲olid ← { faces points → 2 1 3 t̲ranspose (3 c̲at s̲hape faces) r̲eshape (r̲avel faces) s̲elect₂ points }