wip line tests

This commit is contained in:
Ben Cragg 2019-04-03 11:47:36 +01:00
parent eb3d7e0787
commit aa7ef59ecd
2 changed files with 47 additions and 53 deletions

View File

@ -211,25 +211,34 @@ func (l Line) Closest(v Vec) Vec {
// Account for horizontal lines
if m == 0 {
fmt.Println("h", l)
x := v.X
y := l.A.Y
fmt.Println(x, y)
return V(x, y)
}
// Account for vertical lines
if math.IsInf(math.Abs(m), 1) {
fmt.Println("v", l)
x := l.A.X
y := v.Y
fmt.Println(x, y)
return V(x, y)
}
// Check if the point is within the lines' bounding box, if not, one of the endpoints will be the closest point
if !l.Bounds().Contains(v) {
fmt.Println("out")
perpendicularM := -1 / m
perpendicularB := v.Y - (perpendicularM * v.X)
// Coordinates of intersect (of infinite lines)
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
toStart := v.To(l.A)
toEnd := v.To(l.B)
@ -240,15 +249,6 @@ func (l Line) Closest(v Vec) Vec {
return l.B
}
perpendicularM := -1 / m
perpendicularB := v.Y - (perpendicularM * v.X)
fmt.Println(m, b, perpendicularM, perpendicularB)
// Coordinates of intersect (of infinite lines)
x := (perpendicularB - b) / (m - perpendicularM)
y := m*x + b
fmt.Println(x, y)
return V(x, y)
}
@ -273,11 +273,9 @@ func (l Line) Formula() (m, b float64) {
// Intersect will return the point of intersection for the two line segments. If the line segments do not intersect,
// this function will return the zero-vector and `false`.
func (l Line) Intersect(k Line) (Vec, bool) {
fmt.Println(l, k)
// Check if the lines are parallel
lDir := l.A.To(l.B)
kDir := k.A.To(k.B)
fmt.Println(lDir, kDir)
if lDir.X == kDir.X && lDir.Y == kDir.Y {
return ZV, false
}
@ -287,7 +285,6 @@ func (l Line) Intersect(k Line) (Vec, bool) {
// segments
lm, lb := l.Formula()
km, kb := k.Formula()
fmt.Println(lm, lb, km, kb)
// Account for vertical lines
if math.IsInf(math.Abs(lm), 1) && math.IsInf(math.Abs(km), 1) {
@ -326,8 +323,6 @@ func (l Line) Intersect(k Line) (Vec, bool) {
// Coordinates of intersect
x := (kb - lb) / (lm - km)
y := lm*x + lb
fmt.Println(x, y)
fmt.Println(l.Contains(V(x, y)), k.Contains(V(x, y)))
if l.Contains(V(x, y)) && k.Contains(V(x, y)) {
// The intersect point is on both line segments, they intersect.
@ -356,22 +351,18 @@ func (l Line) IntersectCircle(c Circle) Vec {
func (l Line) IntersectRect(r Rect) Vec {
// Check if either end of the line segment are within the rectangle
if r.Contains(l.A) || r.Contains(l.B) {
fmt.Println("yes1")
// Use the `Rect.Intersect` to get minimal return value
rIntersect := l.Bounds().Intersect(r)
if rIntersect.H() > rIntersect.W() {
fmt.Println("yes2")
// Go vertical
return V(0, rIntersect.H())
}
return V(rIntersect.W(), 0)
}
fmt.Println("No")
// Check if any of the rectangles' edges intersect with this line.
for _, edge := range r.Edges() {
if _, ok := l.Intersect(edge); ok {
fmt.Println(edge)
// Get the closest points on the line to each corner, where:
// - the point is contained by the rectangle
// - the point is not the corner itself
@ -380,15 +371,12 @@ func (l Line) IntersectRect(r Rect) Vec {
closestCorner := corners[0]
for _, c := range corners {
cc := l.Closest(c)
if closest != ZV || (closest.Len() > cc.Len() && r.Contains(cc)) {
if closest == ZV || (closest.Len() > cc.Len() && r.Contains(cc)) {
closest = cc
closestCorner = c
}
}
fmt.Println(closest)
fmt.Println(closestCorner)
return closest.To(closestCorner)
}
}

View File

@ -865,6 +865,12 @@ func TestLine_Closest(t *testing.T) {
args: args{v: pixel.V(5, 6)},
want: pixel.V(5, 5),
},
{
name: "Point far from line",
fields: fields{A: pixel.V(0, 0), B: pixel.V(10, 10)},
args: args{v: pixel.V(80, -70)},
want: pixel.V(5, 5),
},
{
name: "Point on inline with line",
fields: fields{A: pixel.V(0, 0), B: pixel.V(10, 10)},
@ -1108,30 +1114,30 @@ func TestLine_IntersectRect(t *testing.T) {
args: args{r: pixel.R(-1, 1, 5, 5)},
want: pixel.V(-1, 0),
},
// {
// name: "Line through rect horizontally",
// fields: fields{A: pixel.V(-5, 0), B: pixel.V(5, 0)},
// args: args{r: pixel.R(-2, -5, 2, 1)},
// want: pixel.V(0, 1),
// },
// {
// name: "Line through rect diagonally bottom and left edges",
// fields: fields{A: pixel.V(0, 0), B: pixel.V(10, 10)},
// args: args{r: pixel.R(0, 2, 3, 3)},
// want: pixel.V(1, -1),
// },
// {
// name: "Line through rect diagonally top and right edges",
// fields: fields{A: pixel.V(10, 0), B: pixel.V(0, 10)},
// args: args{r: pixel.R(5, 0, 8, 3)},
// want: pixel.V(-1, -1),
// },
// {
// name: "Line with not rect intersect",
// fields: fields{A: pixel.V(0, 0), B: pixel.V(10, 10)},
// args: args{r: pixel.R(20, 20, 21, 21)},
// want: pixel.ZV,
// },
{
name: "Line through rect horizontally",
fields: fields{A: pixel.V(0, 1), B: pixel.V(10, 1)},
args: args{r: pixel.R(1, 0, 5, 5)},
want: pixel.V(0, -1),
},
{
name: "Line through rect diagonally bottom and left edges",
fields: fields{A: pixel.V(0, 0), B: pixel.V(10, 10)},
args: args{r: pixel.R(0, 2, 3, 3)},
want: pixel.V(-1, 1),
},
{
name: "Line through rect diagonally top and right edges",
fields: fields{A: pixel.V(10, 0), B: pixel.V(0, 10)},
args: args{r: pixel.R(5, 0, 8, 3)},
want: pixel.V(-2.5, -2.5),
},
{
name: "Line with not rect intersect",
fields: fields{A: pixel.V(0, 0), B: pixel.V(10, 10)},
args: args{r: pixel.R(20, 20, 21, 21)},
want: pixel.ZV,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {