import java.awt.geom.Ellipse2D;\r
import java.awt.geom.GeneralPath;\r
import java.awt.geom.PathIterator;\r
+import java.awt.geom.Point2D;\r
import java.awt.geom.Rectangle2D;\r
\r
import javax.swing.JFrame;\r
}\r
\r
public Area getRegressedShape(double regression){\r
- Area ret = new Area(); \r
+ if ( regression == 0 )\r
+ return a;\r
+ \r
+ //Build these separatly because intersecting the line\r
+ //with the circle creates a small amount of error which\r
+ //shows up when the resulting edge is no longer exactly\r
+ //colinear with the original edge.\r
+ Area rRect = new Area(); \r
+ Area rCirc = new Area();\r
\r
PathIterator i = a.getPathIterator(new AffineTransform(), .001);\r
double last[] = {0,0};\r
double first[] = {0,0};\r
+\r
while (!i.isDone()) {\r
double coords[] = new double[6];\r
int type = i.currentSegment(coords);\r
coords[0] = first[0];\r
coords[1] = first[1];\r
case PathIterator.SEG_LINETO:\r
- //Do it;\r
- \r
- //TODO XXX\r
- //Usint arctan is imprecise, the base of the rectangle does not perfectly coincide with the\r
- //edge of the poly. Instead I should find the normal vector and build the rect myself prerotated.\r
- double len = Math.sqrt(Math.pow(last[0] - coords[0], 2) + Math.pow(last[1] - coords[1], 2));\r
+ //Calculate the normal to this edge\r
double dx = coords[0]-last[0];\r
double dy = coords[1]-last[1];\r
- double angle = Math.atan2(dy, dx);\r
- \r
- Area rect;\r
- if ( regression > 0 )\r
- rect = new Area(new Rectangle2D.Double(0,0,len,regression));\r
- else\r
- rect = new Area(new Rectangle2D.Double(0,regression,len,-regression));\r
- rect.transform(AffineTransform.getRotateInstance(angle));\r
- rect.transform(AffineTransform.getTranslateInstance(last[0], last[1]));\r
- ret.add(rect);\r
- \r
- if ( regression > 0 ){\r
- ret.add(new Area(new Ellipse2D.Double(coords[0]-regression, coords[1]-regression, regression*2, regression*2)));\r
- } else {\r
- ret.add(new Area(new Ellipse2D.Double(coords[0]+regression, coords[1]+regression, -regression*2, -regression*2)));\r
- }\r
+ double len = Math.sqrt(dx*dx + dy*dy); \r
+ double normal[] = {-dy/len,dx/len};\r
\r
+ //Calculate the displacement of the endpoints\r
+ //to create a rect\r
+ double displacement[] = {regression*normal[0], regression*normal[1]};\r
+\r
+ //Create that rect. Winding does not seem to matter...\r
+ GeneralPath p = new GeneralPath();\r
+ p.moveTo(last[0], last[1]);\r
+ p.lineTo(last[0]+displacement[0], last[1]+displacement[1]);\r
+ p.lineTo(coords[0]+displacement[0], coords[1]+displacement[1]);\r
+ p.lineTo(coords[0], coords[1]);\r
+ p.closePath();\r
+ rRect.add( new Area(p));\r
+\r
+ double er = Math.abs(regression);\r
+ rCirc.add(new Area(new Ellipse2D.Double(coords[0]-er, coords[1]-er, 2*er, 2*er)));\r
\r
last[0] = coords[0];\r
last[1] = coords[1];\r
i.next();\r
}\r
\r
+\r
if ( regression > 0 ){\r
- ret.add(a);\r
+ //Combine all together\r
+ rRect.add(a);\r
+ rRect.add(rCirc);\r
}else{\r
Area acp = (Area)a.clone();\r
- acp.subtract(ret);\r
- ret = acp;\r
+ acp.subtract(rRect);\r
+ acp.subtract(rCirc);\r
+ rRect = acp;\r
}\r
- return ret;\r
+ return rRect;\r
}\r
}\r
\r
\r
g.clearRect(0, 0, 600, 600);\r
\r
+\r
+ g.setColor(Color.black);\r
+ g.fill(shape.getRegressedShape(r));\r
+ g.setColor(Color.yellow); \r
+ g.draw(shape.getRegressedShape(0));\r
g.setColor(Color.red);\r
g.draw(shape.getRegressedShape(r));\r
- //g.setColor(Color.black); \r
- //g.draw(shape.getRegressedShape(0));\r
+\r
\r
}\r
\r