2024-05-28 11:24:12 +03:00
|
|
|
package mx
|
2024-01-16 01:08:21 +03:00
|
|
|
|
|
|
|
// The type represents a line segment. The name is for short.
|
2024-05-28 11:24:12 +03:00
|
|
|
type Line [2]Vector
|
|
|
|
type Lines []Line
|
2024-01-16 01:08:21 +03:00
|
|
|
|
|
|
|
// Returns corresponding to the segment Line.
|
2024-05-28 11:24:12 +03:00
|
|
|
func (l Line) GetLineExpr() LineExpr {
|
2024-01-22 10:23:47 +03:00
|
|
|
var (
|
|
|
|
x Float
|
|
|
|
vertical bool
|
|
|
|
)
|
|
|
|
|
2024-01-16 01:08:21 +03:00
|
|
|
p0 := l[0]
|
|
|
|
p1 := l[1]
|
|
|
|
|
|
|
|
k := (p0.Y - p1.Y) / (p0.X - p1.X)
|
|
|
|
c := p0.Y - p0.X*k
|
2024-01-22 10:23:47 +03:00
|
|
|
if p0.X == p1.X {
|
|
|
|
x = p0.X
|
2024-01-22 20:08:50 +03:00
|
|
|
vertical = true
|
2024-01-22 10:23:47 +03:00
|
|
|
}
|
|
|
|
|
2024-05-28 11:24:12 +03:00
|
|
|
return LineExpr{k, c, x, vertical}
|
2024-01-16 01:08:21 +03:00
|
|
|
}
|
|
|
|
|
2024-05-28 11:24:12 +03:00
|
|
|
// Returns the points that the Line contains.
|
|
|
|
func (l Line) GetContainedPoints(pts Vectors) Vectors {
|
|
|
|
ret := make(Vectors, 0, len(pts))
|
2024-01-16 01:08:21 +03:00
|
|
|
for i := range pts {
|
|
|
|
if l.ContainsPoint(pts[i]) {
|
|
|
|
ret = append(ret, pts[i])
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return ret
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check if the edge contains the specified point.
|
2024-05-28 11:24:12 +03:00
|
|
|
func (l Line) ContainsPoint(p Vector) bool {
|
|
|
|
lexpr := l.GetLineExpr()
|
|
|
|
if !lexpr.ContainsPoint(p) {
|
2024-01-16 01:08:21 +03:00
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2024-01-22 10:23:47 +03:00
|
|
|
xMax := Max(l[0].X, l[1].X)
|
|
|
|
xMin := Min(l[0].X, l[1].X)
|
2024-01-16 01:08:21 +03:00
|
|
|
|
2024-01-22 10:23:47 +03:00
|
|
|
yMax := Max(l[0].Y, l[1].Y)
|
|
|
|
yMin := Min(l[0].Y, l[1].Y)
|
2024-01-16 01:08:21 +03:00
|
|
|
|
2024-01-22 20:08:50 +03:00
|
|
|
if !(xMin <= p.X && p.X <= xMax) ||
|
|
|
|
!(yMin <= p.Y && p.Y <= yMax) {
|
2024-01-16 01:08:21 +03:00
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get square of length of line segment (for performance sometimes).
|
2024-05-28 11:24:12 +03:00
|
|
|
func (ls Line) LenSqr() Float {
|
2024-01-16 01:08:21 +03:00
|
|
|
return Sqr(ls[0].X - ls[1].X) +
|
|
|
|
Sqr(ls[0].Y - ls[1].Y)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get length of the line segment.
|
2024-05-28 11:24:12 +03:00
|
|
|
func (ls Line) Len() Float {
|
2024-01-16 01:08:21 +03:00
|
|
|
return Sqrt(ls.LenSqr())
|
|
|
|
}
|
|
|
|
|