-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathutil.go
More file actions
106 lines (94 loc) · 2.05 KB
/
util.go
File metadata and controls
106 lines (94 loc) · 2.05 KB
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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
package mathgl
import (
"fmt"
)
// Polys need to be defined in clock-wise order
type Poly []Vec2
func (p *Poly) Clip(s *Seg2) {
var start int
for start = 0; start < len(*p); start++ {
if s.Right(&(*p)[start]) {
break
}
}
if start == len(*p) {
*p = (*p)[0:0]
return
}
clip1, clip2 := -1, -1
var isect1, isect2 Vec2
for _i := range (*p) {
prev := (_i + start) % len(*p)
i := (_i + start + 1) % len(*p)
if clip1 == -1 {
if s.Left(&(*p)[i]) {
clip1 = i
seg := Seg2{(*p)[i], (*p)[prev]}
isect1 = seg.Isect(s)
}
} else {
if !s.Left(&(*p)[i]) {
clip2 = i
seg := Seg2{(*p)[i], (*p)[prev]}
isect2 = seg.Isect(s)
break
}
}
}
if clip2 == -1 {
return
}
fmt.Printf("Isect at %d: %v, %d: %v\n", clip1, isect1, clip2, isect2)
var clipper Poly
clipper = append(clipper, isect1)
clipper = append(clipper, isect2)
for _i := range *p {
i := (_i + clip2) % len(*p)
if i == clip1 { break }
clipper = append(clipper, (*p)[i])
}
*p = clipper
}
type Seg2 struct {
A, B Vec2
}
func (a Seg2) Ray() Vec2 {
var v Vec2
v.Assign(&a.B)
v.Subtract(&a.A)
return v
}
// Returns a Vec2 indicating the intersection point of the lines passing
// through segments a and b
func (u Seg2) Isect(v *Seg2) Vec2 {
vy := v.B.Y - v.A.Y
vx := v.A.X - v.B.X
n := (v.A.X - u.A.X) * vy + (v.A.Y - u.A.Y) * vx
d := (u.B.X - u.A.X) * vy + (u.B.Y - u.A.Y) * vx
f := n/d
return Vec2{ u.A.X + (u.B.X - u.A.X) * f, u.A.Y + (u.B.Y - u.A.Y) * f}
}
func (a Seg2) DistFromOrigin() float32 {
a_ray := a.Ray()
a_ray.Cross()
r := (Seg2{a_ray, Vec2{0,0}}).Isect(&a)
return r.Length()
}
// Returns true iff u lies to the left of a
func (a Seg2) Left(u *Vec2) bool {
v := a.Ray()
v.Cross()
var v2 Vec2
v2.Assign(u)
v2.Subtract(&a.A)
return v.Dot(&v2) > 0
}
// Returns true iff u lies to the left of a
func (a Seg2) Right(u *Vec2) bool {
v := a.Ray()
v.Cross()
var v2 Vec2
v2.Assign(u)
v2.Subtract(&a.A)
return v.Dot(&v2) < 0
}