1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 package math.geom2d.line;
28
29 import java.util.ArrayList;
30 import java.util.Collection;
31
32 import math.geom2d.AffineTransform2D;
33 import math.geom2d.Box2D;
34 import math.geom2d.Point2D;
35 import math.geom2d.Shape2D;
36 import math.geom2d.UnboundedShapeException;
37 import math.geom2d.domain.SmoothOrientedCurve2D;
38
39
40
41
42
43
44
45
46
47
48 public class LineArc2D extends AbstractLine2D
49 implements SmoothOrientedCurve2D, Cloneable {
50
51 protected double t0 = 0;
52 protected double t1 = 1;
53
54
55
56
57
58
59
60
61
62
63 public LineArc2D(Point2D point1, Point2D point2, double t0, double t1) {
64 this(point1.getX(), point1.getY(),
65 point2.getX()-point1.getX(), point2.getY()-point1.getY(),
66 t0, t1);
67 }
68
69
70
71
72
73
74
75
76
77 public LineArc2D(LinearShape2D line, double t0, double t1) {
78 super(line);
79 this.t0 = t0;
80 this.t1 = t1;
81 }
82
83
84
85
86
87
88 public LineArc2D(LineArc2D line) {
89 this(line.x0, line.y0, line.dx, line.dy, line.t0, line.t1);
90 }
91
92
93
94
95
96
97
98
99
100
101
102
103 public LineArc2D(double x1, double y1, double dx, double dy, double t0,
104 double t1) {
105 super(x1, y1, dx, dy);
106 this.t0 = t0;
107 this.t1 = t1;
108 }
109
110
111
112
113
114
115
116
117
118 public LineArc2D create(Point2D p1, Point2D p2, double t0, double t1) {
119 return new LineArc2D(p1, p2, t0, t1);
120 }
121
122
123
124
125
126
127
128
129 @Override
130 public double getLength() {
131 if (t0!=Double.NEGATIVE_INFINITY&&t1!=Double.POSITIVE_INFINITY)
132 return getPoint1().getDistance(getPoint2());
133 else
134 return Double.POSITIVE_INFINITY;
135 }
136
137
138
139
140
141
142
143 public Point2D getPoint1() {
144 if (t0!=Double.NEGATIVE_INFINITY)
145 return new Point2D(x0+t0*dx, y0+t0*dy);
146 else
147 throw new UnboundedShapeException(this);
148 }
149
150
151
152
153
154
155
156 public Point2D getPoint2() {
157 if (t1!=Double.POSITIVE_INFINITY)
158 return new Point2D(x0+t1*dx, y0+t1*dy);
159 else
160 throw new UnboundedShapeException(this);
161 }
162
163 public double getX1() {
164 if (t0!=Double.NEGATIVE_INFINITY)
165 return x0+t0*dx;
166 else
167 return Double.NEGATIVE_INFINITY;
168 }
169
170 public double getY1() {
171 if (t0!=Double.NEGATIVE_INFINITY)
172 return y0+t0*dy;
173 else
174 return Double.NEGATIVE_INFINITY;
175 }
176
177 public double getX2() {
178 if (t1!=Double.POSITIVE_INFINITY)
179 return x0+t1*dx;
180 else
181 return Double.POSITIVE_INFINITY;
182 }
183
184 public double getY2() {
185 if (t1!=Double.POSITIVE_INFINITY)
186 return y0+t1*dy;
187 else
188 return Double.POSITIVE_INFINITY;
189 }
190
191
192
193
194
195
196
197 public LineArc2D getParallel(double d) {
198 double dd = Math.hypot(dx, dy);
199 return new LineArc2D(x0+dy*d/dd, y0-dx*d/dd, dx, dy, t0, t1);
200 }
201
202
203
204
205
206
207
208
209
210 public double getT0() {
211 return t0;
212 }
213
214
215
216
217
218 public double getT1() {
219 return t1;
220 }
221
222 public Point2D getPoint(double t) {
223 if (t<t0)
224 t = t0;
225 if (t>t1)
226 t = t1;
227
228 if (Double.isInfinite(t))
229 throw new UnboundedShapeException(this);
230 else
231 return new Point2D(x0+dx*t, y0+dy*t);
232 }
233
234
235
236
237
238
239
240 @Override
241 public Point2D getFirstPoint() {
242 if (!Double.isInfinite(t0))
243 return new Point2D(x0+t0*dx, y0+t0*dy);
244 else
245 throw new UnboundedShapeException(this);
246 }
247
248
249
250
251
252
253
254 @Override
255 public Point2D getLastPoint() {
256 if (!Double.isInfinite(t1))
257 return new Point2D(x0+t1*dx, y0+t1*dy);
258 else
259 throw new UnboundedShapeException(this);
260 }
261
262 @Override
263 public Collection<Point2D> getSingularPoints() {
264 ArrayList<Point2D> list = new ArrayList<Point2D>(2);
265 if (t0!=Double.NEGATIVE_INFINITY)
266 list.add(this.getFirstPoint());
267 if (t1!=Double.POSITIVE_INFINITY)
268 list.add(this.getLastPoint());
269 return list;
270 }
271
272 @Override
273 public boolean isSingular(double pos) {
274 if (Math.abs(pos-t0)<Shape2D.ACCURACY)
275 return true;
276 if (Math.abs(pos-t1)<Shape2D.ACCURACY)
277 return true;
278 return false;
279 }
280
281 @Override
282 public Collection<? extends LineArc2D> getContinuousCurves() {
283 return wrapCurve(this);
284 }
285
286
287
288
289
290 public LineArc2D getReverseCurve() {
291 return new LineArc2D(x0, y0, -dx, -dy, -t1, -t0);
292 }
293
294
295
296
297
298 @Override
299 public LineArc2D getSubCurve(double t0, double t1) {
300 t0 = Math.max(t0, this.getT0());
301 t1 = Math.min(t1, this.getT1());
302 return new LineArc2D(this, t0, t1);
303 }
304
305
306
307
308
309 public boolean isBounded() {
310 if (t1==Double.POSITIVE_INFINITY)
311 return false;
312 if (t0==Double.NEGATIVE_INFINITY)
313 return false;
314 return true;
315 }
316
317 public Box2D getBoundingBox() {
318 return new Box2D(x0+t0*dx, x0+t1*dx, y0+t0*dy, y0+t1*dy);
319 }
320
321
322
323
324 @Override
325 public boolean contains(java.awt.geom.Point2D pt) {
326 return contains(pt.getX(), pt.getY());
327 }
328
329 public boolean contains(double xp, double yp) {
330 if (!super.supportContains(xp, yp))
331 return false;
332
333
334 double t = getPositionOnLine(xp, yp);
335
336 if (t-t0<-ACCURACY)
337 return false;
338 if (t-t1>ACCURACY)
339 return false;
340
341 return true;
342 }
343
344 public java.awt.geom.GeneralPath getGeneralPath() {
345 if (!this.isBounded())
346 throw new UnboundedShapeException(this);
347 java.awt.geom.GeneralPath path = new java.awt.geom.GeneralPath();
348 path.moveTo((float) (x0+t0*dx), (float) (y0+t0*dy));
349 path.lineTo((float) (x0+t1*dx), (float) (y0+t1*dy));
350 return path;
351 }
352
353
354
355
356
357
358
359
360 public java.awt.geom.GeneralPath appendPath(java.awt.geom.GeneralPath path) {
361 if (!this.isBounded())
362 throw new UnboundedShapeException(this);
363 if (t0==Double.NEGATIVE_INFINITY)
364 return path;
365 if (t1==Double.POSITIVE_INFINITY)
366 return path;
367 path.lineTo((float) getX1(), (float) getY1());
368 path.lineTo((float) getX2(), (float) getY2());
369 return path;
370 }
371
372 @Override
373 public LineArc2D transform(AffineTransform2D trans) {
374 double[] tab = trans.getCoefficients();
375 double x1 = x0*tab[0]+y0*tab[1]+tab[2];
376 double y1 = x0*tab[3]+y0*tab[4]+tab[5];
377 return new LineArc2D(x1, y1, dx*tab[0]+dy*tab[1], dx*tab[3]+dy*tab[4],
378 t0, t1);
379 }
380
381 @Override
382 public String toString() {
383 return new String("LineArc2D(" + x0 + "," + y0 + "," +
384 dx + "," + dy + "," + t0 + "," + t1 +")");
385 }
386
387
388
389
390 @Override
391 public boolean equals(Object obj) {
392 if (!(obj instanceof LineArc2D))
393 return false;
394 LineArc2D arc = (LineArc2D) obj;
395
396
397 if (!this.isColinear(arc))
398 return false;
399
400
401 if (t0==Double.NEGATIVE_INFINITY&&t1==Double.POSITIVE_INFINITY) {
402
403 if (arc.t0!=Double.NEGATIVE_INFINITY)
404 return false;
405 if (arc.t1!=Double.POSITIVE_INFINITY)
406 return false;
407 return true;
408 }
409
410
411 if (t0==Double.NEGATIVE_INFINITY) {
412
413 if (arc.t0==Double.NEGATIVE_INFINITY)
414 return this.getPoint2().getDistance(arc.getPoint2())<Shape2D.ACCURACY;
415 if (arc.t1==Double.POSITIVE_INFINITY)
416 return this.getPoint2().getDistance(arc.getPoint1())<Shape2D.ACCURACY;
417 return false;
418 }
419 if (t1==Double.POSITIVE_INFINITY) {
420
421 if (arc.t0==Double.NEGATIVE_INFINITY)
422 return this.getPoint1().getDistance(arc.getPoint2())<Shape2D.ACCURACY;
423 if (arc.t1==Double.POSITIVE_INFINITY)
424 return this.getPoint1().getDistance(arc.getPoint1())<Shape2D.ACCURACY;
425 return false;
426 }
427
428
429
430 if (arc.t0==Double.NEGATIVE_INFINITY||arc.t0==Double.POSITIVE_INFINITY)
431 return false;
432 if (arc.t1==Double.NEGATIVE_INFINITY||arc.t1==Double.POSITIVE_INFINITY)
433 return false;
434
435
436 if (getPoint1().getDistance(arc.getPoint1())<ACCURACY)
437 return getPoint2().getDistance(arc.getPoint2())<ACCURACY;
438
439 if (getPoint1().getDistance(arc.getPoint2())>ACCURACY)
440 return false;
441 if (getPoint2().getDistance(arc.getPoint1())>ACCURACY)
442 return false;
443 return true;
444 }
445
446 @Override
447 public LineArc2D clone() {
448 return new LineArc2D(x0, y0, dx, dy, t0, t1);
449 }
450 }