diff --git a/point.go b/point.go index 032f180..84a330f 100644 --- a/point.go +++ b/point.go @@ -11,7 +11,7 @@ func distance(p1, p2 Point) float64 { } func onLine(rp1, rp2, p Point) bool { - if distance(rp1, p)+distance(rp2, p) == distance(rp1, rp2) { + if math.Abs(distance(rp1, p)+distance(rp2, p)-distance(rp1, rp2)) < ɛ { minx, maxx := math.Min(rp1.X, rp2.X), math.Max(rp1.X, rp2.X) miny, maxy := math.Min(rp1.Y, rp2.Y), math.Max(rp1.Y, rp2.Y) if minx <= p.X && p.X <= maxx && miny <= p.Y && p.Y <= maxy { diff --git a/rectangle.go b/rectangle.go index be326d5..a2d6197 100644 --- a/rectangle.go +++ b/rectangle.go @@ -9,7 +9,10 @@ type Rectangle struct { P1, P2, P3, P4 Point } -func (r Rectangle) IsRect() bool { +// maximum error used for floating point math +var ɛ = 0.00001 + +func (r Rectangle) isRect() bool { // make sure they aren't all just the same point if (r.P1.X == r.P2.X && r.P1.X == r.P3.X && r.P1.X == r.P4.X) && (r.P1.Y == r.P2.Y && r.P1.Y == r.P3.Y && r.P1.Y == r.P4.Y) { @@ -23,39 +26,39 @@ func (r Rectangle) IsRect() bool { dd2 := math.Sqrt(math.Abs(cx-r.P2.X)) + math.Sqrt(math.Abs(cy-r.P2.Y)) dd3 := math.Sqrt(math.Abs(cx-r.P3.X)) + math.Sqrt(math.Abs(cy-r.P3.Y)) dd4 := math.Sqrt(math.Abs(cx-r.P4.X)) + math.Sqrt(math.Abs(cy-r.P4.Y)) - return dd1 == dd2 && dd1 == dd3 && dd1 == dd4 + return math.Abs(dd1-dd2) < ɛ && math.Abs(dd1-dd3) < ɛ && math.Abs(dd1-dd4) < ɛ } -func (r Rectangle) Neighbors(p Point) (Point, Point) { +func (r Rectangle) neighbors(p Point) (Point, Point) { keys := []float64{distance(r.P1, p), distance(r.P2, p), distance(r.P3, p), distance(r.P4, p)} sort.Float64s(keys) n := []Point{} d := distance(r.P1, p) - if keys[1] == d || keys[2] == d { + if math.Abs(keys[1]-d) < ɛ || math.Abs(keys[2]-d) < ɛ { n = append(n, r.P1) } d = distance(r.P2, p) - if keys[1] == d || keys[2] == d { + if math.Abs(keys[1]-d) < ɛ || math.Abs(keys[2]-d) < ɛ { n = append(n, r.P2) } d = distance(r.P3, p) - if keys[1] == d || keys[2] == d { + if math.Abs(keys[1]-d) < ɛ || math.Abs(keys[2]-d) < ɛ { n = append(n, r.P3) } d = distance(r.P4, p) - if keys[1] == d || keys[2] == d { + if math.Abs(keys[1]-d) < ɛ || math.Abs(keys[2]-d) < ɛ { n = append(n, r.P4) } return n[0], n[1] } -func (r Rectangle) Size() float64 { - n1, n2 := r.Neighbors(r.P1) +func (r Rectangle) size() float64 { + n1, n2 := r.neighbors(r.P1) return distance(r.P1, n1) * distance(r.P1, n2) } func (r Rectangle) inOrder() []Point { - n1, n2 := r.Neighbors(r.P1) + n1, n2 := r.neighbors(r.P1) accross := &Point{} if r.P2 != n1 || r.P2 != n2 { accross = &r.P2 @@ -126,26 +129,26 @@ func Intersection(r1, r2 Rectangle) []Point { } func sumOfTri(r Rectangle, p Point) bool { - n1, n2 := r.Neighbors(r.P1) + n1, n2 := r.neighbors(r.P1) x1, x2 := Point{}, Point{} accross := &Point{} if r.P2 != n1 || r.P2 != n2 { accross = &r.P2 - x1, x2 = r.Neighbors(r.P2) + x1, x2 = r.neighbors(r.P2) } if r.P3 != n1 || r.P3 != n2 { accross = &r.P3 - x1, x2 = r.Neighbors(r.P3) + x1, x2 = r.neighbors(r.P3) } if r.P4 != n1 || r.P4 != n2 { accross = &r.P4 - x1, x2 = r.Neighbors(r.P4) + x1, x2 = r.neighbors(r.P4) } - sumTri := SizeTriangle(r.P1, n1, p) + - SizeTriangle(r.P1, n2, p) + - SizeTriangle(*accross, x1, p) + - SizeTriangle(*accross, x2, p) - if r.Size() == sumTri { + sumTri := sizeTriangle(r.P1, n1, p) + + sizeTriangle(r.P1, n2, p) + + sizeTriangle(*accross, x1, p) + + sizeTriangle(*accross, x2, p) + if math.Abs(r.size()-sumTri) < ɛ { return true } return false @@ -153,7 +156,7 @@ func sumOfTri(r Rectangle, p Point) bool { // Containment returns whether r2 is contained inside of r1 func Containment(r1, r2 Rectangle) bool { - if r1.Size() <= r2.Size() { + if r1.size() <= r2.size() { return false } if sumOfTri(r1, r2.P1) && sumOfTri(r1, r2.P2) && sumOfTri(r1, r2.P3) && sumOfTri(r1, r2.P4) { diff --git a/triangle.go b/triangle.go index 489dfda..c860a96 100644 --- a/triangle.go +++ b/triangle.go @@ -2,6 +2,6 @@ package rect import "math" -func SizeTriangle(p1, p2, p3 Point) float64 { +func sizeTriangle(p1, p2, p3 Point) float64 { return math.Abs((p1.X*p2.Y + p2.X*p3.Y + p3.X*p1.Y - p1.Y*p2.X - p2.Y*p3.X - p3.Y*p1.X) / 2) } diff --git a/triangle_test.go b/triangle_test.go index cf80b43..2c301ec 100644 --- a/triangle_test.go +++ b/triangle_test.go @@ -12,7 +12,7 @@ func TestSizeTriangle(t *testing.T) { {[]Point{Point{10, 14}, Point{20, 15}, Point{12, 52}}, 189}, } for _, rt := range sizeTriangleTests { - actual := SizeTriangle(rt.pts[0], rt.pts[1], rt.pts[2]) + actual := sizeTriangle(rt.pts[0], rt.pts[1], rt.pts[2]) if actual != rt.expected { t.Errorf( "failed sizeTriangle:\n\texpected: %f\n\t actual: %f",