1 import java.awt.BasicStroke;
\r
2 import java.awt.Color;
\r
3 import java.awt.Graphics;
\r
4 import java.awt.Graphics2D;
\r
5 import java.awt.Shape;
\r
6 import java.awt.geom.AffineTransform;
\r
7 import java.awt.geom.Area;
\r
8 import java.awt.geom.FlatteningPathIterator;
\r
9 import java.awt.geom.GeneralPath;
\r
10 import java.awt.geom.PathIterator;
\r
12 import javax.swing.JFrame;
\r
13 import javax.swing.JPanel;
\r
16 public class QuadTest extends JPanel {
\r
19 public void paint(Graphics g){
\r
21 Graphics2D g2d = (Graphics2D)g;
\r
28 g2d.setStroke(new BasicStroke(.02f));
\r
32 a = new Area(new Rectangle2D.Double(0,0,1,1));
\r
33 //a.transform(AffineTransform.getRotateInstance(Math.PI/4.0));
\r
34 g2d.setColor(Color.black);
\r
36 g2d.setColor(Color.red);
\r
38 g2d.draw(square( a ));
\r
40 yRotatedVolume(a) + ", " +
\r
41 yRotatedSurfaceArea(a) + "\n"
\r
45 a = new Area( new Ellipse2D.Double(2, 5, 4, 4));
\r
46 g2d.setColor(Color.black);
\r
48 g2d.setColor(Color.red);
\r
50 g2d.draw(square( a ));
\r
52 yRotatedVolume(a) + ", " +
\r
53 yRotatedSurfaceArea(a) + "\n"
\r
58 p = new GeneralPath();
\r
64 g2d.translate(0, 8);
\r
65 g2d.setColor(Color.black);
\r
67 g2d.setColor(Color.red);
\r
69 g2d.draw(square( a ));
\r
71 yRotatedVolume(a) + ", " +
\r
72 yRotatedSurfaceArea(a) + "\n"
\r
75 p = new GeneralPath();
\r
81 g2d.translate(0, 2);
\r
82 g2d.setColor(Color.black);
\r
84 g2d.setColor(Color.red);
\r
86 g2d.draw(square( a ));
\r
88 yRotatedVolume(a) + ", " +
\r
89 yRotatedSurfaceArea(a) + "\n"
\r
92 p = new GeneralPath();
\r
99 g2d.translate(0, 2);
\r
100 g2d.setColor(Color.black);
\r
102 g2d.setColor(Color.red);
\r
104 g2d.draw(square( a ));
\r
105 System.out.println(
\r
106 yRotatedVolume(a) + ", " +
\r
107 yRotatedSurfaceArea(a) + "\n"
\r
114 private double yRotatedVolume(Area a){
\r
115 return Math.PI * area(new Area(square(a)));
\r
118 private Shape square(java.awt.geom.Area a) {
\r
119 PathIterator i = a.getPathIterator(new AffineTransform(), 0.0001);
\r
120 GeneralPath cur = new GeneralPath();
\r
122 double last[] = {0,0};
\r
123 while (!i.isDone()) {
\r
124 double coords[] = new double[6];
\r
125 int type = i.currentSegment(coords);
\r
127 case PathIterator.SEG_CLOSE:
\r
130 case PathIterator.SEG_MOVETO:
\r
131 cur.moveTo(Math.pow(coords[0],2), coords[1]);
\r
132 last[0] = coords[0];
\r
133 last[1] = coords[1];
\r
135 case PathIterator.SEG_CUBICTO:
\r
136 throw new Error("Non-flattened geometry!");
\r
137 case PathIterator.SEG_LINETO:
\r
138 double x = last[0];
\r
139 double y = last[1];
\r
140 double len = Math.sqrt(Math.pow(last[0]-coords[0], 2) + Math.pow(last[1]-coords[1], 2));
\r
141 int steps = (int)(len / .01) + 5;
\r
142 for (int s = 0; s < steps; s++) {
\r
143 x += (coords[0] - last[0]) / steps;
\r
144 y += (coords[1] - last[1]) / steps;
\r
145 cur.lineTo(Math.pow(x, 2), y);
\r
147 last[0] = coords[0];
\r
148 last[1] = coords[1];
\r
150 case PathIterator.SEG_QUADTO:
\r
151 throw new Error("Non-flattened geometry!");
\r
159 private double yRotatedSurfaceArea(java.awt.geom.Area a) {
\r
160 //TODO: I think I need to handle seg_close!!
\r
161 PathIterator i = a.getPathIterator(new AffineTransform(), .001);
\r
162 double x = 0, y = 0;
\r
163 double mx = 0, my = 0;
\r
165 while (!i.isDone()) {
\r
166 double coords[] = new double[6];
\r
167 int type = i.currentSegment(coords);
\r
168 if (type == PathIterator.SEG_LINETO || type == PathIterator.SEG_CLOSE) {
\r
171 double nx = coords[0];
\r
172 double ny = coords[1];
\r
174 if ( type == PathIterator.SEG_CLOSE ){
\r
179 double dy = Math.abs(y-ny);
\r
180 double dx = Math.abs(x-nx);
\r
181 double xl = x>nx?x:nx;
\r
182 double xs = x<nx?x:nx;
\r
186 add = 2 * Math.PI * xl * dy;
\r
187 } else if ( dy == 0 ){
\r
188 add = Math.PI * xl * xl - Math.PI * xs * xs;
\r
190 double h = xl/dx * dy;
\r
191 double s1 = Math.sqrt(xl*xl + h*h);
\r
192 double s2 = Math.sqrt(xs*xs + (h-dy)*(h-dy));
\r
193 add = Math.PI * (xl*s1 - xs*s2);
\r
200 } else if (type == PathIterator.SEG_MOVETO) {
\r
201 mx = x = coords[0];
\r
202 my = y = coords[1];
\r
204 throw new Error("Non-flattened geometry!");
\r
213 private double area(java.awt.geom.Area a) {
\r
214 if ( !a.isSingular() )
\r
215 throw new IllegalArgumentException("Can not calculate area of non-singular shape!");
\r
216 PathIterator i = a.getPathIterator(new AffineTransform(), .001);
\r
219 double x = 0, y = 0, sx = 0, sy = 0;
\r
222 while (!i.isDone()) {
\r
223 double coords[] = new double[6];
\r
224 int type = i.currentSegment(coords);
\r
226 case PathIterator.SEG_CLOSE:
\r
227 //Go back to the start
\r
233 case PathIterator.SEG_LINETO:
\r
239 //Remember the last points
\r
244 case PathIterator.SEG_MOVETO:
\r
245 //Remember the starting point
\r
246 x = sx = coords[0];
\r
247 y = sy = coords[1];
\r
250 throw new Error("Bad segment type from Flattening Path Iterator");
\r
255 area = area / 2.0; // Result so far is double the signed area
\r
257 if ( area < 0 ) //Depending on winding it could be negative
\r
258 area = area * -1.0;
\r
265 public class FancyPathIterator extends FlatteningPathIterator{
\r
267 public FancyPathIterator(PathIterator path, double error) {
\r
268 super(path, error);
\r
275 public static void main(String args[]){
\r
276 JFrame f = new JFrame();
\r
277 f.setContentPane(new QuadTest());
\r
278 f.setDefaultCloseOperation(f.DISPOSE_ON_CLOSE);
\r
279 f.setSize(1500,800);
\r
280 f.setLocation(1600, 100);
\r