]> git.ipfire.org Git - thirdparty/gcc.git/blob - libgo/go/image/geom.go
Add Go frontend, libgo library, and Go testsuite.
[thirdparty/gcc.git] / libgo / go / image / geom.go
1 // Copyright 2010 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 package image
6
7 import (
8 "strconv"
9 )
10
11 // A Point is an X, Y coordinate pair. The axes increase right and down.
12 type Point struct {
13 X, Y int
14 }
15
16 // String returns a string representation of p like "(3,4)".
17 func (p Point) String() string {
18 return "(" + strconv.Itoa(p.X) + "," + strconv.Itoa(p.Y) + ")"
19 }
20
21 // Add returns the vector p+q.
22 func (p Point) Add(q Point) Point {
23 return Point{p.X + q.X, p.Y + q.Y}
24 }
25
26 // Sub returns the vector p-q.
27 func (p Point) Sub(q Point) Point {
28 return Point{p.X - q.X, p.Y - q.Y}
29 }
30
31 // Mul returns the vector p*k.
32 func (p Point) Mul(k int) Point {
33 return Point{p.X * k, p.Y * k}
34 }
35
36 // Div returns the vector p/k.
37 func (p Point) Div(k int) Point {
38 return Point{p.X / k, p.Y / k}
39 }
40
41 // Mod returns the point q in r such that p.X-q.X is a multiple of r's width
42 // and p.Y-q.Y is a multiple of r's height.
43 func (p Point) Mod(r Rectangle) Point {
44 w, h := r.Dx(), r.Dy()
45 p = p.Sub(r.Min)
46 p.X = p.X % w
47 if p.X < 0 {
48 p.X += w
49 }
50 p.Y = p.Y % h
51 if p.Y < 0 {
52 p.Y += h
53 }
54 return p.Add(r.Min)
55 }
56
57 // Eq returns whether p and q are equal.
58 func (p Point) Eq(q Point) bool {
59 return p.X == q.X && p.Y == q.Y
60 }
61
62 // ZP is the zero Point.
63 var ZP Point
64
65 // Pt is shorthand for Point{X, Y}.
66 func Pt(X, Y int) Point {
67 return Point{X, Y}
68 }
69
70 // A Rectangle contains the points with Min.X <= X < Max.X, Min.Y <= Y < Max.Y.
71 // It is well-formed if Min.X <= Max.X and likewise for Y. Points are always
72 // well-formed. A rectangle's methods always return well-formed outputs for
73 // well-formed inputs.
74 type Rectangle struct {
75 Min, Max Point
76 }
77
78 // String returns a string representation of r like "(3,4)-(6,5)".
79 func (r Rectangle) String() string {
80 return r.Min.String() + "-" + r.Max.String()
81 }
82
83 // Dx returns r's width.
84 func (r Rectangle) Dx() int {
85 return r.Max.X - r.Min.X
86 }
87
88 // Dy returns r's height.
89 func (r Rectangle) Dy() int {
90 return r.Max.Y - r.Min.Y
91 }
92
93 // Size returns r's width and height.
94 func (r Rectangle) Size() Point {
95 return Point{
96 r.Max.X - r.Min.X,
97 r.Max.Y - r.Min.Y,
98 }
99 }
100
101 // Add returns the rectangle r translated by p.
102 func (r Rectangle) Add(p Point) Rectangle {
103 return Rectangle{
104 Point{r.Min.X + p.X, r.Min.Y + p.Y},
105 Point{r.Max.X + p.X, r.Max.Y + p.Y},
106 }
107 }
108
109 // Add returns the rectangle r translated by -p.
110 func (r Rectangle) Sub(p Point) Rectangle {
111 return Rectangle{
112 Point{r.Min.X - p.X, r.Min.Y - p.Y},
113 Point{r.Max.X - p.X, r.Max.Y - p.Y},
114 }
115 }
116
117 // Inset returns the rectangle r inset by n, which may be negative. If either
118 // of r's dimensions is less than 2*n then an empty rectangle near the center
119 // of r will be returned.
120 func (r Rectangle) Inset(n int) Rectangle {
121 if r.Dx() < 2*n {
122 r.Min.X = (r.Min.X + r.Max.X) / 2
123 r.Max.X = r.Min.X
124 } else {
125 r.Min.X += n
126 r.Max.X -= n
127 }
128 if r.Dy() < 2*n {
129 r.Min.Y = (r.Min.Y + r.Max.Y) / 2
130 r.Max.Y = r.Min.Y
131 } else {
132 r.Min.Y += n
133 r.Max.Y -= n
134 }
135 return r
136 }
137
138 // Intersect returns the largest rectangle contained by both r and s. If the
139 // two rectangles do not overlap then the zero rectangle will be returned.
140 func (r Rectangle) Intersect(s Rectangle) Rectangle {
141 if r.Min.X < s.Min.X {
142 r.Min.X = s.Min.X
143 }
144 if r.Min.Y < s.Min.Y {
145 r.Min.Y = s.Min.Y
146 }
147 if r.Max.X > s.Max.X {
148 r.Max.X = s.Max.X
149 }
150 if r.Max.Y > s.Max.Y {
151 r.Max.Y = s.Max.Y
152 }
153 if r.Min.X > r.Max.X || r.Min.Y > r.Max.Y {
154 return ZR
155 }
156 return r
157 }
158
159 // Union returns the smallest rectangle that contains both r and s.
160 func (r Rectangle) Union(s Rectangle) Rectangle {
161 if r.Min.X > s.Min.X {
162 r.Min.X = s.Min.X
163 }
164 if r.Min.Y > s.Min.Y {
165 r.Min.Y = s.Min.Y
166 }
167 if r.Max.X < s.Max.X {
168 r.Max.X = s.Max.X
169 }
170 if r.Max.Y < s.Max.Y {
171 r.Max.Y = s.Max.Y
172 }
173 return r
174 }
175
176 // Empty returns whether the rectangle contains no points.
177 func (r Rectangle) Empty() bool {
178 return r.Min.X >= r.Max.X || r.Min.Y >= r.Max.Y
179 }
180
181 // Eq returns whether r and s are equal.
182 func (r Rectangle) Eq(s Rectangle) bool {
183 return r.Min.X == s.Min.X && r.Min.Y == s.Min.Y &&
184 r.Max.X == s.Max.X && r.Max.Y == s.Max.Y
185 }
186
187 // Overlaps returns whether r and s have a non-empty intersection.
188 func (r Rectangle) Overlaps(s Rectangle) bool {
189 return r.Min.X < s.Max.X && s.Min.X < r.Max.X &&
190 r.Min.Y < s.Max.Y && s.Min.Y < r.Max.Y
191 }
192
193 // Contains returns whether r contains p.
194 func (r Rectangle) Contains(p Point) bool {
195 return p.X >= r.Min.X && p.X < r.Max.X &&
196 p.Y >= r.Min.Y && p.Y < r.Max.Y
197 }
198
199 // Canon returns the canonical version of r. The returned rectangle has minimum
200 // and maximum coordinates swapped if necessary so that it is well-formed.
201 func (r Rectangle) Canon() Rectangle {
202 if r.Max.X < r.Min.X {
203 r.Min.X, r.Max.X = r.Max.X, r.Min.X
204 }
205 if r.Max.Y < r.Min.Y {
206 r.Min.Y, r.Max.Y = r.Max.Y, r.Min.Y
207 }
208 return r
209 }
210
211 // ZR is the zero Rectangle.
212 var ZR Rectangle
213
214 // Rect is shorthand for Rectangle{Pt(x0, y0), Pt(x1, y1)}.
215 func Rect(x0, y0, x1, y1 int) Rectangle {
216 if x0 > x1 {
217 x0, x1 = x1, x0
218 }
219 if y0 > y1 {
220 y0, y1 = y1, y0
221 }
222 return Rectangle{Point{x0, y0}, Point{x1, y1}}
223 }