From 3850bdc59212bda48b8af8277b5f0be7120826d5 Mon Sep 17 00:00:00 2001 From: Derek McQuay Date: Sat, 27 Aug 2016 19:10:42 -0700 Subject: [PATCH] created line.go and moved tests and funcs --- line.go | 45 +++++++++++++++++++++++++++++++++++++++++++ line_test.go | 49 +++++++++++++++++++++++++++++++++++++++++++++++ point.go | 44 +----------------------------------------- point_test.go | 46 -------------------------------------------- rectangle_test.go | 4 ++-- 5 files changed, 97 insertions(+), 91 deletions(-) create mode 100644 line.go create mode 100644 line_test.go diff --git a/line.go b/line.go new file mode 100644 index 0000000..f97e641 --- /dev/null +++ b/line.go @@ -0,0 +1,45 @@ +package rect + +import ( + "fmt" + "math" +) + +type line struct { + pt1, pt2 Point +} + +func lineHelper(l line) (float64, float64, float64) { + a := l.pt2.Y - l.pt1.Y + b := l.pt1.X - l.pt2.X + c := a*l.pt1.X + b*l.pt1.Y + return a, b, c +} + +func lineIntersection(l1, l2 line) (Point, error) { + a1, b1, c1 := lineHelper(l1) + a2, b2, c2 := lineHelper(l2) + det := a1*b2 - a2*b1 + + if det != 0 { + x := ((b2*c1 - b1*c2) / det) + y := ((a1*c2 - a2*c1) / det) + minx1, maxx1 := math.Min(l1.pt1.X, l1.pt2.X), math.Max(l1.pt1.X, l1.pt2.X) + miny1, maxy1 := math.Min(l1.pt1.Y, l1.pt2.Y), math.Max(l1.pt1.Y, l1.pt2.Y) + minx2, maxx2 := math.Min(l2.pt1.X, l2.pt2.X), math.Max(l2.pt1.X, l2.pt2.X) + miny2, maxy2 := math.Min(l2.pt1.Y, l2.pt2.Y), math.Max(l2.pt1.Y, l2.pt2.Y) + if minx1 <= x && x <= maxx1 && miny1 <= y && y <= maxy1 { + if minx2 <= x && x <= maxx2 && miny2 <= y && y <= maxy2 { + return Point{x, y}, nil + } + } + } + return Point{}, fmt.Errorf("lines do not intersect") +} + +func lineOnLine(l1, l2 line) bool { + if onLine(l1.pt1, l1.pt2, l2.pt1) && onLine(l1.pt1, l1.pt2, l2.pt2) { + return true + } + return false +} diff --git a/line_test.go b/line_test.go new file mode 100644 index 0000000..4f398fa --- /dev/null +++ b/line_test.go @@ -0,0 +1,49 @@ +package rect + +import "testing" + +func TestOnLine(t *testing.T) { + var onLineTest = []struct { + p []Point + expected bool + }{ + {[]Point{Point{1, 1}, Point{3, 3}, Point{2, 2}}, true}, + {[]Point{Point{1, 1}, Point{3, 3}, Point{4, 4}}, false}, + {[]Point{Point{-1, -1}, Point{-3, -3}, Point{-4, -4}}, false}, + {[]Point{Point{-1, -1}, Point{-3, -3}, Point{-2, -2}}, true}, + } + for _, rt := range onLineTest { + actual := onLine(rt.p[0], rt.p[1], rt.p[2]) + if actual != rt.expected { + t.Errorf( + "failed onLine:\n\texpected: %t\n\t actual: %t", + rt.expected, + actual, + ) + } + + } +} + +func TestLineIntersection(t *testing.T) { + var lineIntersectionTest = []struct { + l []line + expected Point + }{ + {[]line{line{Point{0, 0}, Point{2, 2}}, line{Point{2, 0}, Point{0, 2}}}, Point{1, 1}}, + {[]line{line{Point{0, 0}, Point{-2, -2}}, line{Point{-2, 0}, Point{0, -2}}}, Point{-1, -1}}, + {[]line{line{Point{0, 0}, Point{-2, -2}}, line{Point{1, 0}, Point{1, -7}}}, Point{0, 0}}, + {[]line{line{Point{5, 8}, Point{8, 5}}, line{Point{3, 7}, Point{7, 3}}}, Point{0, 0}}, + } + for _, rt := range lineIntersectionTest { + actual, _ := lineIntersection(rt.l[0], rt.l[1]) + if actual != rt.expected { + t.Errorf( + "failed lineIntersection:\n\texpected: %v\n\t actual: %v", + rt.expected, + actual, + ) + } + + } +} diff --git a/point.go b/point.go index 02ec13f..032f180 100644 --- a/point.go +++ b/point.go @@ -1,18 +1,11 @@ package rect -import ( - "fmt" - "math" -) +import "math" type Point struct { X, Y float64 } -type line struct { - pt1, pt2 Point -} - func distance(p1, p2 Point) float64 { return math.Sqrt(math.Pow((p1.X-p2.X), 2) + math.Pow((p1.Y-p2.Y), 2)) } @@ -27,38 +20,3 @@ func onLine(rp1, rp2, p Point) bool { } return false } - -func lineHelper(l line) (float64, float64, float64) { - a := l.pt2.Y - l.pt1.Y - b := l.pt1.X - l.pt2.X - c := a*l.pt1.X + b*l.pt1.Y - return a, b, c -} - -func lineIntersection(l1, l2 line) (Point, error) { - a1, b1, c1 := lineHelper(l1) - a2, b2, c2 := lineHelper(l2) - det := a1*b2 - a2*b1 - - if det != 0 { - x := ((b2*c1 - b1*c2) / det) - y := ((a1*c2 - a2*c1) / det) - minx1, maxx1 := math.Min(l1.pt1.X, l1.pt2.X), math.Max(l1.pt1.X, l1.pt2.X) - miny1, maxy1 := math.Min(l1.pt1.Y, l1.pt2.Y), math.Max(l1.pt1.Y, l1.pt2.Y) - minx2, maxx2 := math.Min(l2.pt1.X, l2.pt2.X), math.Max(l2.pt1.X, l2.pt2.X) - miny2, maxy2 := math.Min(l2.pt1.Y, l2.pt2.Y), math.Max(l2.pt1.Y, l2.pt2.Y) - if minx1 <= x && x <= maxx1 && miny1 <= y && y <= maxy1 { - if minx2 <= x && x <= maxx2 && miny2 <= y && y <= maxy2 { - return Point{x, y}, nil - } - } - } - return Point{}, fmt.Errorf("lines do not intersect") -} - -func lineOnLine(l1, l2 line) bool { - if onLine(l1.pt1, l1.pt2, l2.pt1) && onLine(l1.pt1, l1.pt2, l2.pt2) { - return true - } - return false -} diff --git a/point_test.go b/point_test.go index 659e070..b31c0da 100644 --- a/point_test.go +++ b/point_test.go @@ -27,49 +27,3 @@ func TestDistance(t *testing.T) { } } - -func TestOnLine(t *testing.T) { - var onLineTest = []struct { - p []Point - expected bool - }{ - {[]Point{Point{1, 1}, Point{3, 3}, Point{2, 2}}, true}, - {[]Point{Point{1, 1}, Point{3, 3}, Point{4, 4}}, false}, - {[]Point{Point{-1, -1}, Point{-3, -3}, Point{-4, -4}}, false}, - {[]Point{Point{-1, -1}, Point{-3, -3}, Point{-2, -2}}, true}, - } - for _, rt := range onLineTest { - actual := onLine(rt.p[0], rt.p[1], rt.p[2]) - if actual != rt.expected { - t.Errorf( - "failed onLine:\n\texpected: %t\n\t actual: %t", - rt.expected, - actual, - ) - } - - } -} - -func TestLineIntersection(t *testing.T) { - var lineIntersectionTest = []struct { - l []line - expected Point - }{ - {[]line{line{Point{0, 0}, Point{2, 2}}, line{Point{2, 0}, Point{0, 2}}}, Point{1, 1}}, - {[]line{line{Point{0, 0}, Point{-2, -2}}, line{Point{-2, 0}, Point{0, -2}}}, Point{-1, -1}}, - {[]line{line{Point{0, 0}, Point{-2, -2}}, line{Point{1, 0}, Point{1, -7}}}, Point{0, 0}}, - {[]line{line{Point{5, 8}, Point{8, 5}}, line{Point{3, 7}, Point{7, 3}}}, Point{0, 0}}, - } - for _, rt := range lineIntersectionTest { - actual, _ := lineIntersection(rt.l[0], rt.l[1]) - if actual != rt.expected { - t.Errorf( - "failed lineIntersection:\n\texpected: %v\n\t actual: %v", - rt.expected, - actual, - ) - } - - } -} diff --git a/rectangle_test.go b/rectangle_test.go index 472501a..7ec6014 100644 --- a/rectangle_test.go +++ b/rectangle_test.go @@ -16,7 +16,7 @@ func TestIsRect(t *testing.T) { {Rectangle{P1: Point{0, 0}, P2: Point{0, 0}, P3: Point{0, 0}, P4: Point{0, 0}}, false}, } for _, rt := range isRectTests { - actual := rt.r.IsRect() + actual := rt.r.isRect() if actual != rt.expected { t.Errorf( "failed isRect:\n\texpected: %t\n\t actual: %t", @@ -41,7 +41,7 @@ func TestSize(t *testing.T) { {Rectangle{P1: Point{0, 0}, P2: Point{0, 100}, P3: Point{100, 0}, P4: Point{100, 100}}, 10000}, } for _, rt := range isRectTests { - actual := rt.r.Size() + actual := rt.r.size() if actual != rt.expected { t.Errorf( "failed size:\n\texpected: %f\n\t actual: %f",