mirror of https://github.com/tidwall/tile38.git
1388 lines
51 KiB
Go
1388 lines
51 KiB
Go
// Copyright 2018 Joshua J Baker. All rights reserved.
|
|
// Use of this source code is governed by an MIT-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package geometry
|
|
|
|
import (
|
|
"fmt"
|
|
"testing"
|
|
)
|
|
|
|
func newRingXSimple(points []Point) Ring {
|
|
ring := newRing(points, DefaultIndex)
|
|
if ring.(*baseSeries).tree != nil {
|
|
ring.(*baseSeries).tree = nil
|
|
}
|
|
return ring
|
|
}
|
|
func newRingXIndexed(points []Point) Ring {
|
|
ring := newRing(points, DefaultIndex)
|
|
if ring.(*baseSeries).tree == nil {
|
|
ring.(*baseSeries).buildTree()
|
|
}
|
|
return ring
|
|
}
|
|
|
|
func testDualRingX(t *testing.T, points []Point, do func(t *testing.T, ring Ring)) {
|
|
t.Run("index", func(t *testing.T) {
|
|
do(t, newRingXSimple(points))
|
|
})
|
|
t.Run("noindex", func(t *testing.T) {
|
|
do(t, newRingXIndexed(points))
|
|
})
|
|
}
|
|
|
|
func TestRectGeometryDefaults(t *testing.T) {
|
|
g := Geometry(Rect{})
|
|
expect(t, !g.Empty())
|
|
expect(t, g.Rect() == R(0, 0, 0, 0))
|
|
expect(t, !g.ContainsLine(nil))
|
|
expect(t, !g.ContainsLine(&Line{}))
|
|
expect(t, g.ContainsPoint(Point{}))
|
|
expect(t, !g.ContainsPoly(nil))
|
|
expect(t, !g.ContainsPoly(&Poly{}))
|
|
expect(t, g.ContainsRect(Rect{}))
|
|
expect(t, !g.IntersectsLine(nil))
|
|
expect(t, !g.IntersectsLine(&Line{}))
|
|
expect(t, g.IntersectsPoint(Point{}))
|
|
expect(t, !g.IntersectsPoly(nil))
|
|
expect(t, !g.IntersectsPoly(&Poly{}))
|
|
expect(t, g.IntersectsRect(Rect{}))
|
|
}
|
|
|
|
func TestRingXContainsPoint(t *testing.T) {
|
|
testDualRingX(t, octagon, func(t *testing.T, ring Ring) {
|
|
expect(t, !ringContainsPoint(ring, P(0, 0), true).hit)
|
|
expect(t, ringContainsPoint(ring, P(0, 5), true).hit)
|
|
expect(t, !ringContainsPoint(ring, P(0, 5), false).hit)
|
|
expect(t, ringContainsPoint(ring, P(4, 4), true).hit)
|
|
expect(t, !ringContainsPoint(ring, P(1.4, 1.4), true).hit)
|
|
expect(t, ringContainsPoint(ring, P(1.5, 1.5), true).hit)
|
|
expect(t, !ringContainsPoint(ring, P(1.5, 1.5), false).hit)
|
|
})
|
|
shape := []Point{
|
|
P(0, 0), P(4, 0), P(4, 3),
|
|
P(3, 4), P(1, 4),
|
|
P(0, 3), P(0, 0),
|
|
}
|
|
ring := newRing(shape, DefaultIndex)
|
|
expect(t, !ringContainsPoint(ring, P(0, 3.5), true).hit)
|
|
expect(t, !ringContainsPoint(ring, P(0.4, 3.5), true).hit)
|
|
expect(t, ringContainsPoint(ring, P(0.5, 3.5), true).hit)
|
|
expect(t, ringContainsPoint(ring, P(0.6, 3.5), true).hit)
|
|
expect(t, ringContainsPoint(ring, P(1, 3.5), true).hit)
|
|
expect(t, ringContainsPoint(ring, P(3, 3.5), true).hit)
|
|
expect(t, ringContainsPoint(ring, P(3.4, 3.5), true).hit)
|
|
expect(t, ringContainsPoint(ring, P(3.5, 3.5), true).hit)
|
|
expect(t, !ringContainsPoint(ring, P(3.9, 3.5), true).hit)
|
|
expect(t, !ringContainsPoint(ring, P(4, 3.5), true).hit)
|
|
expect(t, !ringContainsPoint(ring, P(4.1, 3.5), true).hit)
|
|
|
|
}
|
|
|
|
func TestRingXIntersectsPoint(t *testing.T) {
|
|
testDualRingX(t, octagon, func(t *testing.T, ring Ring) {
|
|
expect(t, !ringIntersectsPoint(ring, P(0, 0), true).hit)
|
|
expect(t, ringIntersectsPoint(ring, P(0, 5), true).hit)
|
|
expect(t, !ringIntersectsPoint(ring, P(0, 5), false).hit)
|
|
expect(t, ringIntersectsPoint(ring, P(4, 4), true).hit)
|
|
expect(t, !ringIntersectsPoint(ring, P(1.4, 1.4), true).hit)
|
|
expect(t, ringIntersectsPoint(ring, P(1.5, 1.5), true).hit)
|
|
expect(t, !ringIntersectsPoint(ring, P(1.5, 1.5), false).hit)
|
|
})
|
|
}
|
|
|
|
func TestRingXIntersectsSegment(t *testing.T) {
|
|
t.Run("Cases", func(t *testing.T) {
|
|
ring := newRing([]Point{
|
|
P(0, 0), P(4, 0), P(4, 4), P(0, 4), P(0, 0),
|
|
}, DefaultIndex)
|
|
t.Run("1", func(t *testing.T) {
|
|
expect(t, ringIntersectsSegment(ring, S(2, 2, 4, 4), true))
|
|
expect(t, ringIntersectsSegment(ring, S(2, 2, 4, 4), false))
|
|
})
|
|
t.Run("2", func(t *testing.T) {
|
|
expect(t, ringIntersectsSegment(ring, S(2, 0, 4, 2), true))
|
|
expect(t, ringIntersectsSegment(ring, S(2, 0, 4, 2), false))
|
|
})
|
|
t.Run("3", func(t *testing.T) {
|
|
expect(t, ringIntersectsSegment(ring, S(1, 0, 3, 0), true))
|
|
expect(t, !ringIntersectsSegment(ring, S(1, 0, 3, 0), false))
|
|
})
|
|
t.Run("4", func(t *testing.T) {
|
|
expect(t, ringIntersectsSegment(ring, S(2, 4, 2, 0), true))
|
|
expect(t, ringIntersectsSegment(ring, S(2, 4, 2, 0), false))
|
|
})
|
|
t.Run("5", func(t *testing.T) {
|
|
expect(t, ringIntersectsSegment(ring, S(2, 0, 2, -3), true))
|
|
expect(t, !ringIntersectsSegment(ring, S(2, 0, 2, -3), false))
|
|
})
|
|
t.Run("6", func(t *testing.T) {
|
|
expect(t, !ringIntersectsSegment(ring, S(2, -1, 2, -3), true))
|
|
expect(t, !ringIntersectsSegment(ring, S(2, -1, 2, -3), false))
|
|
})
|
|
t.Run("7", func(t *testing.T) {
|
|
expect(t, ringIntersectsSegment(ring, S(-1, 2, 3, 2), true))
|
|
expect(t, ringIntersectsSegment(ring, S(-1, 2, 3, 2), false))
|
|
})
|
|
t.Run("8", func(t *testing.T) {
|
|
expect(t, ringIntersectsSegment(ring, S(-1, 3, 2, 1), true))
|
|
expect(t, ringIntersectsSegment(ring, S(-1, 3, 2, 1), false))
|
|
})
|
|
t.Run("9", func(t *testing.T) {
|
|
expect(t, ringIntersectsSegment(ring, S(-1, 2, 5, 1), true))
|
|
expect(t, ringIntersectsSegment(ring, S(-1, 2, 5, 1), false))
|
|
})
|
|
t.Run("10", func(t *testing.T) {
|
|
expect(t, ringIntersectsSegment(ring, S(2, 5, 1, -1), true))
|
|
expect(t, ringIntersectsSegment(ring, S(2, 5, 1, -1), false))
|
|
})
|
|
t.Run("11", func(t *testing.T) {
|
|
expect(t, ringIntersectsSegment(ring, S(0, 4, 4, 0), true))
|
|
expect(t, ringIntersectsSegment(ring, S(0, 4, 4, 0), false))
|
|
})
|
|
t.Run("12", func(t *testing.T) {
|
|
ring := newRing([]Point{
|
|
{0, 0}, {2, 0}, {4, 0}, {4, 4}, {0, 4}, {0, 0},
|
|
}, DefaultIndex)
|
|
expect(t, ringIntersectsSegment(ring, S(1, 0, 3, 0), true))
|
|
expect(t, !ringIntersectsSegment(ring, S(1, 0, 3, 0), false))
|
|
})
|
|
t.Run("13", func(t *testing.T) {
|
|
ring := newRing([]Point{
|
|
{0, 0}, {4, 0}, {4, 4}, {2, 4}, {0, 4}, {0, 0},
|
|
}, DefaultIndex)
|
|
expect(t, ringIntersectsSegment(ring, S(0, 4, 4, 4), true))
|
|
expect(t, !ringIntersectsSegment(ring, S(0, 4, 4, 4), false))
|
|
})
|
|
t.Run("14", func(t *testing.T) {
|
|
ring := newRing([]Point{
|
|
{0, 0}, {4, 0}, {4, 4}, {2, 4}, {0, 4}, {0, 0},
|
|
}, DefaultIndex)
|
|
expect(t, ringIntersectsSegment(ring, S(-1, -2, 0, 0), true))
|
|
expect(t, !ringIntersectsSegment(ring, S(-1, -2, 0, 0), false))
|
|
})
|
|
t.Run("15", func(t *testing.T) {
|
|
ring := newRing([]Point{
|
|
{0, 0}, {4, 0}, {4, 4}, {2, 4}, {0, 4}, {0, 0},
|
|
}, DefaultIndex)
|
|
expect(t, ringIntersectsSegment(ring, S(0, 4, 5, 4), true))
|
|
expect(t, !ringIntersectsSegment(ring, S(0, 4, 5, 4), false))
|
|
})
|
|
t.Run("16", func(t *testing.T) {
|
|
ring := newRing([]Point{
|
|
{0, 0}, {4, 0}, {4, 4}, {2, 4}, {0, 4}, {0, 0},
|
|
}, DefaultIndex)
|
|
expect(t, ringIntersectsSegment(ring, S(1, 4, 5, 4), true))
|
|
expect(t, !ringIntersectsSegment(ring, S(1, 4, 5, 4), false))
|
|
})
|
|
t.Run("17", func(t *testing.T) {
|
|
ring := newRing([]Point{
|
|
{0, 0}, {4, 0}, {4, 4}, {2, 4}, {0, 4}, {0, 0},
|
|
}, DefaultIndex)
|
|
expect(t, ringIntersectsSegment(ring, S(1, 4, 4, 4), true))
|
|
expect(t, !ringIntersectsSegment(ring, S(1, 4, 4, 4), false))
|
|
})
|
|
})
|
|
|
|
// convex shape
|
|
t.Run("Octagon", func(t *testing.T) {
|
|
shape := octagon
|
|
t.Run("Outside", func(t *testing.T) {
|
|
// test coming off of the edges
|
|
segs := []Segment{
|
|
S(0, 5, -5, 5).Move(-1, 0), // left
|
|
S(1.5, 1.5, -3.5, -3.5).Move(-1, -1), // bottom-left corner
|
|
S(5, 0, 5, -5).Move(0, -1), // bottom
|
|
S(8.5, 1.5, 13.5, -3.5).Move(1, -1), // bottom-right corner
|
|
S(10, 5, 15, 5).Move(1, 0), // right
|
|
S(8.5, 8.5, 13.5, 13.5).Move(1, 1), // top-right corner
|
|
S(5, 10, 5, 15).Move(0, 5), // top
|
|
S(1.5, 8.5, -3.5, 13.5).Move(-1, 1), // top-left corner
|
|
}
|
|
for i, seg := range segs {
|
|
t.Run(fmt.Sprintf("Segment-%d", i), func(t *testing.T) {
|
|
testDualRingX(t, shape, func(t *testing.T, ring Ring) {
|
|
expect(t, !ringIntersectsSegment(ring, seg, true))
|
|
expect(t, !ringIntersectsSegment(ring, seg, false))
|
|
seg.A, seg.B = seg.B, seg.A
|
|
expect(t, !ringIntersectsSegment(ring, seg, true))
|
|
expect(t, !ringIntersectsSegment(ring, seg, false))
|
|
})
|
|
})
|
|
}
|
|
})
|
|
t.Run("OutsideEdgeTouch", func(t *testing.T) {
|
|
// test coming off of the edges
|
|
segs := []Segment{
|
|
S(0, 5, -5, 5), // left
|
|
S(1.5, 1.5, -3.5, -3.5), // bottom-left corner
|
|
S(5, 0, 5, -5), // bottom
|
|
S(8.5, 1.5, 13.5, -3.5), // bottom-right corner
|
|
S(10, 5, 15, 5), // right
|
|
S(8.5, 8.5, 13.5, 13.5), // top-right corner
|
|
S(5, 10, 5, 15), // top
|
|
S(1.5, 8.5, -3.5, 13.5), // top-left corner
|
|
}
|
|
for i, seg := range segs {
|
|
t.Run(fmt.Sprintf("Segment-%d", i), func(t *testing.T) {
|
|
testDualRingX(t, shape, func(t *testing.T, ring Ring) {
|
|
expect(t, ringIntersectsSegment(ring, seg, true))
|
|
expect(t, !ringIntersectsSegment(ring, seg, false))
|
|
seg.A, seg.B = seg.B, seg.A
|
|
expect(t, ringIntersectsSegment(ring, seg, true))
|
|
expect(t, !ringIntersectsSegment(ring, seg, false))
|
|
})
|
|
})
|
|
}
|
|
})
|
|
t.Run("EdgeCross", func(t *testing.T) {
|
|
segs := []Segment{
|
|
S(0, 5, -5, 5).Move(2.5, 0), // left
|
|
S(1.5, 1.5, -3.5, -3.5).Move(2.5, 2.5), // bottom-left corner
|
|
S(5, 0, 5, -5).Move(0, 2.5), // bottom
|
|
S(8.5, 1.5, 13.5, -3.5).Move(-2.5, 2.5), // bottom-right corner
|
|
S(10, 5, 15, 5).Move(-2.5, 0), // right
|
|
S(8.5, 8.5, 13.5, 13.5).Move(-2.5, -2.5), // top-right corner
|
|
S(5, 10, 5, 15).Move(0, -2.5), // top
|
|
S(1.5, 8.5, -3.5, 13.5).Move(2.5, -2.5), // top-left corner
|
|
}
|
|
for i, seg := range segs {
|
|
t.Run(fmt.Sprintf("Segment-%d", i), func(t *testing.T) {
|
|
testDualRingX(t, shape, func(t *testing.T, ring Ring) {
|
|
expect(t, ringIntersectsSegment(ring, seg, true))
|
|
expect(t, ringIntersectsSegment(ring, seg, false))
|
|
seg.A, seg.B = seg.B, seg.A
|
|
expect(t, ringIntersectsSegment(ring, seg, true))
|
|
expect(t, ringIntersectsSegment(ring, seg, false))
|
|
})
|
|
})
|
|
}
|
|
})
|
|
t.Run("InsideEdgeTouch", func(t *testing.T) {
|
|
segs := []Segment{
|
|
S(0, 5, -5, 5).Move(5, 0), // left
|
|
S(1.5, 1.5, -3.5, -3.5).Move(5, 5), // bottom-left corner
|
|
S(5, 0, 5, -5).Move(0, 5), // bottom
|
|
S(8.5, 1.5, 13.5, -3.5).Move(-5, 5), // bottom-right corner
|
|
S(10, 5, 15, 5).Move(-5, 0), // right
|
|
S(8.5, 8.5, 13.5, 13.5).Move(-5, -5), // top-right corner
|
|
S(5, 10, 5, 15).Move(0, -5), // top
|
|
S(1.5, 8.5, -3.5, 13.5).Move(5, -5), // top-left corner
|
|
}
|
|
for i, seg := range segs {
|
|
t.Run(fmt.Sprintf("Segment-%d", i), func(t *testing.T) {
|
|
testDualRingX(t, shape, func(t *testing.T, ring Ring) {
|
|
expect(t, ringIntersectsSegment(ring, seg, true))
|
|
expect(t, ringIntersectsSegment(ring, seg, false))
|
|
seg.A, seg.B = seg.B, seg.A
|
|
expect(t, ringIntersectsSegment(ring, seg, true))
|
|
expect(t, ringIntersectsSegment(ring, seg, false))
|
|
})
|
|
})
|
|
}
|
|
})
|
|
t.Run("Inside", func(t *testing.T) {
|
|
segs := []Segment{
|
|
S(0, 5, -5, 5).Move(6, 0), // left
|
|
S(1.5, 1.5, -3.5, -3.5).Move(6, 6), // bottom-left corner
|
|
S(5, 0, 5, -5).Move(0, 6), // bottom
|
|
S(8.5, 1.5, 13.5, -3.5).Move(-6, 6), // bottom-right corner
|
|
S(10, 5, 15, 5).Move(-6, 0), // right
|
|
S(8.5, 8.5, 13.5, 13.5).Move(-6, -6), // top-right corner
|
|
S(5, 10, 5, 15).Move(0, -6), // top
|
|
S(1.5, 8.5, -3.5, 13.5).Move(6, -6), // top-left corner
|
|
}
|
|
for i, seg := range segs {
|
|
t.Run(fmt.Sprintf("Segment-%d", i), func(t *testing.T) {
|
|
testDualRingX(t, shape, func(t *testing.T, ring Ring) {
|
|
expect(t, ringIntersectsSegment(ring, seg, true))
|
|
expect(t, ringIntersectsSegment(ring, seg, false))
|
|
seg.A, seg.B = seg.B, seg.A
|
|
expect(t, ringIntersectsSegment(ring, seg, true))
|
|
expect(t, ringIntersectsSegment(ring, seg, false))
|
|
})
|
|
})
|
|
}
|
|
})
|
|
t.Run("InsideEdgeToEdge", func(t *testing.T) {
|
|
segs := []Segment{
|
|
S(0, 5, 10, 5), // left to right
|
|
S(1.5, 1.5, 8.5, 8.5), // bottom-left to top-right
|
|
S(5, 0, 5, 10), // bottom to top
|
|
S(8.5, 1.5, 1.5, 8.5), // bottom-right to top-left
|
|
}
|
|
for i, seg := range segs {
|
|
t.Run(fmt.Sprintf("Segment-%d", i), func(t *testing.T) {
|
|
testDualRingX(t, shape, func(t *testing.T, ring Ring) {
|
|
expect(t, ringIntersectsSegment(ring, seg, true))
|
|
expect(t, ringIntersectsSegment(ring, seg, false))
|
|
seg.A, seg.B = seg.B, seg.A
|
|
expect(t, ringIntersectsSegment(ring, seg, true))
|
|
expect(t, ringIntersectsSegment(ring, seg, false))
|
|
})
|
|
})
|
|
}
|
|
})
|
|
t.Run("PassoverEdgeToEdge", func(t *testing.T) {
|
|
segs := []Segment{
|
|
S(-1, 5, 11, 5), // left to right
|
|
S(0.5, 0.5, 9.5, 9.5), // bottom-left to top-right
|
|
S(5, -1, 5, 11), // bottom to top
|
|
S(9.5, 0.5, 0.5, 9.5), // bottom-right to top-left
|
|
}
|
|
for i, seg := range segs {
|
|
t.Run(fmt.Sprintf("Segment-%d", i), func(t *testing.T) {
|
|
testDualRingX(t, shape, func(t *testing.T, ring Ring) {
|
|
expect(t, ringIntersectsSegment(ring, seg, true))
|
|
expect(t, ringIntersectsSegment(ring, seg, false))
|
|
seg.A, seg.B = seg.B, seg.A
|
|
expect(t, ringIntersectsSegment(ring, seg, true))
|
|
expect(t, ringIntersectsSegment(ring, seg, false))
|
|
})
|
|
})
|
|
}
|
|
})
|
|
})
|
|
|
|
// concave shape
|
|
t.Run("Concave", func(t *testing.T) {
|
|
shape := concave1
|
|
t.Run("Outside", func(t *testing.T) {
|
|
segs := []Segment{
|
|
S(0, 7.5, -5, 7.5).Move(-1, 0), // left
|
|
S(2.5, 5, 2.5, 0).Move(0, -1), // bottom-left-1
|
|
S(5, 2.5, 0, 2.5).Move(-1, 0), // bottom-left-2
|
|
S(7.5, 0, 7.5, -5).Move(0, -1), // bottom
|
|
S(10, 5, 15, 5).Move(1, 0), // right
|
|
S(5, 10, 5, 15).Move(0, 1), // top
|
|
}
|
|
for i, seg := range segs {
|
|
t.Run(fmt.Sprintf("Segment-%d", i), func(t *testing.T) {
|
|
testDualRingX(t, shape, func(t *testing.T, ring Ring) {
|
|
expect(t, !ringIntersectsSegment(ring, seg, true))
|
|
expect(t, !ringIntersectsSegment(ring, seg, false))
|
|
seg.A, seg.B = seg.B, seg.A
|
|
expect(t, !ringIntersectsSegment(ring, seg, true))
|
|
expect(t, !ringIntersectsSegment(ring, seg, false))
|
|
})
|
|
})
|
|
}
|
|
})
|
|
t.Run("OutsideEdgeTouch", func(t *testing.T) {
|
|
segs := []Segment{
|
|
S(0, 7.5, -5, 7.5), // left
|
|
S(2.5, 5, 2.5, 0), // bottom-left-1
|
|
S(5, 2.5, 0, 2.5), // bottom-left-2
|
|
S(7.5, 0, 7.5, -5), // bottom
|
|
S(10, 5, 15, 5), // right
|
|
S(5, 10, 5, 15), // top
|
|
}
|
|
for i, seg := range segs {
|
|
t.Run(fmt.Sprintf("Segment-%d", i), func(t *testing.T) {
|
|
testDualRingX(t, shape, func(t *testing.T, ring Ring) {
|
|
expect(t, ringIntersectsSegment(ring, seg, true))
|
|
expect(t, !ringIntersectsSegment(ring, seg, false))
|
|
seg.A, seg.B = seg.B, seg.A
|
|
expect(t, ringIntersectsSegment(ring, seg, true))
|
|
expect(t, !ringIntersectsSegment(ring, seg, false))
|
|
})
|
|
})
|
|
}
|
|
})
|
|
t.Run("EdgeCross", func(t *testing.T) {
|
|
segs := []Segment{
|
|
S(0, 7.5, -5, 7.5).Move(2.5, 0), // left
|
|
S(2.5, 5, 2.5, 0).Move(0, 2.5), // bottom-left-1
|
|
S(5, 2.5, 0, 2.5).Move(2.5, 0), // bottom-left-2
|
|
S(7.5, 0, 7.5, -5).Move(0, 2.5), // bottom
|
|
S(10, 5, 15, 5).Move(-2.5, 0), // right
|
|
S(5, 10, 5, 15).Move(0, -2.5), // top
|
|
}
|
|
for i, seg := range segs {
|
|
t.Run(fmt.Sprintf("Segment-%d", i), func(t *testing.T) {
|
|
testDualRingX(t, shape, func(t *testing.T, ring Ring) {
|
|
expect(t, ringIntersectsSegment(ring, seg, true))
|
|
expect(t, ringIntersectsSegment(ring, seg, false))
|
|
seg.A, seg.B = seg.B, seg.A
|
|
expect(t, ringIntersectsSegment(ring, seg, true))
|
|
expect(t, ringIntersectsSegment(ring, seg, false))
|
|
})
|
|
})
|
|
}
|
|
})
|
|
t.Run("InsideEdgeTouch", func(t *testing.T) {
|
|
segs := []Segment{
|
|
S(0, 7.5, -3, 7.5).Move(3, 0), // 0:left
|
|
S(2.5, 5, 2.5, 2).Move(0, 3), // 1:bottom-left-1
|
|
S(5, 2.5, 2, 2.5).Move(3, 0), // 2:bottom-left-2
|
|
S(7.5, 0, 7.5, -3).Move(0, 3), // 3:bottom
|
|
S(10, 5, 13, 5).Move(-3, 0), // 4:right
|
|
S(5, 10, 5, 13).Move(0, -3), // 5:top
|
|
}
|
|
for i, seg := range segs {
|
|
t.Run(fmt.Sprintf("Segment-%d", i), func(t *testing.T) {
|
|
testDualRingX(t, shape, func(t *testing.T, ring Ring) {
|
|
expect(t, ringIntersectsSegment(ring, seg, true))
|
|
expect(t, ringIntersectsSegment(ring, seg, false))
|
|
seg.A, seg.B = seg.B, seg.A
|
|
expect(t, ringIntersectsSegment(ring, seg, true))
|
|
expect(t, ringIntersectsSegment(ring, seg, false))
|
|
})
|
|
})
|
|
}
|
|
})
|
|
t.Run("Inside", func(t *testing.T) {
|
|
segs := []Segment{
|
|
S(0, 7.5, -3, 7.5).Move(4, 0), // 0:left
|
|
S(2.5, 5, 2.5, 2).Move(0, 4), // 1:bottom-left-1
|
|
S(5, 2.5, 2, 2.5).Move(4, 0), // 2:bottom-left-2
|
|
S(7.5, 0, 7.5, -3).Move(0, 4), // 3:bottom
|
|
S(10, 5, 13, 5).Move(-4, 0), // 4:right
|
|
S(5, 10, 5, 13).Move(0, -4), // 5:top
|
|
}
|
|
for i, seg := range segs {
|
|
t.Run(fmt.Sprintf("Segment-%d", i), func(t *testing.T) {
|
|
testDualRingX(t, shape, func(t *testing.T, ring Ring) {
|
|
expect(t, ringIntersectsSegment(ring, seg, true))
|
|
expect(t, ringIntersectsSegment(ring, seg, false))
|
|
seg.A, seg.B = seg.B, seg.A
|
|
expect(t, ringIntersectsSegment(ring, seg, true))
|
|
expect(t, ringIntersectsSegment(ring, seg, false))
|
|
})
|
|
})
|
|
}
|
|
})
|
|
t.Run("InsideEdgeToEdge", func(t *testing.T) {
|
|
segs := []Segment{
|
|
S(0, 7.5, 10, 7.5), // 0:left
|
|
S(2.5, 5, 2.5, 10), // 1:bottom-left-1
|
|
S(5, 2.5, 10, 2.5), // 2:bottom-left-2
|
|
S(7.5, 0, 7.5, 10), // 3:bottom
|
|
}
|
|
for i, seg := range segs {
|
|
t.Run(fmt.Sprintf("Segment-%d", i), func(t *testing.T) {
|
|
testDualRingX(t, shape, func(t *testing.T, ring Ring) {
|
|
expect(t, ringIntersectsSegment(ring, seg, true))
|
|
expect(t, ringIntersectsSegment(ring, seg, false))
|
|
seg.A, seg.B = seg.B, seg.A
|
|
expect(t, ringIntersectsSegment(ring, seg, true))
|
|
expect(t, ringIntersectsSegment(ring, seg, false))
|
|
})
|
|
})
|
|
}
|
|
})
|
|
t.Run("PassoverEdgeToEdge", func(t *testing.T) {
|
|
segs := []Segment{
|
|
S(-1, 7.5, 11, 7.5), // 0:left
|
|
S(2.5, 4, 2.5, 11), // 1:bottom-left-1
|
|
S(4, 2.5, 11, 2.5), // 2:bottom-left-2
|
|
S(7.5, -1, 7.5, 11), // 3:bottom
|
|
}
|
|
for i, seg := range segs {
|
|
t.Run(fmt.Sprintf("Segment-%d", i), func(t *testing.T) {
|
|
testDualRingX(t, shape, func(t *testing.T, ring Ring) {
|
|
expect(t, ringIntersectsSegment(ring, seg, true))
|
|
expect(t, ringIntersectsSegment(ring, seg, false))
|
|
seg.A, seg.B = seg.B, seg.A
|
|
expect(t, ringIntersectsSegment(ring, seg, true))
|
|
expect(t, ringIntersectsSegment(ring, seg, false))
|
|
})
|
|
})
|
|
}
|
|
})
|
|
})
|
|
}
|
|
|
|
func TestRingXContainsSegment(t *testing.T) {
|
|
expect(t, ringContainsSegment(R(0, 0, 10, 10), S(5, 5, 5, 5), true))
|
|
expect(t, ringContainsSegment(R(0, 0, 10, 10), S(5, 5, 5, 5), false))
|
|
expect(t, ringContainsSegment(R(0, 0, 10, 10), S(0, 0, 0, 0), true))
|
|
expect(t, !ringContainsSegment(R(0, 0, 10, 10), S(0, 0, 0, 0), false))
|
|
expect(t, ringContainsSegment(R(0, 0, 10, 10), S(10, 10, 10, 10), true))
|
|
expect(t, !ringContainsSegment(R(0, 0, 10, 10), S(10, 10, 10, 10), false))
|
|
|
|
// convex shape
|
|
t.Run("Octagon", func(t *testing.T) {
|
|
shape := octagon
|
|
t.Run("Outside", func(t *testing.T) {
|
|
// test coming off of the edges
|
|
segs := []Segment{
|
|
S(0, 5, -5, 5).Move(-1, 0), // left
|
|
S(1.5, 1.5, -3.5, -3.5).Move(-1, -1), // bottom-left corner
|
|
S(5, 0, 5, -5).Move(0, -1), // bottom
|
|
S(8.5, 1.5, 13.5, -3.5).Move(1, -1), // bottom-right corner
|
|
S(10, 5, 15, 5).Move(1, 0), // right
|
|
S(8.5, 8.5, 13.5, 13.5).Move(1, 1), // top-right corner
|
|
S(5, 10, 5, 15).Move(0, 5), // top
|
|
S(1.5, 8.5, -3.5, 13.5).Move(-1, 1), // top-left corner
|
|
}
|
|
for i, seg := range segs {
|
|
t.Run(fmt.Sprintf("Segment-%d", i), func(t *testing.T) {
|
|
testDualRingX(t, shape, func(t *testing.T, ring Ring) {
|
|
expect(t, !ringContainsSegment(ring, seg, true))
|
|
expect(t, !ringContainsSegment(ring, seg, false))
|
|
seg.A, seg.B = seg.B, seg.A
|
|
expect(t, !ringContainsSegment(ring, seg, true))
|
|
expect(t, !ringContainsSegment(ring, seg, false))
|
|
})
|
|
})
|
|
}
|
|
})
|
|
t.Run("OutsideEdgeTouch", func(t *testing.T) {
|
|
// test coming off of the edges
|
|
segs := []Segment{
|
|
S(0, 5, -5, 5), // left
|
|
S(1.5, 1.5, -3.5, -3.5), // bottom-left corner
|
|
S(5, 0, 5, -5), // bottom
|
|
S(8.5, 1.5, 13.5, -3.5), // bottom-right corner
|
|
S(10, 5, 15, 5), // right
|
|
S(8.5, 8.5, 13.5, 13.5), // top-right corner
|
|
S(5, 10, 5, 15), // top
|
|
S(1.5, 8.5, -3.5, 13.5), // top-left corner
|
|
}
|
|
for i, seg := range segs {
|
|
t.Run(fmt.Sprintf("Segment-%d", i), func(t *testing.T) {
|
|
testDualRingX(t, shape, func(t *testing.T, ring Ring) {
|
|
expect(t, !ringContainsSegment(ring, seg, true))
|
|
expect(t, !ringContainsSegment(ring, seg, false))
|
|
seg.A, seg.B = seg.B, seg.A
|
|
expect(t, !ringContainsSegment(ring, seg, true))
|
|
expect(t, !ringContainsSegment(ring, seg, false))
|
|
})
|
|
})
|
|
}
|
|
})
|
|
t.Run("EdgeCross", func(t *testing.T) {
|
|
segs := []Segment{
|
|
S(0, 5, -5, 5).Move(2.5, 0), // left
|
|
S(1.5, 1.5, -3.5, -3.5).Move(2.5, 2.5), // bottom-left corner
|
|
S(5, 0, 5, -5).Move(0, 2.5), // bottom
|
|
S(8.5, 1.5, 13.5, -3.5).Move(-2.5, 2.5), // bottom-right corner
|
|
S(10, 5, 15, 5).Move(-2.5, 0), // right
|
|
S(8.5, 8.5, 13.5, 13.5).Move(-2.5, -2.5), // top-right corner
|
|
S(5, 10, 5, 15).Move(0, -2.5), // top
|
|
S(1.5, 8.5, -3.5, 13.5).Move(2.5, -2.5), // top-left corner
|
|
}
|
|
for i, seg := range segs {
|
|
t.Run(fmt.Sprintf("Segment-%d", i), func(t *testing.T) {
|
|
testDualRingX(t, shape, func(t *testing.T, ring Ring) {
|
|
expect(t, !ringContainsSegment(ring, seg, true))
|
|
expect(t, !ringContainsSegment(ring, seg, false))
|
|
seg.A, seg.B = seg.B, seg.A
|
|
expect(t, !ringContainsSegment(ring, seg, true))
|
|
expect(t, !ringContainsSegment(ring, seg, false))
|
|
})
|
|
})
|
|
}
|
|
})
|
|
t.Run("InsideEdgeTouch", func(t *testing.T) {
|
|
segs := []Segment{
|
|
S(0, 5, -5, 5).Move(5, 0), // left
|
|
S(1.5, 1.5, -3.5, -3.5).Move(5, 5), // bottom-left corner
|
|
S(5, 0, 5, -5).Move(0, 5), // bottom
|
|
S(8.5, 1.5, 13.5, -3.5).Move(-5, 5), // bottom-right corner
|
|
S(10, 5, 15, 5).Move(-5, 0), // right
|
|
S(8.5, 8.5, 13.5, 13.5).Move(-5, -5), // top-right corner
|
|
S(5, 10, 5, 15).Move(0, -5), // top
|
|
S(1.5, 8.5, -3.5, 13.5).Move(5, -5), // top-left corner
|
|
}
|
|
for i, seg := range segs {
|
|
t.Run(fmt.Sprintf("Segment-%d", i), func(t *testing.T) {
|
|
testDualRingX(t, shape, func(t *testing.T, ring Ring) {
|
|
expect(t, ringContainsSegment(ring, seg, true))
|
|
expect(t, !ringContainsSegment(ring, seg, false))
|
|
seg.A, seg.B = seg.B, seg.A
|
|
expect(t, ringContainsSegment(ring, seg, true))
|
|
expect(t, !ringContainsSegment(ring, seg, false))
|
|
})
|
|
})
|
|
}
|
|
})
|
|
t.Run("Inside", func(t *testing.T) {
|
|
segs := []Segment{
|
|
S(0, 5, -5, 5).Move(6, 0), // left
|
|
S(1.5, 1.5, -3.5, -3.5).Move(6, 6), // bottom-left corner
|
|
S(5, 0, 5, -5).Move(0, 6), // bottom
|
|
S(8.5, 1.5, 13.5, -3.5).Move(-6, 6), // bottom-right corner
|
|
S(10, 5, 15, 5).Move(-6, 0), // right
|
|
S(8.5, 8.5, 13.5, 13.5).Move(-6, -6), // top-right corner
|
|
S(5, 10, 5, 15).Move(0, -6), // top
|
|
S(1.5, 8.5, -3.5, 13.5).Move(6, -6), // top-left corner
|
|
}
|
|
for i, seg := range segs {
|
|
t.Run(fmt.Sprintf("Segment-%d", i), func(t *testing.T) {
|
|
testDualRingX(t, shape, func(t *testing.T, ring Ring) {
|
|
expect(t, ringContainsSegment(ring, seg, true))
|
|
expect(t, ringContainsSegment(ring, seg, false))
|
|
seg.A, seg.B = seg.B, seg.A
|
|
expect(t, ringContainsSegment(ring, seg, true))
|
|
expect(t, ringContainsSegment(ring, seg, false))
|
|
})
|
|
})
|
|
}
|
|
})
|
|
t.Run("InsideEdgeToEdge", func(t *testing.T) {
|
|
segs := []Segment{
|
|
S(0, 5, 10, 5), // left to right
|
|
S(1.5, 1.5, 8.5, 8.5), // bottom-left to top-right
|
|
S(5, 0, 5, 10), // bottom to top
|
|
S(8.5, 1.5, 1.5, 8.5), // bottom-right to top-left
|
|
}
|
|
for i, seg := range segs {
|
|
t.Run(fmt.Sprintf("Segment-%d", i), func(t *testing.T) {
|
|
testDualRingX(t, shape, func(t *testing.T, ring Ring) {
|
|
expect(t, ringContainsSegment(ring, seg, true))
|
|
expect(t, !ringContainsSegment(ring, seg, false))
|
|
seg.A, seg.B = seg.B, seg.A
|
|
expect(t, ringContainsSegment(ring, seg, true))
|
|
expect(t, !ringContainsSegment(ring, seg, false))
|
|
})
|
|
})
|
|
}
|
|
})
|
|
t.Run("PassoverEdgeToEdge", func(t *testing.T) {
|
|
segs := []Segment{
|
|
S(-1, 5, 11, 5), // left to right
|
|
S(0.5, 0.5, 9.5, 9.5), // bottom-left to top-right
|
|
S(5, -1, 5, 11), // bottom to top
|
|
S(9.5, 0.5, 0.5, 9.5), // bottom-right to top-left
|
|
}
|
|
for i, seg := range segs {
|
|
t.Run(fmt.Sprintf("Segment-%d", i), func(t *testing.T) {
|
|
testDualRingX(t, shape, func(t *testing.T, ring Ring) {
|
|
expect(t, !ringContainsSegment(ring, seg, true))
|
|
expect(t, !ringContainsSegment(ring, seg, false))
|
|
seg.A, seg.B = seg.B, seg.A
|
|
expect(t, !ringContainsSegment(ring, seg, true))
|
|
expect(t, !ringContainsSegment(ring, seg, false))
|
|
})
|
|
})
|
|
}
|
|
})
|
|
})
|
|
|
|
// concave shape
|
|
t.Run("Concave", func(t *testing.T) {
|
|
shape := concave1
|
|
t.Run("Outside", func(t *testing.T) {
|
|
segs := []Segment{
|
|
S(0, 7.5, -5, 7.5).Move(-1, 0), // left
|
|
S(2.5, 5, 2.5, 0).Move(0, -1), // bottom-left-1
|
|
S(5, 2.5, 0, 2.5).Move(-1, 0), // bottom-left-2
|
|
S(7.5, 0, 7.5, -5).Move(0, -1), // bottom
|
|
S(10, 5, 15, 5).Move(1, 0), // right
|
|
S(5, 10, 5, 15).Move(0, 1), // top
|
|
}
|
|
for i, seg := range segs {
|
|
t.Run(fmt.Sprintf("Segment-%d", i), func(t *testing.T) {
|
|
testDualRingX(t, shape, func(t *testing.T, ring Ring) {
|
|
expect(t, !ringContainsSegment(ring, seg, true))
|
|
expect(t, !ringContainsSegment(ring, seg, false))
|
|
seg.A, seg.B = seg.B, seg.A
|
|
expect(t, !ringContainsSegment(ring, seg, true))
|
|
expect(t, !ringContainsSegment(ring, seg, false))
|
|
})
|
|
})
|
|
}
|
|
})
|
|
t.Run("OutsideEdgeTouch", func(t *testing.T) {
|
|
segs := []Segment{
|
|
S(0, 7.5, -5, 7.5), // left
|
|
S(2.5, 5, 2.5, 0), // bottom-left-1
|
|
S(5, 2.5, 0, 2.5), // bottom-left-2
|
|
S(7.5, 0, 7.5, -5), // bottom
|
|
S(10, 5, 15, 5), // right
|
|
S(5, 10, 5, 15), // top
|
|
}
|
|
for i, seg := range segs {
|
|
t.Run(fmt.Sprintf("Segment-%d", i), func(t *testing.T) {
|
|
testDualRingX(t, shape, func(t *testing.T, ring Ring) {
|
|
expect(t, !ringContainsSegment(ring, seg, true))
|
|
expect(t, !ringContainsSegment(ring, seg, false))
|
|
seg.A, seg.B = seg.B, seg.A
|
|
expect(t, !ringContainsSegment(ring, seg, true))
|
|
expect(t, !ringContainsSegment(ring, seg, false))
|
|
})
|
|
})
|
|
}
|
|
})
|
|
t.Run("EdgeCross", func(t *testing.T) {
|
|
segs := []Segment{
|
|
S(0, 7.5, -5, 7.5).Move(2.5, 0), // left
|
|
S(2.5, 5, 2.5, 0).Move(0, 2.5), // bottom-left-1
|
|
S(5, 2.5, 0, 2.5).Move(2.5, 0), // bottom-left-2
|
|
S(7.5, 0, 7.5, -5).Move(0, 2.5), // bottom
|
|
S(10, 5, 15, 5).Move(-2.5, 0), // right
|
|
S(5, 10, 5, 15).Move(0, -2.5), // top
|
|
}
|
|
for i, seg := range segs {
|
|
t.Run(fmt.Sprintf("Segment-%d", i), func(t *testing.T) {
|
|
testDualRingX(t, shape, func(t *testing.T, ring Ring) {
|
|
expect(t, !ringContainsSegment(ring, seg, true))
|
|
expect(t, !ringContainsSegment(ring, seg, false))
|
|
seg.A, seg.B = seg.B, seg.A
|
|
expect(t, !ringContainsSegment(ring, seg, true))
|
|
expect(t, !ringContainsSegment(ring, seg, false))
|
|
})
|
|
})
|
|
}
|
|
})
|
|
t.Run("InsideEdgeTouch", func(t *testing.T) {
|
|
segs := []Segment{
|
|
S(0, 7.5, -3, 7.5).Move(3, 0), // 0:left
|
|
S(2.5, 5, 2.5, 2).Move(0, 3), // 1:bottom-left-1
|
|
S(5, 2.5, 2, 2.5).Move(3, 0), // 2:bottom-left-2
|
|
S(7.5, 0, 7.5, -3).Move(0, 3), // 3:bottom
|
|
S(10, 5, 13, 5).Move(-3, 0), // 4:right
|
|
S(5, 10, 5, 13).Move(0, -3), // 5:top
|
|
}
|
|
for i, seg := range segs {
|
|
t.Run(fmt.Sprintf("Segment-%d", i), func(t *testing.T) {
|
|
testDualRingX(t, shape, func(t *testing.T, ring Ring) {
|
|
expect(t, ringContainsSegment(ring, seg, true))
|
|
expect(t, !ringContainsSegment(ring, seg, false))
|
|
seg.A, seg.B = seg.B, seg.A
|
|
expect(t, ringContainsSegment(ring, seg, true))
|
|
expect(t, !ringContainsSegment(ring, seg, false))
|
|
})
|
|
})
|
|
}
|
|
})
|
|
t.Run("Inside", func(t *testing.T) {
|
|
segs := []Segment{
|
|
S(0, 7.5, -3, 7.5).Move(4, 0), // 0:left
|
|
S(2.5, 5, 2.5, 2).Move(0, 4), // 1:bottom-left-1
|
|
S(5, 2.5, 2, 2.5).Move(4, 0), // 2:bottom-left-2
|
|
S(7.5, 0, 7.5, -3).Move(0, 4), // 3:bottom
|
|
S(10, 5, 13, 5).Move(-4, 0), // 4:right
|
|
S(5, 10, 5, 13).Move(0, -4), // 5:top
|
|
}
|
|
for i, seg := range segs {
|
|
t.Run(fmt.Sprintf("Segment-%d", i), func(t *testing.T) {
|
|
testDualRingX(t, shape, func(t *testing.T, ring Ring) {
|
|
expect(t, ringContainsSegment(ring, seg, true))
|
|
expect(t, ringContainsSegment(ring, seg, false))
|
|
seg.A, seg.B = seg.B, seg.A
|
|
expect(t, ringContainsSegment(ring, seg, true))
|
|
expect(t, ringContainsSegment(ring, seg, false))
|
|
})
|
|
})
|
|
}
|
|
})
|
|
t.Run("InsideEdgeToEdge", func(t *testing.T) {
|
|
segs := []Segment{
|
|
S(0, 7.5, 10, 7.5), // 0:left
|
|
S(2.5, 5, 2.5, 10), // 1:bottom-left-1
|
|
S(5, 2.5, 10, 2.5), // 2:bottom-left-2
|
|
S(7.5, 0, 7.5, 10), // 3:bottom
|
|
}
|
|
for i, seg := range segs {
|
|
t.Run(fmt.Sprintf("Segment-%d", i), func(t *testing.T) {
|
|
testDualRingX(t, shape, func(t *testing.T, ring Ring) {
|
|
expect(t, ringContainsSegment(ring, seg, true))
|
|
expect(t, !ringContainsSegment(ring, seg, false))
|
|
seg.A, seg.B = seg.B, seg.A
|
|
expect(t, ringContainsSegment(ring, seg, true))
|
|
expect(t, !ringContainsSegment(ring, seg, false))
|
|
})
|
|
})
|
|
}
|
|
})
|
|
t.Run("PassoverEdgeToEdge", func(t *testing.T) {
|
|
segs := []Segment{
|
|
S(-1, 7.5, 11, 7.5), // 0:left
|
|
S(2.5, 4, 2.5, 11), // 1:bottom-left-1
|
|
S(4, 2.5, 11, 2.5), // 2:bottom-left-2
|
|
S(7.5, -1, 7.5, 11), // 3:bottom
|
|
}
|
|
for i, seg := range segs {
|
|
t.Run(fmt.Sprintf("Segment-%d", i), func(t *testing.T) {
|
|
testDualRingX(t, shape, func(t *testing.T, ring Ring) {
|
|
expect(t, !ringContainsSegment(ring, seg, true))
|
|
expect(t, !ringContainsSegment(ring, seg, false))
|
|
seg.A, seg.B = seg.B, seg.A
|
|
expect(t, !ringContainsSegment(ring, seg, true))
|
|
expect(t, !ringContainsSegment(ring, seg, false))
|
|
})
|
|
})
|
|
}
|
|
})
|
|
})
|
|
|
|
t.Run("Cases", func(t *testing.T) {
|
|
ring := newRing([]Point{
|
|
P(0, 0), P(4, 0), P(4, 4), P(3, 4),
|
|
P(2, 3), P(1, 4), P(0, 4), P(0, 0),
|
|
}, DefaultIndex)
|
|
t.Run("1", func(t *testing.T) {
|
|
expect(t, !ringContainsSegment(ring, S(1.5, 3.5, 2.5, 3.5), true))
|
|
expect(t, !ringContainsSegment(ring, S(1.5, 3.5, 2.5, 3.5), false))
|
|
})
|
|
t.Run("2", func(t *testing.T) {
|
|
expect(t, !ringContainsSegment(ring, S(1.0, 3.5, 2.5, 3.5), true))
|
|
expect(t, !ringContainsSegment(ring, S(1.0, 3.5, 2.5, 3.5), false))
|
|
})
|
|
t.Run("3", func(t *testing.T) {
|
|
expect(t, ringContainsSegment(ring, S(1.25, 3.75, 1.75, 3.25), true))
|
|
expect(t, !ringContainsSegment(ring, S(1.25, 3.75, 1.75, 3.25), false))
|
|
})
|
|
t.Run("4", func(t *testing.T) {
|
|
expect(t, !ringContainsSegment(ring, S(1.5, 3.5, 3, 3.5), true))
|
|
expect(t, !ringContainsSegment(ring, S(1.5, 3.5, 3, 3.5), false))
|
|
})
|
|
t.Run("5", func(t *testing.T) {
|
|
expect(t, !ringContainsSegment(ring, S(1.0, 3.5, 3, 3.5), true))
|
|
expect(t, !ringContainsSegment(ring, S(1.0, 3.5, 3, 3.5), false))
|
|
})
|
|
t.Run("6", func(t *testing.T) {
|
|
ring := newRing([]Point{
|
|
P(0, 0), P(4, 0), P(4, 4), P(3, 4),
|
|
P(2, 5), P(1, 4), P(0, 4), P(0, 0),
|
|
}, DefaultIndex)
|
|
expect(t, ringContainsSegment(ring, S(1.5, 4.5, 2.5, 4.5), true))
|
|
expect(t, !ringContainsSegment(ring, S(1.5, 4.5, 2.5, 4.5), false))
|
|
})
|
|
t.Run("7", func(t *testing.T) {
|
|
ring := newRing([]Point{
|
|
P(0, 0), P(4, 0), P(4, 4), P(3, 4),
|
|
P(2.5, 3), P(2, 4), P(1.5, 3),
|
|
P(1, 4), P(0, 4), P(0, 0),
|
|
}, DefaultIndex)
|
|
expect(t, !ringContainsSegment(ring, S(1.25, 3.5, 2.75, 3.5), true))
|
|
expect(t, !ringContainsSegment(ring, S(1.25, 3.5, 2.75, 3.5), false))
|
|
})
|
|
t.Run("8", func(t *testing.T) {
|
|
ring := newRing([]Point{
|
|
P(0, 0), P(4, 0), P(4, 4), P(3, 4),
|
|
P(2.5, 5), P(2, 4), P(1.5, 5),
|
|
P(1, 4), P(0, 4), P(0, 0),
|
|
}, DefaultIndex)
|
|
expect(t, !ringContainsSegment(ring, S(1.25, 4.5, 2.75, 4.5), true))
|
|
expect(t, !ringContainsSegment(ring, S(1.25, 4.5, 2.75, 4.5), false))
|
|
})
|
|
t.Run("9", func(t *testing.T) {
|
|
expect(t, ringContainsSegment(ring, S(1, 2, 3, 2), true))
|
|
expect(t, ringContainsSegment(ring, S(1, 2, 3, 2), false))
|
|
})
|
|
t.Run("10", func(t *testing.T) {
|
|
expect(t, ringContainsSegment(ring, S(1, 3, 3, 2), true))
|
|
expect(t, ringContainsSegment(ring, S(1, 3, 3, 2), false))
|
|
})
|
|
t.Run("11", func(t *testing.T) {
|
|
expect(t, ringContainsSegment(ring, S(1, 2, 3, 3), true))
|
|
expect(t, ringContainsSegment(ring, S(1, 2, 3, 3), false))
|
|
})
|
|
t.Run("12", func(t *testing.T) {
|
|
expect(t, ringContainsSegment(ring, S(1.5, 3.5, 1.5, 2), true))
|
|
expect(t, !ringContainsSegment(ring, S(1.5, 3.5, 1.5, 2), false))
|
|
})
|
|
t.Run("13", func(t *testing.T) {
|
|
ring := newRing([]Point{
|
|
P(0, 0), P(2, 0), P(4, 0), P(4, 4), P(3, 4),
|
|
P(2, 3), P(1, 4), P(0, 4), P(0, 0),
|
|
}, DefaultIndex)
|
|
expect(t, ringContainsSegment(ring, S(1, 0, 3, 0), true))
|
|
expect(t, !ringContainsSegment(ring, S(1, 0, 3, 0), false))
|
|
})
|
|
t.Run("14", func(t *testing.T) {
|
|
ring := newRing([]Point{
|
|
P(0, 0), P(4, 0), P(2, 2), P(0, 4), P(0, 0),
|
|
}, DefaultIndex)
|
|
expect(t, ringContainsSegment(ring, S(1, 3, 3, 1), true))
|
|
expect(t, ringContainsSegment(ring, S(3, 1, 1, 3), true))
|
|
expect(t, !ringContainsSegment(ring, S(1, 3, 3, 1), false))
|
|
expect(t, !ringContainsSegment(ring, S(3, 1, 1, 3), false))
|
|
})
|
|
t.Run("15", func(t *testing.T) {
|
|
expect(t, ringContainsSegment(ring, S(1, 3, 3, 3), true))
|
|
expect(t, !ringContainsSegment(ring, S(1, 3, 3, 3), false))
|
|
})
|
|
t.Run("16", func(t *testing.T) {
|
|
expect(t, ringContainsSegment(ring, S(1, 3, 2, 3), true))
|
|
expect(t, !ringContainsSegment(ring, S(1, 3, 2, 3), false))
|
|
})
|
|
})
|
|
}
|
|
|
|
func TestRingXContainsRing(t *testing.T) {
|
|
t.Run("Empty", func(t *testing.T) {
|
|
expect(t, !ringContainsRing(newRing(nil, DefaultIndex), R(0, 0, 1, 1), true))
|
|
expect(t, !ringContainsRing(R(0, 0, 1, 1), newRing(nil, DefaultIndex), true))
|
|
})
|
|
|
|
t.Run("Exact", func(t *testing.T) {
|
|
expect(t, ringContainsRing(R(0, 0, 1, 1), R(0, 0, 1, 1), true))
|
|
expect(t, !ringContainsRing(R(0, 0, 1, 1), R(0, 0, 1, 1), false))
|
|
expect(t, ringContainsRing(newRing(concave1, DefaultIndex), newRing(concave1, DefaultIndex), true))
|
|
expect(t, !ringContainsRing(newRing(concave1, DefaultIndex), newRing(concave1, DefaultIndex), false))
|
|
expect(t, ringContainsRing(newRing(octagon, DefaultIndex), newRing(octagon, DefaultIndex), true))
|
|
expect(t, !ringContainsRing(newRing(octagon, DefaultIndex), newRing(octagon, DefaultIndex), false))
|
|
})
|
|
t.Run("Cases", func(t *testing.T) {
|
|
// concave
|
|
ring := newRing([]Point{
|
|
P(0, 0), P(4, 0), P(4, 4), P(3, 4),
|
|
P(2, 3), P(1, 4), P(0, 4), P(0, 0),
|
|
}, DefaultIndex)
|
|
t.Run("1", func(t *testing.T) {
|
|
expect(t, ringContainsRing(ring, R(1, 1, 3, 2), true))
|
|
expect(t, ringContainsRing(ring, R(1, 1, 3, 2), false))
|
|
})
|
|
t.Run("2", func(t *testing.T) {
|
|
expect(t, ringContainsRing(ring, R(0, 0, 2, 1), true))
|
|
expect(t, !ringContainsRing(ring, R(0, 0, 2, 1), false))
|
|
})
|
|
t.Run("3", func(t *testing.T) {
|
|
expect(t, !ringContainsRing(ring, R(-1.5, 1, 1.5, 2), true))
|
|
expect(t, !ringContainsRing(ring, R(-1.5, 1, 1.5, 2), false))
|
|
})
|
|
t.Run("4", func(t *testing.T) {
|
|
expect(t, !ringContainsRing(ring, R(1, 2.5, 3, 3.5), true))
|
|
expect(t, !ringContainsRing(ring, R(1, 2.5, 3, 3.5), false))
|
|
})
|
|
t.Run("5", func(t *testing.T) {
|
|
expect(t, ringContainsRing(ring, R(1, 2, 3, 3), true))
|
|
expect(t, !ringContainsRing(ring, R(1, 2, 3, 3), false))
|
|
})
|
|
// convex
|
|
ring = newRing([]Point{
|
|
P(0, 0), P(4, 0), P(4, 4),
|
|
P(3, 4), P(2, 5), P(1, 4),
|
|
P(0, 4), P(0, 0),
|
|
}, DefaultIndex)
|
|
t.Run("6", func(t *testing.T) {
|
|
expect(t, ringContainsRing(ring, R(1, 2, 3, 3), true))
|
|
expect(t, ringContainsRing(ring, R(1, 2, 3, 3), false))
|
|
})
|
|
t.Run("7", func(t *testing.T) {
|
|
expect(t, ringContainsRing(ring, R(1, 3, 3, 4), true))
|
|
expect(t, !ringContainsRing(ring, R(1, 3, 3, 4), false))
|
|
})
|
|
t.Run("8", func(t *testing.T) {
|
|
expect(t, !ringContainsRing(ring, R(1, 3.5, 3, 4.5), true))
|
|
expect(t, !ringContainsRing(ring, R(1, 3.5, 3, 4.5), false))
|
|
})
|
|
t.Run("9", func(t *testing.T) {
|
|
ring = newRing([]Point{
|
|
P(0, 0), P(2, 0), P(4, 0), P(4, 4), P(3, 4),
|
|
P(2, 5), P(1, 4), P(0, 4), P(0, 0),
|
|
}, DefaultIndex)
|
|
expect(t, ringContainsRing(ring, R(1, 0, 3, 1), true))
|
|
expect(t, !ringContainsRing(ring, R(1, 0, 3, 1), false))
|
|
})
|
|
t.Run("10", func(t *testing.T) {
|
|
ring = newRing([]Point{
|
|
P(0, 0), P(4, 0), P(4, 3), P(2, 4),
|
|
P(0, 3), P(0, 0),
|
|
}, DefaultIndex)
|
|
expect(t, ringContainsRing(ring, R(1, 1, 3, 2), true))
|
|
expect(t, ringContainsRing(ring, R(1, 1, 3, 2), false))
|
|
})
|
|
ring = newRing([]Point{
|
|
P(0, 0), P(4, 0), P(4, 3), P(3, 4), P(1, 4), P(0, 3), P(0, 0),
|
|
}, DefaultIndex)
|
|
t.Run("11", func(t *testing.T) {
|
|
expect(t, ringContainsRing(ring, R(1, 1, 3, 2), true))
|
|
expect(t, ringContainsRing(ring, R(1, 1, 3, 2), false))
|
|
})
|
|
t.Run("12", func(t *testing.T) {
|
|
expect(t, ringContainsRing(ring, R(0, 1, 2, 2), true))
|
|
expect(t, !ringContainsRing(ring, R(0, 1, 2, 2), false))
|
|
})
|
|
t.Run("13", func(t *testing.T) {
|
|
expect(t, !ringContainsRing(ring, R(-1, 1, 1, 2), true))
|
|
expect(t, !ringContainsRing(ring, R(-1, 1, 1, 2), false))
|
|
})
|
|
t.Run("14", func(t *testing.T) {
|
|
expect(t, ringContainsRing(ring, R(0.5, 2.5, 2.5, 3.5), true))
|
|
expect(t, !ringContainsRing(ring, R(0.5, 2.5, 2.5, 3.5), false))
|
|
})
|
|
t.Run("15", func(t *testing.T) {
|
|
expect(t, !ringContainsRing(ring, R(0.25, 2.75, 2.25, 3.75), true))
|
|
expect(t, !ringContainsRing(ring, R(0.25, 2.75, 2.25, 3.75), false))
|
|
})
|
|
t.Run("16", func(t *testing.T) {
|
|
expect(t, !ringContainsRing(ring, R(-2, 1, -1, 2), true))
|
|
expect(t, !ringContainsRing(ring, R(-2, 1, -1, 2), false))
|
|
})
|
|
t.Run("17", func(t *testing.T) {
|
|
expect(t, !ringContainsRing(ring, R(-0.5, 3.5, 0.5, 4.5), true))
|
|
expect(t, !ringContainsRing(ring, R(-0.5, 3.5, 0.5, 4.5), false))
|
|
})
|
|
t.Run("18", func(t *testing.T) {
|
|
expect(t, !ringContainsRing(ring, R(-0.75, 3.75, 0.25, 4.75), true))
|
|
expect(t, !ringContainsRing(ring, R(-0.74, 3.75, 0.25, 4.75), false))
|
|
})
|
|
t.Run("19", func(t *testing.T) {
|
|
expect(t, !ringContainsRing(ring, R(-1, -1, 5, 5), true))
|
|
expect(t, !ringContainsRing(ring, R(-1, -1, 5, 5), false))
|
|
})
|
|
|
|
})
|
|
t.Run("Identical", func(t *testing.T) {
|
|
shapes := []Ring{
|
|
R(0, 0, 10, 10),
|
|
newRing(octagon, DefaultIndex),
|
|
newRing(concave1, DefaultIndex), newRing(concave2, DefaultIndex),
|
|
newRing(concave3, DefaultIndex), newRing(concave4, DefaultIndex),
|
|
newRing(ri, DefaultIndex),
|
|
}
|
|
for i, shape := range shapes {
|
|
t.Run(fmt.Sprintf("Shape%d", i), func(t *testing.T) {
|
|
expect(t, ringContainsRing(shape, shape, true))
|
|
})
|
|
}
|
|
})
|
|
|
|
t.Run("Big", func(t *testing.T) {
|
|
// use rhode island
|
|
ring := newRing(ri, DefaultIndex)
|
|
expect(t, ringContainsRing(ring.Rect(), ring, true))
|
|
expect(t, ringContainsRing(ring, ring, true))
|
|
|
|
})
|
|
}
|
|
|
|
func TestRingXIntersectsRing(t *testing.T) {
|
|
intersectsBothWays := func(ringA, ringB Ring, allowOnEdge bool) bool {
|
|
t1 := ringIntersectsRing(ringA, ringB, allowOnEdge)
|
|
t2 := ringIntersectsRing(ringB, ringA, allowOnEdge)
|
|
if t1 != t2 {
|
|
panic("mismatch")
|
|
}
|
|
return t1
|
|
}
|
|
t.Run("Empty", func(t *testing.T) {
|
|
expect(t, !intersectsBothWays(newRing(nil, DefaultIndex), R(0, 0, 1, 1), true))
|
|
expect(t, !intersectsBothWays(R(0, 0, 1, 1), newRing(nil, DefaultIndex), true))
|
|
})
|
|
t.Run("Cases", func(t *testing.T) {
|
|
// concave
|
|
ring := newRing([]Point{
|
|
P(0, 0), P(4, 0), P(4, 4), P(3, 4),
|
|
P(2, 3), P(1, 4), P(0, 4), P(0, 0),
|
|
}, DefaultIndex)
|
|
t.Run("1", func(t *testing.T) {
|
|
expect(t, intersectsBothWays(ring, R(1, 1, 3, 2), true))
|
|
expect(t, intersectsBothWays(ring, R(1, 1, 3, 2), false))
|
|
})
|
|
t.Run("2", func(t *testing.T) {
|
|
expect(t, intersectsBothWays(ring, R(0, 0, 2, 1), true))
|
|
expect(t, intersectsBothWays(ring, R(0, 0, 2, 1), false))
|
|
})
|
|
t.Run("3", func(t *testing.T) {
|
|
expect(t, intersectsBothWays(ring, R(-1.5, 1, 1.5, 2), true))
|
|
expect(t, intersectsBothWays(ring, R(-1.5, 1, 1.5, 2), false))
|
|
})
|
|
t.Run("4", func(t *testing.T) {
|
|
expect(t, intersectsBothWays(ring, R(1, 2.5, 3, 3.5), true))
|
|
expect(t, intersectsBothWays(ring, R(1, 2.5, 3, 3.5), false))
|
|
})
|
|
t.Run("5", func(t *testing.T) {
|
|
expect(t, intersectsBothWays(ring, R(1, 2, 3, 3), true))
|
|
expect(t, intersectsBothWays(ring, R(1, 2, 3, 3), false))
|
|
})
|
|
// convex
|
|
ring = newRing([]Point{
|
|
P(0, 0), P(4, 0), P(4, 4),
|
|
P(3, 4), P(2, 5), P(1, 4),
|
|
P(0, 4), P(0, 0),
|
|
}, DefaultIndex)
|
|
t.Run("6", func(t *testing.T) {
|
|
expect(t, intersectsBothWays(ring, R(1, 2, 3, 3), true))
|
|
expect(t, intersectsBothWays(ring, R(1, 2, 3, 3), false))
|
|
})
|
|
t.Run("7", func(t *testing.T) {
|
|
expect(t, intersectsBothWays(ring, R(1, 3, 3, 4), true))
|
|
expect(t, intersectsBothWays(ring, R(1, 3, 3, 4), false))
|
|
})
|
|
t.Run("8", func(t *testing.T) {
|
|
expect(t, intersectsBothWays(ring, R(1, 3.5, 3, 4.5), true))
|
|
expect(t, intersectsBothWays(ring, R(1, 3.5, 3, 4.5), false))
|
|
})
|
|
t.Run("9", func(t *testing.T) {
|
|
ring = newRing([]Point{
|
|
P(0, 0), P(2, 0), P(4, 0), P(4, 4), P(3, 4),
|
|
P(2, 5), P(1, 4), P(0, 4), P(0, 0),
|
|
}, DefaultIndex)
|
|
expect(t, intersectsBothWays(ring, R(1, 0, 3, 1), true))
|
|
expect(t, intersectsBothWays(ring, R(1, 0, 3, 1), false))
|
|
})
|
|
t.Run("10", func(t *testing.T) {
|
|
ring = newRing([]Point{
|
|
P(0, 0), P(4, 0), P(4, 3), P(2, 4),
|
|
P(0, 3), P(0, 0),
|
|
}, DefaultIndex)
|
|
expect(t, intersectsBothWays(ring, R(1, 1, 3, 2), true))
|
|
expect(t, intersectsBothWays(ring, R(1, 1, 3, 2), false))
|
|
})
|
|
ring = newRing([]Point{
|
|
P(0, 0), P(4, 0), P(4, 3), P(3, 4), P(1, 4), P(0, 3), P(0, 0),
|
|
}, DefaultIndex)
|
|
t.Run("11", func(t *testing.T) {
|
|
expect(t, intersectsBothWays(ring, R(1, 1, 3, 2), true))
|
|
expect(t, intersectsBothWays(ring, R(1, 1, 3, 2), false))
|
|
})
|
|
t.Run("12", func(t *testing.T) {
|
|
expect(t, intersectsBothWays(ring, R(0, 1, 2, 2), true))
|
|
expect(t, intersectsBothWays(ring, R(0, 1, 2, 2), false))
|
|
})
|
|
t.Run("13", func(t *testing.T) {
|
|
expect(t, intersectsBothWays(ring, R(-1, 1, 1, 2), true))
|
|
expect(t, intersectsBothWays(ring, R(-1, 1, 1, 2), false))
|
|
})
|
|
t.Run("14", func(t *testing.T) {
|
|
expect(t, intersectsBothWays(ring, R(0.5, 2.5, 2.5, 3.5), true))
|
|
expect(t, intersectsBothWays(ring, R(0.5, 2.5, 2.5, 3.5), false))
|
|
})
|
|
t.Run("15", func(t *testing.T) {
|
|
expect(t, intersectsBothWays(ring, R(0.25, 2.75, 2.25, 3.75), true))
|
|
expect(t, intersectsBothWays(ring, R(0.25, 2.75, 2.25, 3.75), false))
|
|
})
|
|
t.Run("16", func(t *testing.T) {
|
|
expect(t, !intersectsBothWays(ring, R(-2, 1, -1, 2), true))
|
|
expect(t, !intersectsBothWays(ring, R(-2, 1, -1, 2), false))
|
|
})
|
|
t.Run("17", func(t *testing.T) {
|
|
expect(t, intersectsBothWays(ring, R(-0.5, 3.5, 0.5, 4.5), true))
|
|
expect(t, !intersectsBothWays(ring, R(-0.5, 3.5, 0.5, 4.5), false))
|
|
})
|
|
t.Run("18", func(t *testing.T) {
|
|
expect(t, !intersectsBothWays(ring, R(-0.75, 3.75, 0.25, 4.75), true))
|
|
expect(t, !intersectsBothWays(ring, R(-0.74, 3.75, 0.25, 4.75), false))
|
|
})
|
|
t.Run("19", func(t *testing.T) {
|
|
expect(t, ringIntersectsRing(ring, R(-1, -1, 5, 5), true))
|
|
expect(t, ringIntersectsRing(ring, R(-1, -1, 5, 5), false))
|
|
})
|
|
})
|
|
}
|
|
|
|
func TestRingXContainsLine(t *testing.T) {
|
|
t.Run("Cases", func(t *testing.T) {
|
|
// convex
|
|
ring := newRing([]Point{
|
|
P(0, 0), P(4, 0), P(4, 3),
|
|
P(3, 4), P(1, 4),
|
|
P(0, 3), P(0, 0),
|
|
}, DefaultIndex)
|
|
makeLine := func(start Point) *Line {
|
|
return NewLine([]Point{
|
|
start, start.Move(0, 1), start.Move(1, 1),
|
|
start.Move(1, 2), start.Move(2, 2),
|
|
}, DefaultIndex)
|
|
}
|
|
t.Run("1", func(t *testing.T) {
|
|
expect(t, ringContainsLine(ring, makeLine(P(1, 1)), true))
|
|
expect(t, ringContainsLine(ring, makeLine(P(1, 1)), false))
|
|
})
|
|
t.Run("2", func(t *testing.T) {
|
|
expect(t, ringContainsLine(ring, makeLine(P(0, 1)), true))
|
|
expect(t, !ringContainsLine(ring, makeLine(P(0, 1)), false))
|
|
})
|
|
t.Run("3", func(t *testing.T) {
|
|
expect(t, !ringContainsLine(ring, makeLine(P(-0.5, 1)), true))
|
|
expect(t, !ringContainsLine(ring, makeLine(P(-0.5, 1)), false))
|
|
})
|
|
t.Run("4", func(t *testing.T) {
|
|
expect(t, ringContainsLine(ring, makeLine(P(0, 2)), true))
|
|
expect(t, !ringContainsLine(ring, makeLine(P(0, 2)), false))
|
|
})
|
|
t.Run("5", func(t *testing.T) {
|
|
expect(t, !ringContainsLine(ring, makeLine(P(0, 2.5)), true))
|
|
expect(t, !ringContainsLine(ring, makeLine(P(0, 2.5)), false))
|
|
})
|
|
t.Run("6", func(t *testing.T) {
|
|
expect(t, !ringContainsLine(ring, makeLine(P(2, 2)), true))
|
|
expect(t, !ringContainsLine(ring, makeLine(P(2, 2)), false))
|
|
})
|
|
t.Run("7", func(t *testing.T) {
|
|
expect(t, !ringContainsLine(ring, makeLine(P(2, 1.5)), true))
|
|
expect(t, !ringContainsLine(ring, makeLine(P(2, 1.5)), false))
|
|
})
|
|
t.Run("8", func(t *testing.T) {
|
|
expect(t, ringContainsLine(ring, makeLine(P(2, 1)), true))
|
|
expect(t, !ringContainsLine(ring, makeLine(P(2, 1)), false))
|
|
})
|
|
t.Run("9", func(t *testing.T) {
|
|
expect(t, ringContainsLine(ring, makeLine(P(2, 0)), true))
|
|
expect(t, !ringContainsLine(ring, makeLine(P(2, 0)), false))
|
|
})
|
|
t.Run("10", func(t *testing.T) {
|
|
expect(t, ringContainsLine(ring, makeLine(P(1.5, 0)), true))
|
|
expect(t, !ringContainsLine(ring, makeLine(P(1.5, 0)), false))
|
|
})
|
|
t.Run("11", func(t *testing.T) {
|
|
expect(t, !ringContainsLine(ring, makeLine(P(1, -1)), true))
|
|
expect(t, !ringContainsLine(ring, makeLine(P(1, -1)), false))
|
|
})
|
|
t.Run("12", func(t *testing.T) {
|
|
expect(t, !ringContainsLine(ring, makeLine(P(1.5, -0.5)), true))
|
|
expect(t, !ringContainsLine(ring, makeLine(P(1.5, -0.5)), false))
|
|
})
|
|
t.Run("13", func(t *testing.T) {
|
|
expect(t, ringContainsLine(ring, makeLine(P(0, 0)), true))
|
|
expect(t, !ringContainsLine(ring, makeLine(P(0, 0)), false))
|
|
})
|
|
t.Run("14", func(t *testing.T) {
|
|
expect(t, !ringContainsLine(ring, makeLine(P(3, 1)), true))
|
|
expect(t, !ringContainsLine(ring, makeLine(P(3, 1)), false))
|
|
})
|
|
t.Run("15", func(t *testing.T) {
|
|
line := L(P(-1, -1), P(-1, 2), P(2, 2), P(2, 5), P(5, 5))
|
|
expect(t, !ringContainsLine(ring, line, true))
|
|
expect(t, !ringContainsLine(ring, line, false))
|
|
})
|
|
t.Run("16", func(t *testing.T) {
|
|
line := L(P(0, -1), P(0, 1), P(3, 3), P(5, 3))
|
|
expect(t, !ringContainsLine(ring, line, true))
|
|
expect(t, !ringContainsLine(ring, line, false))
|
|
})
|
|
t.Run("17", func(t *testing.T) {
|
|
line := L(P(-1, 2), P(2, 1), P(5, 2))
|
|
expect(t, !ringContainsLine(ring, line, true))
|
|
expect(t, !ringContainsLine(ring, line, false))
|
|
})
|
|
t.Run("18", func(t *testing.T) {
|
|
line := L(P(1, -1), P(3, 2), P(2, 5))
|
|
expect(t, !ringContainsLine(ring, line, true))
|
|
expect(t, !ringContainsLine(ring, line, false))
|
|
})
|
|
t.Run("19", func(t *testing.T) {
|
|
line := L(P(3.5, 4.5), P(3.5, 3.5), P(5, 3.5), P(5, 2.5))
|
|
expect(t, !ringContainsLine(ring, line, true))
|
|
expect(t, !ringContainsLine(ring, line, false))
|
|
})
|
|
t.Run("20", func(t *testing.T) {
|
|
line := L(P(4, 5), P(4, 4), P(5, 4), P(5, 3))
|
|
expect(t, !ringContainsLine(ring, line, true))
|
|
expect(t, !ringContainsLine(ring, line, false))
|
|
})
|
|
t.Run("21", func(t *testing.T) {
|
|
line := L(P(1, -1), P(1, -2), P(2, -2), P(2, -3))
|
|
expect(t, !ringContainsLine(ring, line, true))
|
|
expect(t, !ringContainsLine(ring, line, false))
|
|
})
|
|
})
|
|
}
|
|
|
|
func TestRingXIntersectsLine(t *testing.T) {
|
|
t.Run("Various", func(t *testing.T) {
|
|
expect(t, !ringIntersectsLine(R(0, 0, 0, 0), L(), true))
|
|
expect(t, !ringIntersectsLine(R(0, 0, 10, 10),
|
|
L(P(-1, -1), P(11, -1), P(11, 11), P(-1, 11)),
|
|
true))
|
|
expect(t, ringIntersectsLine(R(0, 0, 10, 10),
|
|
L(P(-1, -1), P(11, -1), P(11, 11), P(-1, 11), P(5, -1)),
|
|
true))
|
|
})
|
|
|
|
t.Run("Cases", func(t *testing.T) {
|
|
// convex
|
|
ring := newRing([]Point{
|
|
P(0, 0), P(4, 0), P(4, 3),
|
|
P(3, 4), P(1, 4),
|
|
P(0, 3), P(0, 0),
|
|
}, DefaultIndex)
|
|
makeLine := func(start Point) *Line {
|
|
return NewLine([]Point{
|
|
start, start.Move(0, 1), start.Move(1, 1),
|
|
start.Move(1, 2), start.Move(2, 2),
|
|
}, DefaultIndex)
|
|
}
|
|
t.Run("1", func(t *testing.T) {
|
|
expect(t, ringIntersectsLine(ring, makeLine(P(1, 1)), true))
|
|
expect(t, ringIntersectsLine(ring, makeLine(P(1, 1)), false))
|
|
})
|
|
t.Run("2", func(t *testing.T) {
|
|
expect(t, ringIntersectsLine(ring, makeLine(P(0, 1)), true))
|
|
expect(t, ringIntersectsLine(ring, makeLine(P(0, 1)), false))
|
|
})
|
|
t.Run("3", func(t *testing.T) {
|
|
expect(t, ringIntersectsLine(ring, makeLine(P(-0.5, 1)), true))
|
|
expect(t, ringIntersectsLine(ring, makeLine(P(-0.5, 1)), false))
|
|
})
|
|
t.Run("4", func(t *testing.T) {
|
|
expect(t, ringIntersectsLine(ring, makeLine(P(0, 2)), true))
|
|
expect(t, ringIntersectsLine(ring, makeLine(P(0, 2)), false))
|
|
})
|
|
t.Run("5", func(t *testing.T) {
|
|
expect(t, ringIntersectsLine(ring, makeLine(P(0, 2.5)), true))
|
|
expect(t, ringIntersectsLine(ring, makeLine(P(0, 2.5)), false))
|
|
})
|
|
t.Run("6", func(t *testing.T) {
|
|
expect(t, ringIntersectsLine(ring, makeLine(P(2, 2)), true))
|
|
expect(t, ringIntersectsLine(ring, makeLine(P(2, 2)), false))
|
|
})
|
|
t.Run("7", func(t *testing.T) {
|
|
expect(t, ringIntersectsLine(ring, makeLine(P(2, 1.5)), true))
|
|
expect(t, ringIntersectsLine(ring, makeLine(P(2, 1.5)), false))
|
|
})
|
|
t.Run("8", func(t *testing.T) {
|
|
expect(t, ringIntersectsLine(ring, makeLine(P(2, 1)), true))
|
|
expect(t, ringIntersectsLine(ring, makeLine(P(2, 1)), false))
|
|
})
|
|
t.Run("9", func(t *testing.T) {
|
|
expect(t, ringIntersectsLine(ring, makeLine(P(2, 0)), true))
|
|
expect(t, ringIntersectsLine(ring, makeLine(P(2, 0)), false))
|
|
})
|
|
t.Run("10", func(t *testing.T) {
|
|
expect(t, ringIntersectsLine(ring, makeLine(P(1.5, 0)), true))
|
|
expect(t, ringIntersectsLine(ring, makeLine(P(1.5, 0)), false))
|
|
})
|
|
t.Run("11", func(t *testing.T) {
|
|
expect(t, ringIntersectsLine(ring, makeLine(P(1, -1)), true))
|
|
expect(t, ringIntersectsLine(ring, makeLine(P(1, -1)), false))
|
|
})
|
|
t.Run("12", func(t *testing.T) {
|
|
expect(t, ringIntersectsLine(ring, makeLine(P(1.5, -0.5)), true))
|
|
expect(t, ringIntersectsLine(ring, makeLine(P(1.5, -0.5)), false))
|
|
})
|
|
t.Run("13", func(t *testing.T) {
|
|
expect(t, ringIntersectsLine(ring, makeLine(P(0, 0)), true))
|
|
expect(t, ringIntersectsLine(ring, makeLine(P(0, 0)), false))
|
|
})
|
|
t.Run("14", func(t *testing.T) {
|
|
expect(t, ringIntersectsLine(ring, makeLine(P(3, 1)), true))
|
|
expect(t, ringIntersectsLine(ring, makeLine(P(3, 1)), false))
|
|
})
|
|
t.Run("15", func(t *testing.T) {
|
|
line := L(P(-1, -1), P(-1, 2), P(2, 2), P(2, 5), P(5, 5))
|
|
expect(t, ringIntersectsLine(ring, line, true))
|
|
expect(t, ringIntersectsLine(ring, line, false))
|
|
})
|
|
t.Run("16", func(t *testing.T) {
|
|
line := L(P(0, -1), P(0, 1), P(3, 3), P(5, 3))
|
|
expect(t, ringIntersectsLine(ring, line, true))
|
|
expect(t, ringIntersectsLine(ring, line, false))
|
|
})
|
|
t.Run("17", func(t *testing.T) {
|
|
line := L(P(-1, 2), P(2, 1), P(5, 2))
|
|
expect(t, ringIntersectsLine(ring, line, true))
|
|
expect(t, ringIntersectsLine(ring, line, false))
|
|
})
|
|
t.Run("18", func(t *testing.T) {
|
|
line := L(P(1, -1), P(3, 2), P(2, 5))
|
|
expect(t, ringIntersectsLine(ring, line, true))
|
|
expect(t, ringIntersectsLine(ring, line, false))
|
|
})
|
|
t.Run("19", func(t *testing.T) {
|
|
line := L(P(3.5, 4.5), P(3.5, 3.5), P(5, 3.5), P(5, 2.5))
|
|
expect(t, ringIntersectsLine(ring, line, true))
|
|
expect(t, !ringIntersectsLine(ring, line, false))
|
|
})
|
|
t.Run("20", func(t *testing.T) {
|
|
line := L(P(4, 5), P(4, 4), P(5, 4), P(5, 3))
|
|
expect(t, !ringIntersectsLine(ring, line, true))
|
|
expect(t, !ringIntersectsLine(ring, line, false))
|
|
})
|
|
t.Run("21", func(t *testing.T) {
|
|
line := L(P(1, -1), P(1, -2), P(2, -2), P(2, -3))
|
|
expect(t, !ringIntersectsLine(ring, line, true))
|
|
expect(t, !ringIntersectsLine(ring, line, false))
|
|
})
|
|
})
|
|
}
|