1
2
3
4
5 package math.geom2d.grid;
6
7 import java.util.ArrayList;
8 import java.util.Collection;
9
10 import math.geom2d.Box2D;
11 import math.geom2d.Point2D;
12 import math.geom2d.point.PointArray2D;
13 import math.geom2d.point.PointSet2D;
14 import math.geom2d.line.LineSegment2D;
15 import math.geom2d.line.StraightLine2D;
16 import math.geom2d.line.LinearShape2D;
17
18
19
20
21
22
23
24 public class TriangleGrid2D implements Grid2D {
25
26 double x0 = 0;
27 double y0 = 0;
28 double s = 1;
29
30 double theta = 0;
31
32
33
34
35
36
37
38 private final static boolean isEven(int n) {
39 return Math.abs(n*.5-Math.floor(n*.5))<.25;
40 }
41
42 public TriangleGrid2D() {
43 this(0, 0, 1, 0);
44 }
45
46
47
48
49 public TriangleGrid2D(double s) {
50 this(0, 0, s, 0);
51 }
52
53
54
55
56
57 public TriangleGrid2D(double x0, double y0) {
58 this(x0, y0, 1, 0);
59 }
60
61
62
63
64
65
66 public TriangleGrid2D(double x0, double y0, double s) {
67 this(x0, y0, s, 0);
68 }
69
70
71
72
73
74
75
76 public TriangleGrid2D(double x0, double y0, double s, double theta) {
77 this.x0 = x0;
78 this.y0 = y0;
79 this.s = s;
80 this.theta = theta;
81 }
82
83
84
85
86
87
88 public TriangleGrid2D(Point2D point) {
89 this(point.getX(), point.getY(), 1, 0);
90 }
91
92
93
94
95
96 public TriangleGrid2D(Point2D point, double s) {
97 this(point.getX(), point.getY(), s, 0);
98 }
99
100
101
102
103
104
105 public TriangleGrid2D(Point2D point, double s, double theta) {
106 this(point.getX(), point.getY(), s, theta);
107 }
108
109
110
111
112 @Deprecated
113 public void setOrigin(Point2D point) {
114 this.x0 = point.getX();
115 this.y0 = point.getY();
116 }
117
118 public Point2D getOrigin() {
119 return new Point2D(x0, y0);
120 }
121
122 public double getSize() {
123 return s;
124 }
125
126
127
128
129 @Deprecated
130 public void setSize(double s) {
131 this.s = s;
132 }
133
134
135
136
137 @Deprecated
138 public void setAngle(double theta) {
139 this.theta = theta;
140 }
141
142 public double getTheta() {
143 return theta;
144 }
145
146
147
148
149
150
151 public Point2D getClosestVertex(java.awt.geom.Point2D point) {
152
153 double cot = Math.cos(theta);
154 double sit = Math.sin(theta);
155 StraightLine2D baseLine = new StraightLine2D(x0, y0, cot, sit);
156
157
158 double s2 = s*Math.sqrt(3)/2;
159 double d = baseLine.getSignedDistance(point);
160 int n1 = (int) Math.floor(d/s2);
161 int n2 = (int) Math.ceil(d/s2);
162
163
164 StraightLine2D line1 = baseLine.getParallel(n1*s2);
165 StraightLine2D line2 = baseLine.getParallel(n2*s2);
166
167
168 double t = line1.project(new Point2D(point));
169
170 Point2D p1, p2, p3;
171 if (isEven(n1)) {
172 p1 = line1.getPoint(Math.floor(t/s)*s);
173 p2 = line1.getPoint(Math.ceil(t/s)*s);
174 p3 = line2.getPoint((Math.floor(t/s)+.5)*s);
175 } else {
176 p1 = line1.getPoint((Math.floor(t/s)+.5)*s);
177 p2 = line2.getPoint(Math.floor(t/s)*s);
178 p3 = line2.getPoint(Math.ceil(t/s)*s);
179 }
180
181 Point2D res = p1;
182 double minDist = res.getDistance(point);
183
184 double d2 = p2.getDistance(point);
185 if (d2<minDist) {
186 res = p2;
187 minDist = d2;
188 }
189
190 double d3 = p3.getDistance(point);
191 if (d3<minDist) {
192 res = p3;
193 minDist = d3;
194 }
195 return res;
196 }
197
198
199
200
201
202
203 public Collection<LineSegment2D> getEdges(Box2D box) {
204
205
206 ArrayList<LineSegment2D> array = new ArrayList<LineSegment2D>();
207
208 double d = s*Math.sqrt(3)/2;
209 double dmin, dmax;
210
211 for (int k = 0; k<3; k++) {
212
213 double theta2 = this.theta+Math.PI*(k)/3.0;
214 double cot = Math.cos(theta2);
215 double sit = Math.sin(theta2);
216 StraightLine2D baseLine = new StraightLine2D(x0, y0, cot, sit);
217
218
219 dmin = Double.POSITIVE_INFINITY;
220 dmax = Double.NEGATIVE_INFINITY;
221 for (Point2D point : box.getVertices()) {
222 double dist = baseLine.getSignedDistance(point);
223 dmin = Math.min(dmin, dist);
224 dmax = Math.max(dmax, dist);
225 }
226
227
228 double s2 = s*Math.sqrt(3)/2;
229 int i0 = (int) Math.ceil(dmin/s2);
230 int i1 = (int) Math.floor(dmax/s2);
231
232
233 for (int i = i0; i<=i1; i++) {
234 StraightLine2D line = baseLine.getParallel(d*i);
235 for (LinearShape2D arc : line.clip(box)) {
236 if (arc instanceof LineSegment2D)
237 array.add((LineSegment2D) arc);
238 }
239 }
240 }
241 return array;
242 }
243
244
245
246
247
248
249 public PointSet2D getVertices(Box2D box) {
250
251
252 ArrayList<Point2D> array = new ArrayList<Point2D>();
253
254 double d = s*Math.sqrt(3)/2;
255 double dmin, dmax;
256
257
258 double cot = Math.cos(theta);
259 double sit = Math.sin(theta);
260 StraightLine2D baseLine = new StraightLine2D(x0, y0, cot, sit);
261
262
263 dmin = Double.POSITIVE_INFINITY;
264 dmax = Double.NEGATIVE_INFINITY;
265 for (Point2D point : box.getVertices()) {
266 double dist = baseLine.getSignedDistance(point);
267 dmin = Math.min(dmin, dist);
268 dmax = Math.max(dmax, dist);
269 }
270
271
272 int i0 = (int) Math.ceil(dmin/s);
273 int i1 = (int) Math.floor(dmax/s);
274
275
276 for (int i = i0; i<=i1; i++) {
277
278
279 StraightLine2D line = baseLine.getParallel(d*i);
280
281
282 LineSegment2D seg = (LineSegment2D) line.clip(box).getFirstCurve();
283
284
285
286 double t1 = line.getPosition(seg.getFirstPoint());
287 double t2 = line.getPosition(seg.getLastPoint());
288
289
290 double t0 = isEven(i) ? 0 : s*.5;
291
292
293 int j0 = (int) Math.ceil((t1-t0)/s);
294 int j1 = (int) Math.floor((t2-t0)/s);
295
296
297 if (j1<j0)
298 continue;
299 for (int j = j0; j<=j1; j++)
300 array.add(line.getPoint(j*s+t0));
301 }
302
303 return new PointArray2D(array);
304 }
305
306 }