Sander Schobers
26bac636bc
- Includes PointF, RectangleF and PolygonF. Additional it includes the 32 bit floating point PointF32 and wrappers to image.Point and image.Rectangle.
82 lines
1.7 KiB
Go
82 lines
1.7 KiB
Go
package geom
|
|
|
|
import (
|
|
"math"
|
|
"strconv"
|
|
)
|
|
|
|
// PointF is an X, Y coordinate pair (floating point).
|
|
type PointF struct {
|
|
X, Y float64
|
|
}
|
|
|
|
// PtF is a shorthand function to create a point.
|
|
func PtF(x, y float64) PointF {
|
|
return PointF{X: x, Y: y}
|
|
}
|
|
|
|
// String formats the point p as a string.
|
|
func (p Point) String() string {
|
|
return "(" + strconv.Itoa(p.X) + "," + strconv.Itoa(p.Y) + ")"
|
|
}
|
|
|
|
// To32 transforms the point p into a PointF32.
|
|
func (p PointF) To32() PointF32 {
|
|
return PointF32{float32(p.X), float32(p.Y)}
|
|
}
|
|
|
|
// Add adds q as a vector to p
|
|
func (p PointF) Add(q PointF) PointF {
|
|
return PointF{p.X + q.X, p.Y + q.Y}
|
|
}
|
|
|
|
// AngleTo calculates the angle [0..2*Pi) from point p to point q.
|
|
func (p PointF) AngleTo(q PointF) float64 {
|
|
a := math.Atan((p.Y - q.Y) / (p.X - q.X))
|
|
if q.X < p.X {
|
|
return a + math.Pi
|
|
}
|
|
if a < 0 {
|
|
a += 2 * math.Pi
|
|
}
|
|
return a
|
|
}
|
|
|
|
// Distance calculates the distance between points p and q.
|
|
func (p PointF) Distance(q PointF) float64 {
|
|
return math.Sqrt(p.Distance2(q))
|
|
}
|
|
|
|
// Distance2 calculates the squared distance between points p and q.
|
|
func (p PointF) Distance2(q PointF) float64 {
|
|
dx := q.X - p.X
|
|
dy := q.Y - p.Y
|
|
return dx*dx + dy*dy
|
|
}
|
|
|
|
// In tests if the point p is inside the rectangle r.
|
|
func (p PointF) In(r RectangleF) bool {
|
|
if p.X < r.Min.X || p.X >= r.Max.X || p.Y < r.Min.Y || p.Y >= r.Max.Y {
|
|
return false
|
|
}
|
|
return true
|
|
}
|
|
|
|
// InPolygon tests is the point p is inside the polygon q.
|
|
func (p PointF) InPolygon(q PolygonF) bool {
|
|
var n = len(q.Points)
|
|
var c = false
|
|
|
|
var i = 0
|
|
var j = n - 1
|
|
for i < n {
|
|
if ((q.Points[i].Y >= p.Y) != (q.Points[j].Y >= p.Y)) &&
|
|
(p.X <= (q.Points[j].X-q.Points[i].X)*(p.Y-q.Points[i].Y)/(q.Points[j].Y-q.Points[i].Y)+q.Points[i].X) {
|
|
c = !c
|
|
}
|
|
j = i
|
|
i++
|
|
}
|
|
return c
|
|
}
|