2017-11-01 05:51:41 +00:00
|
|
|
package geom
|
|
|
|
|
|
|
|
// RectangleF is defined by two points, the minimum and maximum (floating point).
|
2017-11-06 19:24:19 +00:00
|
|
|
// Tries to use the same interface as the image.Rectangle but uses float64 instead of int.
|
2017-11-01 05:51:41 +00:00
|
|
|
type RectangleF struct {
|
|
|
|
Min, Max PointF
|
|
|
|
}
|
|
|
|
|
|
|
|
// RectF is a shorthand function to create a rectangle.
|
|
|
|
func RectF(x0, y0, x1, y1 float64) RectangleF {
|
|
|
|
if x0 > x1 {
|
|
|
|
x0, x1 = x1, x0
|
|
|
|
}
|
|
|
|
if y0 > y1 {
|
|
|
|
y0, y1 = y1, y0
|
|
|
|
}
|
|
|
|
return RectangleF{PtF(x0, y0), PtF(x1, y1)}
|
|
|
|
}
|
|
|
|
|
2020-05-15 08:24:09 +00:00
|
|
|
// RectRelF is a shorthand function to create a rectangle specifying its width and height instead of a second coordinate.
|
|
|
|
func RectRelF(x, y, w, h float64) RectangleF {
|
|
|
|
return RectangleF{PointF{x, y}, PointF{x + w, y + h}}
|
|
|
|
}
|
|
|
|
|
2017-11-06 19:24:19 +00:00
|
|
|
// Add translates rectangle r by point p.
|
|
|
|
func (r RectangleF) Add(p PointF) RectangleF {
|
|
|
|
return RectangleF{
|
|
|
|
PointF{r.Min.X + p.X, r.Min.Y + p.Y},
|
|
|
|
PointF{r.Max.X + p.X, r.Max.Y + p.Y},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-06 18:06:08 +00:00
|
|
|
// Center returns the center of the rectangle.
|
|
|
|
func (r RectangleF) Center() PointF {
|
2019-03-06 18:24:03 +00:00
|
|
|
return PointF{.5 * (r.Min.X + r.Max.X), .5 * (r.Min.Y + r.Max.Y)}
|
2019-03-06 18:06:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Dx returns the width of r.
|
|
|
|
func (r RectangleF) Dx() float64 {
|
|
|
|
return r.Max.X - r.Min.X
|
|
|
|
}
|
|
|
|
|
|
|
|
// Dy returns the height of r.
|
|
|
|
func (r RectangleF) Dy() float64 {
|
|
|
|
return r.Max.Y - r.Min.Y
|
|
|
|
}
|
|
|
|
|
2017-11-06 19:24:19 +00:00
|
|
|
// Inset returns the rectangle r inset by n. The resulting rectangle will never have
|
|
|
|
// a negative size.
|
|
|
|
func (r RectangleF) Inset(n float64) RectangleF {
|
|
|
|
if r.Dx() < 2*n {
|
|
|
|
r.Min.X = (r.Min.X + r.Max.X) / 2
|
|
|
|
r.Max.X = r.Min.X
|
|
|
|
} else {
|
|
|
|
r.Min.X += n
|
|
|
|
r.Max.X -= n
|
|
|
|
}
|
|
|
|
if r.Dy() < 2*n {
|
|
|
|
r.Min.Y = (r.Min.Y + r.Max.Y) / 2
|
|
|
|
r.Max.Y = r.Min.Y
|
|
|
|
} else {
|
|
|
|
r.Min.Y += n
|
|
|
|
r.Max.Y -= n
|
|
|
|
}
|
|
|
|
return r
|
|
|
|
}
|
|
|
|
|
2017-11-01 05:51:41 +00:00
|
|
|
// Size returns the size of the rectangle.
|
|
|
|
func (r RectangleF) Size() PointF {
|
2017-11-01 10:24:33 +00:00
|
|
|
return PointF{r.Max.X - r.Min.X, r.Max.Y - r.Min.Y}
|
2017-11-01 05:51:41 +00:00
|
|
|
}
|
2019-03-06 18:24:03 +00:00
|
|
|
|
|
|
|
// Sub translates rectangle r in the opposite direction of point p.
|
|
|
|
func (r RectangleF) Sub(p PointF) RectangleF {
|
|
|
|
return RectangleF{
|
|
|
|
PointF{r.Min.X - p.X, r.Min.Y - p.Y},
|
|
|
|
PointF{r.Max.X - p.X, r.Max.Y - p.Y},
|
|
|
|
}
|
|
|
|
}
|
2020-05-17 08:38:01 +00:00
|
|
|
|
|
|
|
// ToF32 returns the floating point representation of r.
|
|
|
|
func (r RectangleF) ToF32() RectangleF32 { return RectangleF32{Min: r.Min.ToF32(), Max: r.Max.ToF32()} }
|
|
|
|
|
|
|
|
// ToInt returns the integer point representation of r.
|
|
|
|
func (r RectangleF) ToInt() Rectangle { return Rectangle{Min: r.Min.ToInt(), Max: r.Max.ToInt()} }
|
2021-02-15 18:39:39 +00:00
|
|
|
|
|
|
|
// Union gives back the union of the two rectangles.
|
|
|
|
func (r RectangleF) Union(s RectangleF) RectangleF {
|
|
|
|
return RectF(Min(r.Min.X, s.Min.X), Min(r.Min.Y, s.Min.Y), Max(r.Max.X, s.Max.X), Max(r.Max.Y, s.Max.Y))
|
|
|
|
}
|