View Javadoc

1   // Copyright 2004, FreeHEP.
2   package org.freehep.graphics2d;
3   
4   import java.awt.Rectangle;
5   import java.awt.Shape;
6   import java.awt.geom.AffineTransform;
7   import java.awt.geom.PathIterator;
8   import java.awt.geom.Point2D;
9   import java.awt.geom.Rectangle2D;
10  
11  /**
12   * This class can be used in a transient way to deal with the drawing or filling
13   * of an array of double points as a polyline/polygon. The class implements a
14   * shape and comes with an associated iterator.
15   * 
16   * @author Mark Donszelmann
17   * @version $Id: ArrayPath.java 8584 2006-08-10 23:06:37Z duns $
18   */
19  public class ArrayPath implements Shape {
20  
21      private class ArrayPathIterator implements PathIterator {
22  
23          private double[] xPoints, yPoints;
24  
25          private double lastX, lastY;
26  
27          private int nPoints;
28  
29          private boolean closed;
30  
31          private int resolution;
32  
33          private int currentPoint;
34  
35          private boolean isDone;
36  
37          private ArrayPathIterator(double[] xPoints, double[] yPoints,
38                  int nPoints, boolean closed, int resolution) {
39              this.xPoints = xPoints;
40              this.yPoints = yPoints;
41              this.nPoints = nPoints;
42              this.closed = closed;
43              this.resolution = resolution;
44              currentPoint = 0;
45              isDone = nPoints == 0;
46          }
47  
48          public boolean isDone() {
49              return isDone;
50          }
51  
52          public void next() {
53              currentPoint++;
54              while ((currentPoint < nPoints - 1)
55                      && (Math.abs(xPoints[currentPoint] - lastX) < resolution)
56                      && (Math.abs(yPoints[currentPoint] - lastY) < resolution)) {
57                  currentPoint++;
58              }
59  
60              if (closed
61                      && (currentPoint == nPoints - 1)
62                      && (Math.abs(xPoints[currentPoint] - xPoints[0]) < resolution)
63                      && (Math.abs(yPoints[currentPoint] - yPoints[0]) < resolution)) {
64                  currentPoint++; // skip last point since it is same as first
65              }
66  
67              isDone = (closed) ? currentPoint > nPoints
68                      : currentPoint >= nPoints;
69          }
70  
71          public int currentSegment(double[] coords) {
72              if (closed && (currentPoint == nPoints)) {
73                  return PathIterator.SEG_CLOSE;
74              }
75  
76              coords[0] = lastX = xPoints[currentPoint];
77              coords[1] = lastY = yPoints[currentPoint];
78              return (currentPoint == 0) ? PathIterator.SEG_MOVETO
79                      : PathIterator.SEG_LINETO;
80          }
81  
82          public int currentSegment(float[] coords) {
83              if (closed && (currentPoint == nPoints)) {
84                  return PathIterator.SEG_CLOSE;
85              }
86  
87              lastX = xPoints[currentPoint];
88              lastY = yPoints[currentPoint];
89              coords[0] = (float) lastX;
90              coords[1] = (float) lastY;
91              return (currentPoint == 0) ? PathIterator.SEG_MOVETO
92                      : PathIterator.SEG_LINETO;
93          }
94  
95          public int getWindingRule() {
96              return PathIterator.WIND_NON_ZERO;
97          }
98      }
99  
100     private double[] xPoints, yPoints;
101 
102     private int nPoints;
103 
104     private boolean closed;
105 
106     private int resolution;
107 
108     public ArrayPath(double[] xPoints, double[] yPoints, int nPoints,
109             boolean closed, int resolution) {
110         this.xPoints = xPoints;
111         this.yPoints = yPoints;
112         this.nPoints = nPoints;
113         this.closed = closed;
114         this.resolution = resolution;
115     }
116 
117     public boolean contains(double x, double y) {
118         // conservative guess
119         return false;
120     }
121 
122     public boolean contains(double x, double y, double w, double h) {
123         // conservative guess
124         return false;
125     }
126 
127     public boolean contains(Point2D p) {
128         return contains(p.getX(), p.getY());
129     }
130 
131     public boolean contains(Rectangle2D r) {
132         return contains(r.getX(), r.getY(), r.getWidth(), r.getHeight());
133     }
134 
135     public boolean intersects(double x, double y, double w, double h) {
136         // conservative guess
137         return true;
138     }
139 
140     public boolean intersects(Rectangle2D r) {
141         return intersects(r.getX(), r.getY(), r.getWidth(), r.getHeight());
142     }
143 
144     public PathIterator getPathIterator(AffineTransform at, double flatness) {
145         return getPathIterator(at);
146     }
147 
148     public Rectangle2D getBounds2D() {
149         double x1, y1, x2, y2;
150         int i = nPoints;
151         if (i > 0) {
152             i--;
153             y1 = y2 = yPoints[i];
154             x1 = x2 = xPoints[i];
155             while (i > 0) {
156                 i--;
157                 double y = yPoints[i];
158                 double x = xPoints[i];
159                 if (x < x1)
160                     x1 = x;
161                 if (y < y1)
162                     y1 = y;
163                 if (x > x2)
164                     x2 = x;
165                 if (y > y2)
166                     y2 = y;
167             }
168         } else {
169             x1 = y1 = x2 = y2 = 0.0f;
170         }
171         return new Rectangle2D.Double(x1, y1, x2 - x1, y2 - y1);
172     }
173 
174     public Rectangle getBounds() {
175         return getBounds2D().getBounds();
176     }
177 
178     public PathIterator getPathIterator(AffineTransform t) {
179         double[] transformedXPoints = xPoints;
180         double[] transformedYPoints = yPoints;
181         if (t != null) {
182             // FIXME, this seems a silly slow way to deal with this.
183             transformedXPoints = new double[nPoints];
184             transformedYPoints = new double[nPoints];
185             Point2D s = new Point2D.Double();
186             Point2D d = new Point2D.Double();
187             for (int i = 0; i < nPoints; i++) {
188                 s.setLocation(xPoints[i], yPoints[i]);
189                 t.transform(s, d);
190                 transformedXPoints[i] = d.getX();
191                 transformedYPoints[i] = d.getY();
192             }
193         }
194         return new ArrayPathIterator(transformedXPoints, transformedYPoints,
195                 nPoints, closed, resolution);
196     }
197 }