diff --git a/point.go b/point.go index f765121..308ffb7 100644 --- a/point.go +++ b/point.go @@ -1,19 +1,118 @@ package geom import ( - _image "image" - "strconv" + "fmt" ) -// Point is exposing the standard library image.Point in the geom package. -type Point _image.Point +// ZeroPt represents the coordinate (0, 0) +var ZeroPt = Point{0, 0} + +// OnePt represents the coordinate (1, 1) +var OnePt = Point{1, 1} + +// North represents the coordinate next to the ZeroPt (Y == -1) +var North = Point{0, -1} + +// East represents the coordinate next to the ZeroPt (X == 1) +var East = Point{1, 0} + +// South represents the coordinate next to the ZeroPt (Y == 1) +var South = Point{0, 1} + +// West represents the coordinate next to the ZeroPt (X == -1) +var West = Point{-1, 0} + +// Point represents a 2-dimensional point. +type Point struct { + X, Y int +} // Pt is a shorthand function to create a point. func Pt(x, y int) Point { return Point{x, y} } -// String formats the point p as a string. -func (p Point) String() string { - return "(" + strconv.Itoa(p.X) + "," + strconv.Itoa(p.Y) + ")" +// NewPt is a short function to create a point and return a pointer to it. +func NewPt(x, y int) *Point { + return &Point{x, y} +} + +// Abs returns a point the absolute values of X and Y. +func (p Point) Abs() Point { + return Pt(AbsInt(p.X), AbsInt(p.Y)) +} + +// Add returns the sum of p and q. +func (p Point) Add(q Point) Point { + return p.Add2D(q.X, q.Y) +} + +// Add2D adds x and y to X and Y of point p and returns the sum. +func (p Point) Add2D(x, y int) Point { + return Pt(p.X+x, p.Y+y) +} + +// Less returns true if q is above (Y is smaller) or left (X is smaller) than p. Otherwise returns false. +func (p Point) Less(q Point) bool { + if p.Y == q.Y { + return p.X < q.X + } + return p.Y < q.Y +} + +// DistInt returns the integer distance between the points p and q. +func (p Point) DistInt(q Point) int { + return SubAbsInt(p.X, q.X) + SubAbsInt(p.Y, q.Y) +} + +// Mul multiplier the X and Y values of point p with t and returns the result. +func (p Point) Mul(t int) Point { + return Pt(p.X*t, p.Y*t) +} + +// Norm returns the point with both X and Y normalized. +func (p Point) Norm() Point { + return Pt(NormInt(p.X), NormInt(p.Y)) +} + +// String returns a string representation of point p "X, Y". +func (p Point) String() string { + return fmt.Sprintf("%d, %d", p.X, p.Y) +} + +// StringBrackets formats the point p as a string "(X, Y)". +func (p Point) StringBrackets() string { + return fmt.Sprintf("(%d, %d)", p.X, p.Y) +} + +// StringCompact returns a compact string representation of point p "X,Y". +func (p Point) StringCompact() string { + return fmt.Sprintf("%d,%d", p.X, p.Y) +} + +// Sub returns the difference of p and q. +func (p Point) Sub(p2 Point) Point { + return Pt(p.X-p2.X, p.Y-p2.Y) +} + +// MinMaxPoints returns the extremes of all the given points. +func MinMaxPoints(p ...Point) (min Point, max Point) { + if 0 == len(p) { + return Point{}, Point{} + } + min, max = p[0], p[0] + for i := 1; i < len(p); i++ { + var pt = p[i] + if pt.X < min.X { + min.X = pt.X + } else if pt.X > max.X { + max.X = pt.X + } + if pt.Y < min.Y { + min.Y = pt.Y + } else if pt.Y > max.Y { + max.Y = pt.Y + } + } + return min, max }