1:
60:
61: package ;
62:
63: import ;
64: import ;
65: import ;
66: import ;
67: import ;
68: import ;
69: import ;
70: import ;
71: import ;
72: import ;
73: import ;
74: import ;
75:
76: import ;
77:
78:
83: public class ShapeUtilities {
84:
85:
88: private ShapeUtilities() {
89: }
90:
91:
106: public static Shape clone(final Shape shape) {
107:
108: if (shape instanceof Cloneable) {
109: try {
110: return (Shape) ObjectUtilities.clone(shape);
111: }
112: catch (CloneNotSupportedException cnse) {
113: }
114: }
115: final Shape result = null;
116: return result;
117: }
118:
119:
132: public static boolean equal(final Shape s1, final Shape s2) {
133: if (s1 instanceof Line2D && s2 instanceof Line2D) {
134: return equal((Line2D) s1, (Line2D) s2);
135: }
136: else if (s1 instanceof Ellipse2D && s2 instanceof Ellipse2D) {
137: return equal((Ellipse2D) s1, (Ellipse2D) s2);
138: }
139: else if (s1 instanceof Arc2D && s2 instanceof Arc2D) {
140: return equal((Arc2D) s1, (Arc2D) s2);
141: }
142: else if (s1 instanceof Polygon && s2 instanceof Polygon) {
143: return equal((Polygon) s1, (Polygon) s2);
144: }
145: else if (s1 instanceof GeneralPath && s2 instanceof GeneralPath) {
146: return equal((GeneralPath) s1, (GeneralPath) s2);
147: }
148: else {
149:
150: return ObjectUtilities.equal(s1, s2);
151: }
152: }
153:
154:
163: public static boolean equal(final Line2D l1, final Line2D l2) {
164: if (l1 == null) {
165: return (l2 == null);
166: }
167: if (l2 == null) {
168: return false;
169: }
170: if (!l1.getP1().equals(l2.getP1())) {
171: return false;
172: }
173: if (!l1.getP2().equals(l2.getP2())) {
174: return false;
175: }
176: return true;
177: }
178:
179:
188: public static boolean equal(final Ellipse2D e1, final Ellipse2D e2) {
189: if (e1 == null) {
190: return (e2 == null);
191: }
192: if (e2 == null) {
193: return false;
194: }
195: if (!e1.getFrame().equals(e2.getFrame())) {
196: return false;
197: }
198: return true;
199: }
200:
201:
210: public static boolean equal(final Arc2D a1, final Arc2D a2) {
211: if (a1 == null) {
212: return (a2 == null);
213: }
214: if (a2 == null) {
215: return false;
216: }
217: if (!a1.getFrame().equals(a2.getFrame())) {
218: return false;
219: }
220: if (a1.getAngleStart() != a2.getAngleStart()) {
221: return false;
222: }
223: if (a1.getAngleExtent() != a2.getAngleExtent()) {
224: return false;
225: }
226: if (a1.getArcType() != a2.getArcType()) {
227: return false;
228: }
229: return true;
230: }
231:
232:
241: public static boolean equal(final Polygon p1, final Polygon p2) {
242: if (p1 == null) {
243: return (p2 == null);
244: }
245: if (p2 == null) {
246: return false;
247: }
248: if (p1.npoints != p2.npoints) {
249: return false;
250: }
251: if (!Arrays.equals(p1.xpoints, p2.xpoints)) {
252: return false;
253: }
254: if (!Arrays.equals(p1.ypoints, p2.ypoints)) {
255: return false;
256: }
257: return true;
258: }
259:
260:
269: public static boolean equal(final GeneralPath p1, final GeneralPath p2) {
270: if (p1 == null) {
271: return (p2 == null);
272: }
273: if (p2 == null) {
274: return false;
275: }
276: if (p1.getWindingRule() != p2.getWindingRule()) {
277: return false;
278: }
279: PathIterator iterator1 = p1.getPathIterator(null);
280: PathIterator iterator2 = p1.getPathIterator(null);
281: double[] d1 = new double[6];
282: double[] d2 = new double[6];
283: boolean done = iterator1.isDone() && iterator2.isDone();
284: while (!done) {
285: if (iterator1.isDone() != iterator2.isDone()) {
286: return false;
287: }
288: int seg1 = iterator1.currentSegment(d1);
289: int seg2 = iterator2.currentSegment(d2);
290: if (seg1 != seg2) {
291: return false;
292: }
293: if (!Arrays.equals(d1, d2)) {
294: return false;
295: }
296: iterator1.next();
297: iterator2.next();
298: done = iterator1.isDone() && iterator2.isDone();
299: }
300: return true;
301: }
302:
303:
312: public static Shape createTranslatedShape(final Shape shape,
313: final double transX,
314: final double transY) {
315: if (shape == null) {
316: throw new IllegalArgumentException("Null 'shape' argument.");
317: }
318: final AffineTransform transform = AffineTransform.getTranslateInstance(
319: transX, transY
320: );
321: return transform.createTransformedShape(shape);
322: }
323:
324:
336: public static Shape createTranslatedShape(final Shape shape,
337: final RectangleAnchor anchor,
338: final double locationX,
339: final double locationY) {
340: if (shape == null) {
341: throw new IllegalArgumentException("Null 'shape' argument.");
342: }
343: if (anchor == null) {
344: throw new IllegalArgumentException("Null 'anchor' argument.");
345: }
346: Point2D anchorPoint = RectangleAnchor.coordinates(
347: shape.getBounds2D(), anchor
348: );
349: final AffineTransform transform = AffineTransform.getTranslateInstance(
350: locationX - anchorPoint.getX(), locationY - anchorPoint.getY()
351: );
352: return transform.createTransformedShape(shape);
353: }
354:
355:
366: public static Shape rotateShape(final Shape base, final double angle,
367: final float x, final float y) {
368: if (base == null) {
369: return null;
370: }
371: final AffineTransform rotate = AffineTransform.getRotateInstance(
372: angle, x, y
373: );
374: final Shape result = rotate.createTransformedShape(base);
375: return result;
376: }
377:
378:
387: public static void drawRotatedShape(final Graphics2D g2, final Shape shape,
388: final double angle,
389: final float x, final float y) {
390:
391: final AffineTransform saved = g2.getTransform();
392: final AffineTransform rotate = AffineTransform.getRotateInstance(
393: angle, x, y
394: );
395: g2.transform(rotate);
396: g2.draw(shape);
397: g2.setTransform(saved);
398:
399: }
400:
401:
402: private static final float SQRT2 = (float) Math.pow(2.0, 0.5);
403:
404:
412: public static Shape createDiagonalCross(final float l, final float t) {
413: final GeneralPath p0 = new GeneralPath();
414: p0.moveTo(-l - t, -l + t);
415: p0.lineTo(-l + t, -l - t);
416: p0.lineTo(0.0f, -t * SQRT2);
417: p0.lineTo(l - t, -l - t);
418: p0.lineTo(l + t, -l + t);
419: p0.lineTo(t * SQRT2, 0.0f);
420: p0.lineTo(l + t, l - t);
421: p0.lineTo(l - t, l + t);
422: p0.lineTo(0.0f, t * SQRT2);
423: p0.lineTo(-l + t, l + t);
424: p0.lineTo(-l - t, l - t);
425: p0.lineTo(-t * SQRT2, 0.0f);
426: p0.closePath();
427: return p0;
428: }
429:
430:
438: public static Shape createRegularCross(final float l, final float t) {
439: final GeneralPath p0 = new GeneralPath();
440: p0.moveTo(-l, t);
441: p0.lineTo(-t, t);
442: p0.lineTo(-t, l);
443: p0.lineTo(t, l);
444: p0.lineTo(t, t);
445: p0.lineTo(l, t);
446: p0.lineTo(l, -t);
447: p0.lineTo(t, -t);
448: p0.lineTo(t, -l);
449: p0.lineTo(-t, -l);
450: p0.lineTo(-t, -t);
451: p0.lineTo(-l, -t);
452: p0.closePath();
453: return p0;
454: }
455:
456:
463: public static Shape createDiamond(final float s) {
464: final GeneralPath p0 = new GeneralPath();
465: p0.moveTo(0.0f, -s);
466: p0.lineTo(s, 0.0f);
467: p0.lineTo(0.0f, s);
468: p0.lineTo(-s, 0.0f);
469: p0.closePath();
470: return p0;
471: }
472:
473:
480: public static Shape createUpTriangle(final float s) {
481: final GeneralPath p0 = new GeneralPath();
482: p0.moveTo(0.0f, -s);
483: p0.lineTo(s, s);
484: p0.lineTo(-s, s);
485: p0.closePath();
486: return p0;
487: }
488:
489:
496: public static Shape createDownTriangle(final float s) {
497: final GeneralPath p0 = new GeneralPath();
498: p0.moveTo(0.0f, s);
499: p0.lineTo(s, -s);
500: p0.lineTo(-s, -s);
501: p0.closePath();
502: return p0;
503: }
504:
505:
515: public static Shape createLineRegion(final Line2D line, final float width) {
516: final GeneralPath result = new GeneralPath();
517: final float x1 = (float) line.getX1();
518: final float x2 = (float) line.getX2();
519: final float y1 = (float) line.getY1();
520: final float y2 = (float) line.getY2();
521: if ((x2 - x1) != 0.0) {
522: final double theta = Math.atan((y2 - y1) / (x2 - x1));
523: final float dx = (float) Math.sin(theta) * width;
524: final float dy = (float) Math.cos(theta) * width;
525: result.moveTo(x1 - dx, y1 + dy);
526: result.lineTo(x1 + dx, y1 - dy);
527: result.lineTo(x2 + dx, y2 - dy);
528: result.lineTo(x2 - dx, y2 + dy);
529: result.closePath();
530: }
531: else {
532:
533: result.moveTo(x1 - width / 2.0f, y1);
534: result.lineTo(x1 + width / 2.0f, y1);
535: result.lineTo(x2 + width / 2.0f, y2);
536: result.lineTo(x2 - width / 2.0f, y2);
537: result.closePath();
538: }
539: return result;
540: }
541:
542:
555: public static Point2D getPointInRectangle(double x, double y,
556: final Rectangle2D area) {
557:
558: x = Math.max(area.getMinX(), Math.min(x, area.getMaxX()));
559: y = Math.max(area.getMinY(), Math.min(y, area.getMaxY()));
560: return new Point2D.Double(x, y);
561:
562: }
563:
564:
573: public static boolean contains(final Rectangle2D rect1,
574: final Rectangle2D rect2) {
575:
576: final double x0 = rect1.getX();
577: final double y0 = rect1.getY();
578: final double x = rect2.getX();
579: final double y = rect2.getY();
580: final double w = rect2.getWidth();
581: final double h = rect2.getHeight();
582:
583: return ((x >= x0) && (y >= y0)
584: && ((x + w) <= (x0 + rect1.getWidth()))
585: && ((y + h) <= (y0 + rect1.getHeight())));
586:
587: }
588:
589:
590:
599: public static boolean intersects (final Rectangle2D rect1,
600: final Rectangle2D rect2) {
601:
602: final double x0 = rect1.getX();
603: final double y0 = rect1.getY();
604:
605: final double x = rect2.getX();
606: final double width = rect2.getWidth();
607: final double y = rect2.getY();
608: final double height = rect2.getHeight();
609: return (x + width >= x0 && y + height >= y0 && x <= x0 + rect1.getWidth()
610: && y <= y0 + rect1.getHeight());
611: }
612: }