Adding vertical/horizontal edge cases

This commit is contained in:
Ben Cragg 2019-04-03 12:12:27 +01:00
parent e5ff236d71
commit 98d5b9b417
1 changed files with 30 additions and 9 deletions

View File

@ -206,20 +206,48 @@ func (l Line) Center() Vec {
// Closest will return the point on the line which is closest to the `Vec` provided.
func (l Line) Closest(v Vec) Vec {
// Closest point will be on a line, perpendicular to this line
// between is a helper function which determines whether 'x' is greater than min(a, b) and less than max(a, b)
between := func(a, b, x float64) bool {
min := math.Min(a, b)
max := math.Max(a, b)
return min < x && x < max
}
// Closest point will be on a line which perpendicular to this line.
// If and only if the infinite perpendicular line intersects the segment.
m, b := l.Formula()
// Account for horizontal lines
if m == 0 {
x := v.X
y := l.A.Y
return V(x, y)
// check if the X coordinate of v is on the line
if between(l.A.X, l.B.X, v.X) {
return V(x, y)
}
// Otherwise get the closest endpoint
if l.A.To(v).Len() < l.B.To(v).Len() {
return l.A
}
return l.B
}
// Account for vertical lines
if math.IsInf(math.Abs(m), 1) {
x := l.A.X
y := v.Y
// check if the Y coordinate of v is on the line
if between(l.A.Y, l.B.Y, v.Y) {
return V(x, y)
}
// Otherwise get the closest endpoint
if l.A.To(v).Len() < l.B.To(v).Len() {
return l.A
}
return V(x, y)
}
@ -230,13 +258,6 @@ func (l Line) Closest(v Vec) Vec {
x := (perpendicularB - b) / (m - perpendicularM)
y := m*x + b
// between is a helper function which determines whether 'x' is greater than min(a, b) and less than max(a, b)
between := func(a, b, x float64) bool {
min := math.Min(a, b)
max := math.Max(a, b)
return min < x && x < max
}
// Check if the point lies between the x and y bounds of the segment
if !between(l.A.X, l.B.X, x) && !between(l.A.Y, l.B.Y, y) {
// Not within bounding box