diff --git a/govector_test.go b/govector_test.go index ddd2f26..e0a458d 100644 --- a/govector_test.go +++ b/govector_test.go @@ -138,8 +138,8 @@ func TestAngle(t *testing.T) { a := Angle(v2, v1) - fmt.Printf("%v %v %f\n", v1, v2, a*rad2deg) - if math.Abs(a-math.Pi/2) > epsilon { + fmt.Printf("%v %v %f\n", v1, v2, a*Rad2deg) + if math.Abs(a)-math.Pi/2 > epsilon { t.Errorf("Angle Error") } @@ -148,10 +148,28 @@ func TestAngle(t *testing.T) { a = Angle(v1, v2) - fmt.Printf("%v %v %f\n", v1, v2, a*rad2deg) + fmt.Printf("%v %v %f\n", v1, v2, a*Rad2deg) - if math.Abs(a-math.Pi/4) > epsilon { + if math.Abs(a)-math.Pi/4 > epsilon { t.Errorf("Angle Error") } } + +func TestRotate(t *testing.T) { + v1 := Vector2d{10, 0} + v2 := v1.Rotate(math.Pi / 2) + + fmt.Printf("%v %v\n", v1, v2) + if v2.X > epsilon || v2.Y-10 > epsilon { + t.Errorf("Rotate Error") + } + + v1 = Vector2d{1, 0} + v2 = v1.Rotate(-30 * Deg2rad) + + fmt.Printf("%v %v\n", v1, v2) + if v2.X-0.866025403784438 > epsilon || v2.Y+0.5 > epsilon { + t.Errorf("Rotate Error") + } +} diff --git a/vectorpoint.go b/vectorpoint.go index 4f2222e..e5e204f 100644 --- a/vectorpoint.go +++ b/vectorpoint.go @@ -22,7 +22,8 @@ type Point2d struct { } const epsilon = 1e-7 -const rad2deg = 180 / math.Pi +const Rad2deg = 180 / math.Pi +const Deg2rad = math.Pi / 180 func (p1 Point2d) Sub(p2 Point2d) Vector2d { return Vector2d{p1.X - p2.X, p1.Y - p2.Y} @@ -52,6 +53,12 @@ func (v1 Vector2d) Dot(v2 Vector2d) float64 { return (v1.X * v2.X) + (v1.Y * v2.Y) } +func (v1 Vector2d) Rotate(a float64) Vector2d { + x := v1.X*math.Cos(a) - v1.Y*math.Sin(a) + y := v1.X*math.Sin(a) + v1.Y*math.Cos(a) + return Vector2d{x, y} +} + func Intersection(p1, p2 Point2d, v1, v2 Vector2d) (bool, Point2d) { t := p2.Sub(p1).Cross(v2) / v1.Cross(v2) s := p2.Sub(p1).Cross(v1) / v1.Cross(v2) @@ -84,5 +91,11 @@ func Distance(p1, p2 Point2d) float64 { func Angle(v1, v2 Vector2d) float64 { x := (v1.Dot(v2) / (v1.Mag() * v2.Mag())) - return math.Acos(x) + angle := math.Acos(x) + // Determine the sign to see what direction + // the angle should go in + if v1.Y*v2.X > v1.X*v2.Y { + angle = angle * -1.0 + } + return angle }