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.curve;
28
29 import java.awt.Graphics2D;
30 import java.util.ArrayList;
31 import java.util.Collection;
32
33 import math.geom2d.AffineTransform2D;
34 import math.geom2d.Box2D;
35 import math.geom2d.Point2D;
36 import math.geom2d.Shape2D;
37 import math.geom2d.Vector2D;
38 import math.geom2d.polygon.Polyline2D;
39
40
41
42
43
44
45
46
47
48 public class PolyCurve2D<T extends ContinuousCurve2D> extends CurveArray2D<T>
49 implements ContinuousCurve2D {
50
51
52 protected boolean closed = false;
53
54
55
56
57 public PolyCurve2D() {
58 }
59
60 public PolyCurve2D(int n) {
61 super(n);
62 }
63
64 public PolyCurve2D(T[] curves) {
65 super(curves);
66 }
67
68 public PolyCurve2D(T[] curves, boolean closed) {
69 super(curves);
70 this.closed = closed;
71 }
72
73 public PolyCurve2D(Collection<? extends T> curves) {
74 super(curves);
75 }
76
77 public PolyCurve2D(Collection<? extends T> curves, boolean closed) {
78 super(curves);
79 this.closed = closed;
80 }
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106 protected static <T extends ContinuousCurve2D> Collection<T> wrapCurve(T curve) {
107 ArrayList<T> list = new ArrayList<T> (1);
108 list.add(curve);
109 return list;
110 }
111
112
113
114
115
116
117
118
119 public void setClosed(boolean b) {
120 closed = b;
121 }
122
123
124
125
126
127
128
129 public Vector2D getLeftTangent(double t) {
130 return this.getChildCurve(t).getLeftTangent(this.getLocalPosition(t));
131 }
132
133
134
135
136 public Vector2D getRightTangent(double t) {
137 return this.getChildCurve(t).getRightTangent(this.getLocalPosition(t));
138 }
139
140
141
142
143 public boolean isClosed() {
144 return closed;
145 }
146
147 public Polyline2D getAsPolyline(int n) {
148 Point2D[] points = new Point2D[n+1];
149 double t0 = this.getT0();
150 double t1 = this.getT1();
151 double dt = (t1-t0)/n;
152 for (int i = 0; i<n; i++)
153 points[i] = this.getPoint(i*dt+t0);
154 return new Polyline2D(points);
155 }
156
157
158
159
160
161
162 public Collection<? extends SmoothCurve2D> getSmoothPieces() {
163 ArrayList<SmoothCurve2D> list = new ArrayList<SmoothCurve2D>();
164 for (Curve2D curve : this.curves)
165 list.addAll(PolyCurve2D.getSmoothCurves(curve));
166 return list;
167 }
168
169
170
171
172
173
174
175 private final static Collection<SmoothCurve2D> getSmoothCurves(Curve2D curve) {
176
177 ArrayList<SmoothCurve2D> array = new ArrayList<SmoothCurve2D>();
178
179
180 if (curve instanceof SmoothCurve2D) {
181 array.add((SmoothCurve2D) curve);
182 return array;
183 }
184
185
186 if (curve instanceof CurveSet2D) {
187 for (Curve2D curve2 : ((CurveSet2D<?>) curve).getCurves())
188 array.addAll(getSmoothCurves(curve2));
189 return array;
190 }
191
192 if (curve==null)
193 return array;
194
195 System.err.println("could not find smooth parts of curve with class "
196 +curve.getClass().getName());
197 return array;
198 }
199
200
201
202
203 @Override
204 public Collection<? extends PolyCurve2D<?>> getContinuousCurves() {
205 return wrapCurve(this);
206 }
207
208 @Override
209 public PolyCurve2D<? extends ContinuousCurve2D> getReverseCurve() {
210
211 int n = curves.size();
212 ContinuousCurve2D[] curves2 = new ContinuousCurve2D[n];
213
214
215 for (int i = 0; i<n; i++)
216 curves2[i] = (ContinuousCurve2D)curves.get(n-1-i).getReverseCurve();
217
218
219 return new PolyCurve2D<ContinuousCurve2D>(curves2);
220 }
221
222
223
224
225
226 @Override
227 public PolyCurve2D<? extends ContinuousCurve2D> getSubCurve(double t0,
228 double t1) {
229
230 if (t1<t0&!this.isClosed())
231 return new PolyCurve2D<ContinuousCurve2D>();
232
233
234 CurveSet2D<?> set = super.getSubCurve(t0, t1);
235
236
237 PolyCurve2D<ContinuousCurve2D> subCurve =
238 new PolyCurve2D<ContinuousCurve2D>(set.getCurveNumber());
239
240
241 subCurve.setClosed(false);
242
243
244 for (Curve2D curve : set.getCurves())
245 subCurve.addCurve((ContinuousCurve2D) curve);
246
247
248 return subCurve;
249 }
250
251
252
253
254
255
256
257 @Override
258 public CurveSet2D<? extends ContinuousCurve2D> clip(Box2D box) {
259
260 CurveSet2D<? extends Curve2D> set = Curve2DUtils.clipCurve(this, box);
261
262
263 CurveArray2D<ContinuousCurve2D> result =
264 new CurveArray2D<ContinuousCurve2D>(set.getCurveNumber());
265
266
267 for (Curve2D curve : set.getCurves()) {
268 if (curve instanceof ContinuousCurve2D)
269 result.addCurve((ContinuousCurve2D) curve);
270 }
271 return result;
272 }
273
274 @Override
275 public PolyCurve2D<? extends ContinuousCurve2D> transform(
276 AffineTransform2D trans) {
277 PolyCurve2D<ContinuousCurve2D> result = new PolyCurve2D<ContinuousCurve2D>();
278 for (ContinuousCurve2D curve : curves)
279 result.addCurve((ContinuousCurve2D)curve.transform(trans));
280 result.setClosed(this.isClosed());
281 return result;
282 }
283
284 public java.awt.geom.GeneralPath appendPath(java.awt.geom.GeneralPath path) {
285 Point2D point;
286 for (ContinuousCurve2D curve : getCurves()) {
287 point = curve.getPoint(curve.getT0());
288 path.lineTo((float) point.getX(), (float) point.getY());
289 curve.appendPath(path);
290 }
291
292
293 if (closed) {
294 point = this.getFirstPoint();
295 path.lineTo((float) point.getX(), (float) point.getY());
296 }
297
298 return path;
299 }
300
301 @Override
302 public java.awt.geom.GeneralPath getGeneralPath() {
303
304 java.awt.geom.GeneralPath path = new java.awt.geom.GeneralPath();
305
306
307 if (curves.size()==0)
308 return path;
309
310
311 Point2D start, current;
312 start = this.getFirstPoint();
313 path.moveTo((float) start.getX(), (float) start.getY());
314 current = start;
315
316
317 for(ContinuousCurve2D curve : curves) {
318 start = curve.getFirstPoint();
319 if (start.distance(current)>Shape2D.ACCURACY)
320 path.lineTo((float) start.getX(), (float) start.getY());
321 path = curve.appendPath(path);
322 current = start;
323 }
324
325
326 if (closed) {
327 path.closePath();
328 }
329
330
331 return path;
332 }
333
334 @Override
335 public void draw(Graphics2D g2) {
336 g2.draw(this.getGeneralPath());
337 }
338
339 @Override
340 public boolean equals(Object obj) {
341
342 if (!(obj instanceof CurveSet2D))
343 return false;
344 PolyCurve2D<?> curveSet = (PolyCurve2D<?>) obj;
345
346
347 if (this.getCurveNumber()!=curveSet.getCurveNumber())
348 return false;
349
350
351 for(int i=0; i<curves.size(); i++)
352 if(!this.curves.get(i).equals(curveSet.curves.get(i)))
353 return false;
354
355
356 return true;
357 }
358
359 }