From 9b908a8db1b5cf2444c03d1a90c3e9836ec66919 Mon Sep 17 00:00:00 2001 From: Derek McQuay Date: Sat, 27 Aug 2016 20:46:32 -0700 Subject: [PATCH] changed permission on func and added maximum error made sure that not all functions were public and changed some to private that need not be exposed. also added in maximum error to deal with floating point inaccuracies --- point.go | 2 +- rectangle.go | 43 +++++++++++++++++++++++-------------------- triangle.go | 2 +- triangle_test.go | 2 +- 4 files changed, 26 insertions(+), 23 deletions(-) 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",