...
Source file
src/image/geom.go
Documentation: image
1
2
3
4
5 package image
6
7 import (
8 "image/color"
9 "strconv"
10 )
11
12
13 type Point struct {
14 X, Y int
15 }
16
17
18 func (p Point) String() string {
19 return "(" + strconv.Itoa(p.X) + "," + strconv.Itoa(p.Y) + ")"
20 }
21
22
23 func (p Point) Add(q Point) Point {
24 return Point{p.X + q.X, p.Y + q.Y}
25 }
26
27
28 func (p Point) Sub(q Point) Point {
29 return Point{p.X - q.X, p.Y - q.Y}
30 }
31
32
33 func (p Point) Mul(k int) Point {
34 return Point{p.X * k, p.Y * k}
35 }
36
37
38 func (p Point) Div(k int) Point {
39 return Point{p.X / k, p.Y / k}
40 }
41
42
43 func (p Point) In(r Rectangle) bool {
44 return r.Min.X <= p.X && p.X < r.Max.X &&
45 r.Min.Y <= p.Y && p.Y < r.Max.Y
46 }
47
48
49
50 func (p Point) Mod(r Rectangle) Point {
51 w, h := r.Dx(), r.Dy()
52 p = p.Sub(r.Min)
53 p.X = p.X % w
54 if p.X < 0 {
55 p.X += w
56 }
57 p.Y = p.Y % h
58 if p.Y < 0 {
59 p.Y += h
60 }
61 return p.Add(r.Min)
62 }
63
64
65 func (p Point) Eq(q Point) bool {
66 return p == q
67 }
68
69
70 var ZP Point
71
72
73 func Pt(X, Y int) Point {
74 return Point{X, Y}
75 }
76
77
78
79
80
81
82
83
84
85 type Rectangle struct {
86 Min, Max Point
87 }
88
89
90 func (r Rectangle) String() string {
91 return r.Min.String() + "-" + r.Max.String()
92 }
93
94
95 func (r Rectangle) Dx() int {
96 return r.Max.X - r.Min.X
97 }
98
99
100 func (r Rectangle) Dy() int {
101 return r.Max.Y - r.Min.Y
102 }
103
104
105 func (r Rectangle) Size() Point {
106 return Point{
107 r.Max.X - r.Min.X,
108 r.Max.Y - r.Min.Y,
109 }
110 }
111
112
113 func (r Rectangle) Add(p Point) Rectangle {
114 return Rectangle{
115 Point{r.Min.X + p.X, r.Min.Y + p.Y},
116 Point{r.Max.X + p.X, r.Max.Y + p.Y},
117 }
118 }
119
120
121 func (r Rectangle) Sub(p Point) Rectangle {
122 return Rectangle{
123 Point{r.Min.X - p.X, r.Min.Y - p.Y},
124 Point{r.Max.X - p.X, r.Max.Y - p.Y},
125 }
126 }
127
128
129
130
131 func (r Rectangle) Inset(n int) Rectangle {
132 if r.Dx() < 2*n {
133 r.Min.X = (r.Min.X + r.Max.X) / 2
134 r.Max.X = r.Min.X
135 } else {
136 r.Min.X += n
137 r.Max.X -= n
138 }
139 if r.Dy() < 2*n {
140 r.Min.Y = (r.Min.Y + r.Max.Y) / 2
141 r.Max.Y = r.Min.Y
142 } else {
143 r.Min.Y += n
144 r.Max.Y -= n
145 }
146 return r
147 }
148
149
150
151 func (r Rectangle) Intersect(s Rectangle) Rectangle {
152 if r.Min.X < s.Min.X {
153 r.Min.X = s.Min.X
154 }
155 if r.Min.Y < s.Min.Y {
156 r.Min.Y = s.Min.Y
157 }
158 if r.Max.X > s.Max.X {
159 r.Max.X = s.Max.X
160 }
161 if r.Max.Y > s.Max.Y {
162 r.Max.Y = s.Max.Y
163 }
164
165
166
167
168 if r.Empty() {
169 return ZR
170 }
171 return r
172 }
173
174
175 func (r Rectangle) Union(s Rectangle) Rectangle {
176 if r.Empty() {
177 return s
178 }
179 if s.Empty() {
180 return r
181 }
182 if r.Min.X > s.Min.X {
183 r.Min.X = s.Min.X
184 }
185 if r.Min.Y > s.Min.Y {
186 r.Min.Y = s.Min.Y
187 }
188 if r.Max.X < s.Max.X {
189 r.Max.X = s.Max.X
190 }
191 if r.Max.Y < s.Max.Y {
192 r.Max.Y = s.Max.Y
193 }
194 return r
195 }
196
197
198 func (r Rectangle) Empty() bool {
199 return r.Min.X >= r.Max.X || r.Min.Y >= r.Max.Y
200 }
201
202
203
204 func (r Rectangle) Eq(s Rectangle) bool {
205 return r == s || r.Empty() && s.Empty()
206 }
207
208
209 func (r Rectangle) Overlaps(s Rectangle) bool {
210 return !r.Empty() && !s.Empty() &&
211 r.Min.X < s.Max.X && s.Min.X < r.Max.X &&
212 r.Min.Y < s.Max.Y && s.Min.Y < r.Max.Y
213 }
214
215
216 func (r Rectangle) In(s Rectangle) bool {
217 if r.Empty() {
218 return true
219 }
220
221
222 return s.Min.X <= r.Min.X && r.Max.X <= s.Max.X &&
223 s.Min.Y <= r.Min.Y && r.Max.Y <= s.Max.Y
224 }
225
226
227
228 func (r Rectangle) Canon() Rectangle {
229 if r.Max.X < r.Min.X {
230 r.Min.X, r.Max.X = r.Max.X, r.Min.X
231 }
232 if r.Max.Y < r.Min.Y {
233 r.Min.Y, r.Max.Y = r.Max.Y, r.Min.Y
234 }
235 return r
236 }
237
238
239 func (r Rectangle) At(x, y int) color.Color {
240 if (Point{x, y}).In(r) {
241 return color.Opaque
242 }
243 return color.Transparent
244 }
245
246
247 func (r Rectangle) Bounds() Rectangle {
248 return r
249 }
250
251
252 func (r Rectangle) ColorModel() color.Model {
253 return color.Alpha16Model
254 }
255
256
257 var ZR Rectangle
258
259
260
261
262 func Rect(x0, y0, x1, y1 int) Rectangle {
263 if x0 > x1 {
264 x0, x1 = x1, x0
265 }
266 if y0 > y1 {
267 y0, y1 = y1, y0
268 }
269 return Rectangle{Point{x0, y0}, Point{x1, y1}}
270 }
271
View as plain text