-
Notifications
You must be signed in to change notification settings - Fork 0
/
geom-line-loop.stanza
82 lines (61 loc) · 2.71 KB
/
geom-line-loop.stanza
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
defpackage geom/line-loop :
import core
import collections
import math
import utils/seqable
import geom/vec
import geom/box
import geom/line-segment
import geom/polyline
import geom/plane
import geom/mat
import geom/poseable
import geom/shape
public defstruct LineLoop <: AnyShape&Equalable :
state : AnyShapeState with: (as-method => true, default => default-anyshape-state())
vertices : Tuple<Vec3>
with:
constructor => #LineLoop
public defn LineLoop (vs:Seqable<Vec3>) : #LineLoop $ to-tuple $ vs
defmethod equal? (a:LineLoop, b:LineLoop) -> True|False :
vertices(a) == vertices(b)
public defn bounds (c:LineLoop) -> Box3 :
reduce(union, neg-inf-box3(), seq(Box3{xyz(_)}, vertices(c)))
public defn plus (v:Vec3, line:LineLoop) -> LineLoop :
LineLoop(for e in vertices(line) map : v + e)
public defn line-normal (line:LineLoop) -> Vec3 :
val pts = vertices(line)
normalize(normalize(pts[0] - pts[1]) % normalize(pts[2] - pts[1]))
public defn line-center (line:LineLoop) -> Vec3 :
reduce(fn (a:Vec3, b:Vec3) : a + b, vertices(line)) / to-double(length(vertices(line)))
public defn segments (line:LineLoop) -> Seq<LineSegment3> :
for [s, e] in successive-pairs-wrapped(vertices(line)) seq :
LineSegment3(s, e)
public defn segments2 (line:LineLoop) -> Seq<LineSegment2> :
for seg in segments(line) seq :
LineSegment2(xy(start(seg)), xy(end(seg)))
public defn line-inner-radius (line:LineLoop) -> Double :
val center = xy $ line-center(line)
maximum $ for seg in segments2(line) seq : distance(closest-point-to(seg, center), center)
public defn line-outer-radius (line:LineLoop) -> Double :
val center = line-center(line)
maximum $ for v in vertices(line) seq : distance(v, center)
public defn plane (line:LineLoop) -> Plane :
Plane(line-center(line), line-normal(line))
public defn to-polyline (l:LineLoop) -> PolyLine3 :
PolyLine3(state(l), [vertices(l)])
public defn to-lineloop (l:LineSegment3) -> LineLoop :
LineLoop([start(l), end(l)])
public defn to-polyline2 (l:LineLoop) -> PolyLine2 :
PolyLine2(state(l), [for v in vertices(l) map : Vec2(x(v), y(v))])
defmethod clone (l:LineLoop, state:AnyShapeState) -> LineLoop :
#LineLoop(state, vertices(l))
defmethod xyz (mat:Mat4, l:LineLoop) -> LineLoop :
#LineLoop(state(l), to-tuple $ for v in vertices(l) map : mat * v)
defmethod print (o:OutputStream, c:LineLoop) :
val pv = to-tuple(vertices(c)[0 to 100]) when length(vertices(c)) > 100 else vertices(c)
print(o, "LineLoop([%,])" % [pv])
public defn center-transform (normal:Vec3, center:Vec3) -> Mat4 :
mov-mat4(-1.0 * center) * rot-mat4(normal, z3(1.0))
public defn center-transform (line:LineLoop) -> Mat4 :
center-transform(line-normal(line), line-center(line))