package util import ( "fmt" "math" ) // Point represents a 2 dimensional Point type Point struct { X, Y float64 } // Abs returns a Point with the absolute value of X and Y. // Should not be confused with Magnitude due to its notation ||A||. func (p Point) Abs() Point { return Point{ math.Abs(p.X), math.Abs(p.Y), } } // Add returns a Point with the value of Point p plus Point q. func (p Point) Add(q Point) Point { return Point{ p.X + q.X, p.Y + q.Y, } } // Subtract returns a Point with the value of Point p minus Point q. func (p Point) Subtract(q Point) Point { return Point{ X: p.X - q.X, Y: p.Y - q.Y, } } // Multiply returns a Point with the value of Point p multiplied by f. func (p Point) Multiply(f float64) Point { return Point{X: p.X * f, Y: p.Y * f} } // Divide returns a Point with the value of Point p divided by f. func (p Point) Divide(f float64) Point { return Point{X: p.X / f, Y: p.Y / f} } // Round returns a Point with the rounded value of Point p. func (p Point) Round() Point { return Point{X: math.Round(p.X), Y: math.Round(p.Y)} } // Floor returns a Point with the floored value of Point p. func (p Point) Floor() Point { return Point{X: math.Floor(p.X), Y: math.Floor(p.Y)} } // Ceil returns a Point with the rounded up value of Point p. func (p Point) Ceil() Point { return Point{X: math.Ceil(p.X), Y: math.Ceil(p.Y)} } // Scale returns a Point with the values of Point p scaled up by the values of Point q. func (p Point) Scale(q Point) Point { return Point{ X: p.X * q.X, Y: p.Y * q.Y, } } // ScaleDown returns a Point with the values of Point p scaled down by the values of Point q. func (p Point) ScaleDown(q Point) Point { return Point{ X: p.X / q.X, Y: p.Y / q.Y, } } // Min returns a Point with the smallest values of X and Y for Point p and q. func (p Point) Min(q Point) Point { return Point{ X: math.Min(p.X, q.X), Y: math.Min(p.Y, q.Y), } } // Max returns a Point with the largest values of X and Y for Point p and q. func (p Point) Max(q Point) Point { return Point{ X: math.Max(p.X, q.X), Y: math.Max(p.Y, q.Y), } } // String returns a string with comma separated values of Point p. func (p Point) String() string { return fmt.Sprintf("%v,%v", p.X, p.Y) } // Magnitude returns a float64 with the length/magnitude of Point p. func (p Point) Magnitude() float64 { return math.Sqrt(math.Pow(p.X, 2) + math.Pow(p.Y, 2)) } func (p Point) Unit() Point { return p.Divide(p.Magnitude()) } func (p Point) Rotate(a float64) Point { return Point{ X: math.Cos(a)*p.X - math.Sin(a)*p.Y, Y: math.Sin(a)*p.X + math.Cos(a)*p.Y, } } func (p Point) Distance(q Point) float64 { return p.Subtract(q).Magnitude() } func (p Point) Above(l float64) Point { return p.Subtract(Point{Y: l}) } func (p Point) Below(l float64) Point { return p.Add(Point{Y: l}) } func (p Point) Right(l float64) Point { return p.Add(Point{X: l}) } func (p Point) Left(l float64) Point { return p.Subtract(Point{X: l}) }