created line.go and moved tests and funcs
This commit is contained in:
parent
ace4f45155
commit
3850bdc592
45
line.go
Normal file
45
line.go
Normal file
@ -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
|
||||||
|
}
|
49
line_test.go
Normal file
49
line_test.go
Normal file
@ -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,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
44
point.go
44
point.go
@ -1,18 +1,11 @@
|
|||||||
package rect
|
package rect
|
||||||
|
|
||||||
import (
|
import "math"
|
||||||
"fmt"
|
|
||||||
"math"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Point struct {
|
type Point struct {
|
||||||
X, Y float64
|
X, Y float64
|
||||||
}
|
}
|
||||||
|
|
||||||
type line struct {
|
|
||||||
pt1, pt2 Point
|
|
||||||
}
|
|
||||||
|
|
||||||
func distance(p1, p2 Point) float64 {
|
func distance(p1, p2 Point) float64 {
|
||||||
return math.Sqrt(math.Pow((p1.X-p2.X), 2) + math.Pow((p1.Y-p2.Y), 2))
|
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
|
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
|
|
||||||
}
|
|
||||||
|
@ -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,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -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},
|
{Rectangle{P1: Point{0, 0}, P2: Point{0, 0}, P3: Point{0, 0}, P4: Point{0, 0}}, false},
|
||||||
}
|
}
|
||||||
for _, rt := range isRectTests {
|
for _, rt := range isRectTests {
|
||||||
actual := rt.r.IsRect()
|
actual := rt.r.isRect()
|
||||||
if actual != rt.expected {
|
if actual != rt.expected {
|
||||||
t.Errorf(
|
t.Errorf(
|
||||||
"failed isRect:\n\texpected: %t\n\t actual: %t",
|
"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},
|
{Rectangle{P1: Point{0, 0}, P2: Point{0, 100}, P3: Point{100, 0}, P4: Point{100, 100}}, 10000},
|
||||||
}
|
}
|
||||||
for _, rt := range isRectTests {
|
for _, rt := range isRectTests {
|
||||||
actual := rt.r.Size()
|
actual := rt.r.size()
|
||||||
if actual != rt.expected {
|
if actual != rt.expected {
|
||||||
t.Errorf(
|
t.Errorf(
|
||||||
"failed size:\n\texpected: %f\n\t actual: %f",
|
"failed size:\n\texpected: %f\n\t actual: %f",
|
||||||
|
Loading…
Reference in New Issue
Block a user