vector/vectorpoint.go

102 lines
2.0 KiB
Go
Raw Normal View History

2013-08-08 20:34:27 -07:00
package govector
import (
2013-08-08 20:36:15 -07:00
"math"
2013-08-08 20:34:27 -07:00
)
2013-08-08 21:54:52 -07:00
type Rect2d struct {
X1 float64 `json:"x1"`
Y1 float64 `json:"y1"`
X2 float64 `json:"x2"`
Y2 float64 `json:"y2"`
}
2013-08-08 20:36:15 -07:00
type Vector2d struct {
2013-08-08 20:34:27 -07:00
X float64 `json:"x"`
Y float64 `json:"y"`
}
2013-08-08 20:36:15 -07:00
type Point2d struct {
2013-08-08 20:34:27 -07:00
X float64 `json:"x"`
Y float64 `json:"y"`
}
const epsilon = 1e-7
const Rad2deg = 180 / math.Pi
const Deg2rad = math.Pi / 180
2013-08-08 20:34:27 -07:00
2013-08-08 22:13:04 -07:00
func (p1 Point2d) Sub(p2 Point2d) Vector2d {
2013-08-08 21:54:52 -07:00
return Vector2d{p1.X - p2.X, p1.Y - p2.Y}
}
2013-08-08 22:13:04 -07:00
func (p Point2d) Add(v Vector2d) Point2d {
2013-08-08 21:54:52 -07:00
return Point2d{p.X + v.X, p.Y + v.Y}
2013-08-08 20:34:27 -07:00
}
2013-08-08 22:13:04 -07:00
func (v Vector2d) Mag() float64 {
2013-08-08 20:34:27 -07:00
return math.Abs(math.Sqrt(v.X*v.X + v.Y*v.Y))
}
2013-08-08 21:54:52 -07:00
2013-08-08 22:13:04 -07:00
func (v Vector2d) PopPop() float64 {
return v.Mag()
}
func (v Vector2d) Scale(s float64) Vector2d {
2013-08-08 21:54:52 -07:00
return Vector2d{v.X * s, v.Y * s}
}
2013-08-08 23:08:22 -07:00
func (v1 Vector2d) Cross(v2 Vector2d) float64 {
return v1.X*v2.Y - v1.Y*v2.X
}
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)
if t >= 0 && t <= 1 && s >= 0 && s <= 1 {
return true, p1.Add(v1.Scale(t))
}
return false, Point2d{0, 0}
}
2013-08-08 23:08:22 -07:00
func (v Vector2d) Normalize() Vector2d {
2013-08-08 23:14:18 -07:00
if v.X == 0 && v.Y == 0 {
return v
}
2013-08-08 23:08:22 -07:00
m := v.Mag()
return Vector2d{v.X / m, v.Y / m}
}
2013-09-03 23:32:57 -07:00
func Move(d1, d2 Point2d, velocity float64, timeDelta float64) Point2d {
v := d2.Sub(d1)
v_norm := v.Normalize()
v_scaled := v_norm.Scale(velocity * timeDelta)
return d1.Add(v_scaled)
}
func Distance(p1, p2 Point2d) float64 {
return p1.Sub(p2).Mag()
}
2013-09-21 18:34:53 -07:00
func Angle(v1, v2 Vector2d) float64 {
x := (v1.Dot(v2) / (v1.Mag() * v2.Mag()))
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
2013-09-21 18:34:53 -07:00
}