79 lines
1.4 KiB
Go
79 lines
1.4 KiB
Go
|
package gg
|
||
|
|
||
|
type Edges []Edge
|
||
|
// Get crosses of edges.
|
||
|
func (what Edges) LineCrossWith(with Edges) ([]LineCross, bool) {
|
||
|
ret := []LineCross{}
|
||
|
for i := range what {
|
||
|
for j := range with {
|
||
|
cross, doCross := LinersCross(what[i], with[j])
|
||
|
if doCross {
|
||
|
ret = append(ret, cross)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if len(ret) == 0 {
|
||
|
return nil, false
|
||
|
}
|
||
|
|
||
|
return ret, true
|
||
|
}
|
||
|
|
||
|
// The type represents a line segment. The name is for short.
|
||
|
type Edge [2]Vector
|
||
|
|
||
|
// Returns corresponding to the segment Line.
|
||
|
func (l Edge) Line() Line {
|
||
|
p0 := l[0]
|
||
|
p1 := l[1]
|
||
|
|
||
|
k := (p0.Y - p1.Y) / (p0.X - p1.X)
|
||
|
c := p0.Y - p0.X*k
|
||
|
|
||
|
return Line{k, c}
|
||
|
}
|
||
|
|
||
|
func (l Edge) ContainedPoints(pts Points) (Points) {
|
||
|
ret := Points{}
|
||
|
for i := range pts {
|
||
|
if l.ContainsPoint(pts[i]) {
|
||
|
ret = append(ret, pts[i])
|
||
|
}
|
||
|
}
|
||
|
return ret
|
||
|
}
|
||
|
|
||
|
// Check if the edge contains the specified point.
|
||
|
func (l Edge) ContainsPoint(p Point) bool {
|
||
|
line := l.Line()
|
||
|
if !line.ContainsPoint(p) {
|
||
|
return false
|
||
|
}
|
||
|
|
||
|
xMax := Max(l[0].X, l[1].X)
|
||
|
xMin := Min(l[0].X, l[1].X)
|
||
|
|
||
|
yMax := Max(l[0].Y, l[1].Y)
|
||
|
yMin := Min(l[0].Y, l[1].Y)
|
||
|
|
||
|
if !(xMin < p.X && p.X < xMax) ||
|
||
|
!(yMin < p.Y && p.Y < yMax) {
|
||
|
return false
|
||
|
}
|
||
|
|
||
|
return true
|
||
|
}
|
||
|
|
||
|
// Get square of length of line segment (for performance sometimes).
|
||
|
func (ls Edge) LenSqr() Float {
|
||
|
return Sqr(ls[0].X - ls[1].X) +
|
||
|
Sqr(ls[0].Y - ls[1].Y)
|
||
|
}
|
||
|
|
||
|
// Get length of the line segment.
|
||
|
func (ls Edge) Len() Float {
|
||
|
return Sqrt(ls.LenSqr())
|
||
|
}
|
||
|
|