summaryrefslogtreecommitdiff
path: root/src/pkg/image/geom.go
diff options
context:
space:
mode:
authorNigel Tao <nigeltao@golang.org>2010-09-09 19:12:54 +1000
committerNigel Tao <nigeltao@golang.org>2010-09-09 19:12:54 +1000
commit0be78f78e229cce61fdd9147b7783ef0531eb5bd (patch)
treef3ce6227c2f8d923a6f5f7405066e9897f359b3f /src/pkg/image/geom.go
parent16bcfafdd3d1952608ef42cf62804179f1a7991d (diff)
downloadgo-0be78f78e229cce61fdd9147b7783ef0531eb5bd.tar.gz
exp/draw: clip destination rectangle to the image bounds.
image: introduce Intersect and Union rectangle methods. R=r, rog, nigeltao CC=golang-dev http://codereview.appspot.com/2115043
Diffstat (limited to 'src/pkg/image/geom.go')
-rw-r--r--src/pkg/image/geom.go67
1 files changed, 60 insertions, 7 deletions
diff --git a/src/pkg/image/geom.go b/src/pkg/image/geom.go
index ad0f987cb..06c13fec1 100644
--- a/src/pkg/image/geom.go
+++ b/src/pkg/image/geom.go
@@ -37,6 +37,9 @@ func Pt(X, Y int) Point {
}
// A Rectangle contains the points with Min.X <= X < Max.X, Min.Y <= Y < Max.Y.
+// It is well-formed if Min.X <= Max.X and likewise for Y. Points are always
+// well-formed. A rectangle's methods always return well-formed outputs for
+// well-formed inputs.
type Rectangle struct {
Min, Max Point
}
@@ -72,12 +75,63 @@ func (r Rectangle) Sub(p Point) Rectangle {
}
}
-// Inset returns the rectangle r inset by n, which may be negative.
+// Inset returns the rectangle r inset by n, which may be negative. If either
+// of r's dimensions is less than 2*n then an empty rectangle near the center
+// of r will be returned.
func (r Rectangle) Inset(n int) Rectangle {
- return Rectangle{
- Point{r.Min.X + n, r.Min.Y + n},
- Point{r.Max.X - n, r.Max.Y - n},
+ 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
+}
+
+// Intersect returns the largest rectangle contained by both r and s. If the
+// two rectangles do not overlap then the zero rectangle will be returned.
+func (r Rectangle) Intersect(s Rectangle) Rectangle {
+ if r.Min.X < s.Min.X {
+ r.Min.X = s.Min.X
+ }
+ if r.Min.Y < s.Min.Y {
+ r.Min.Y = s.Min.Y
+ }
+ if r.Max.X > s.Max.X {
+ r.Max.X = s.Max.X
+ }
+ if r.Max.Y > s.Max.Y {
+ r.Max.Y = s.Max.Y
}
+ if r.Min.X > r.Max.X || r.Min.Y > r.Max.Y {
+ return ZR
+ }
+ return r
+}
+
+// Union returns the smallest rectangle that contains both r and s.
+func (r Rectangle) Union(s Rectangle) Rectangle {
+ if r.Min.X > s.Min.X {
+ r.Min.X = s.Min.X
+ }
+ if r.Min.Y > s.Min.Y {
+ r.Min.Y = s.Min.Y
+ }
+ if r.Max.X < s.Max.X {
+ r.Max.X = s.Max.X
+ }
+ if r.Max.Y < s.Max.Y {
+ r.Max.Y = s.Max.Y
+ }
+ return r
}
// Empty returns whether the rectangle contains no points.
@@ -103,9 +157,8 @@ func (r Rectangle) Contains(p Point) bool {
p.Y >= r.Min.Y && p.Y < r.Max.Y
}
-// Canon returns the canonical version of r. The returned rectangle has
-// minimum and maximum coordinates swapped if necessary so that Min.X <= Max.X
-// and Min.Y <= Max.Y.
+// Canon returns the canonical version of r. The returned rectangle has minimum
+// and maximum coordinates swapped if necessary so that it is well-formed.
func (r Rectangle) Canon() Rectangle {
if r.Max.X < r.Min.X {
r.Min.X, r.Max.X = r.Max.X, r.Min.X