gg/mx/line.go
2024-05-28 13:24:12 +05:00

69 lines
1.3 KiB
Go

package mx
// The type represents a line segment. The name is for short.
type Line [2]Vector
type Lines []Line
// Returns corresponding to the segment Line.
func (l Line) GetLineExpr() LineExpr {
var (
x Float
vertical bool
)
p0 := l[0]
p1 := l[1]
k := (p0.Y - p1.Y) / (p0.X - p1.X)
c := p0.Y - p0.X*k
if p0.X == p1.X {
x = p0.X
vertical = true
}
return LineExpr{k, c, x, vertical}
}
// Returns the points that the Line contains.
func (l Line) GetContainedPoints(pts Vectors) Vectors {
ret := make(Vectors, 0, len(pts))
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 Line) ContainsPoint(p Vector) bool {
lexpr := l.GetLineExpr()
if !lexpr.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 Line) 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 Line) Len() Float {
return Sqrt(ls.LenSqr())
}