1 18 package org.apache.batik.ext.awt.geom; 19 20 import java.awt.geom.CubicCurve2D ; 21 import java.awt.geom.Point2D ; 22 import java.awt.geom.QuadCurve2D ; 23 import java.awt.geom.Rectangle2D ; 24 25 30 public class Quadradic extends AbstractSegment { 31 public Point2D.Double p1, p2, p3; 32 33 public Quadradic() { 34 p1 = new Point2D.Double (); 35 p2 = new Point2D.Double (); 36 p3 = new Point2D.Double (); 37 } 38 39 public Quadradic(double x1, double y1, 40 double x2, double y2, 41 double x3, double y3) { 42 p1 = new Point2D.Double (x1, y1); 43 p2 = new Point2D.Double (x2, y2); 44 p3 = new Point2D.Double (x3, y3); 45 } 46 47 public Quadradic(Point2D.Double p1, 48 Point2D.Double p2, 49 Point2D.Double p3) { 50 this.p1 = p1; 51 this.p2 = p2; 52 this.p3 = p3; 53 } 54 55 public Object clone() { 56 return new Quadradic(new Point2D.Double (p1.x, p1.y), 57 new Point2D.Double (p2.x, p2.y), 58 new Point2D.Double (p3.x, p3.y)); 59 } 60 61 public Segment reverse() { 62 return new Quadradic(new Point2D.Double (p3.x, p3.y), 63 new Point2D.Double (p2.x, p2.y), 64 new Point2D.Double (p1.x, p1.y)); 65 } 66 67 private void getMinMax(double p1, double p2, 68 double p3, double [] minMax) { 69 if (p3 > p1){ 70 minMax[0] = p1; minMax[1] = p3; 71 } else { 72 minMax[0] = p3; minMax[1] = p1; 73 } 74 75 double a = (p1-2*p2+p3); 76 double b = (p2-p1); 77 78 if (a == 0) return; 79 80 double tv = b/a; 81 if ((tv <= 0) || (tv >= 1)) return; 82 83 tv = ((p1-2*p2+p3)*tv+2*(p2-p1))*tv + p1; 84 if (tv < minMax[0]) minMax[0] = tv; 85 else if (tv > minMax[1]) minMax[1] = tv; 86 } 87 88 public double minX() { 89 double [] minMax = {0, 0}; 90 getMinMax(p1.x, p2.x, p3.x, minMax); 91 return minMax[0]; 92 } 93 public double maxX() { 94 double [] minMax = {0, 0}; 95 getMinMax(p1.x, p2.x, p3.x, minMax); 96 return minMax[1]; 97 } 98 public double minY() { 99 double [] minMax = {0, 0}; 100 getMinMax(p1.y, p2.y, p3.y, minMax); 101 return minMax[0]; 102 } 103 public double maxY() { 104 double [] minMax = {0, 0}; 105 getMinMax(p1.y, p2.y, p3.y, minMax); 106 return minMax[1]; 107 } 108 public Rectangle2D getBounds2D() { 109 double [] minMaxX = {0, 0}; 110 getMinMax(p1.x, p2.x, p3.x, minMaxX); 111 double [] minMaxY = {0, 0}; 112 getMinMax(p1.y, p2.y, p3.y, minMaxY); 113 114 return new Rectangle2D.Double 115 (minMaxX[0], minMaxY[0], 116 minMaxX[1]-minMaxX[0], minMaxY[1]-minMaxY[0]); 117 } 118 119 protected int findRoots(double y, double [] roots) { 120 double [] eqn = { p1.y-y, 2*(p2.y-p1.y), p1.y-2*p2.y+p3.y }; 121 return QuadCurve2D.solveQuadratic(eqn, roots); 122 } 124 125 public Point2D.Double evalDt(double t) { 126 double x = 2*(p1.x-2*p2.x+p3.x)*t + 2*(p2.x-p1.x); 127 double y = 2*(p1.y-2*p2.y+p3.y)*t + 2*(p2.y-p1.y); 128 return new Point2D.Double (x, y); 129 } 130 public Point2D.Double eval(double t) { 131 double x = ((p1.x-2*p2.x+p3.x)*t+2*(p2.x-p1.x))*t + p1.x; 132 double y = ((p1.y-2*p2.y+p3.y)*t+2*(p2.y-p1.y))*t + p1.y; 133 return new Point2D.Double (x, y); 134 } 135 136 public Segment getSegment(double t0, double t1) { 137 double dt = t1-t0; 138 Point2D.Double np1 = eval(t0); 139 Point2D.Double dp1 = evalDt(t0); 140 141 Point2D.Double np2 = new Point2D.Double 142 (np1.x+.5*dt*dp1.x, np1.y+.5*dt*dp1.y); 143 144 Point2D.Double np3 = eval(t1); 145 return new Quadradic(np1, np2, np3); 146 } 147 148 154 public void subdivide(Quadradic q0, Quadradic q1) { 155 if ((q0 == null) && (q1 == null)) return; 156 157 double x = (p1.x-2*p2.x+p3.x)*.25+(p2.x-p1.x) + p1.x; 158 double y = (p1.y-2*p2.y+p3.y)*.25+(p2.y-p1.y) + p1.y; 159 160 double dx = (p1.x-2*p2.x+p3.x)*.25 + (p2.x-p1.x)*.5; 161 double dy = (p1.y-2*p2.y+p3.y)*.25 + (p2.y-p1.y)*.5; 162 163 if (q0 != null) { 164 q0.p1.x = p1.x; 165 q0.p1.y = p1.y; 166 q0.p2.x = x-dx; 167 q0.p2.y = y-dy; 168 q0.p3.x = x; 169 q0.p3.y = y; 170 } 171 172 if (q1 != null) { 173 q1.p1.x = x; 174 q1.p1.y = y; 175 q1.p2.x = x+dx; 176 q1.p2.y = y+dy; 177 q1.p3.x = p3.x; 178 q1.p3.y = p3.y; 179 } 180 } 181 182 187 public void subdivide(double t, Quadradic q0, Quadradic q1) { 188 Point2D.Double np = eval(t); 189 Point2D.Double npd = evalDt(t); 190 191 if (q0 != null) { 192 q0.p1.x = p1.x; 193 q0.p1.y = p1.y; 194 q0.p2.x = np.x-(npd.x*t*.5); 195 q0.p2.y = np.y-(npd.y*t*.5); 196 q0.p3.x = np.x; 197 q0.p3.y = np.y; 198 } 199 200 if (q1 != null) { 201 q1.p1.x = np.x; 202 q1.p1.y = np.y; 203 q1.p2.x = np.x+(npd.x*(1-t)*.5); 204 q1.p2.y = np.y+(npd.y*(1-t)*.5); 205 q1.p3.x = p3.x; 206 q1.p3.y = p3.y; 207 } 208 } 209 210 216 public void subdivide(Segment s0, Segment s1) { 217 Quadradic q0=null, q1=null; 218 if (s0 instanceof Quadradic) q0 = (Quadradic)s0; 219 if (s1 instanceof Quadradic) q1 = (Quadradic)s1; 220 subdivide(q0, q1); 221 } 222 223 229 public void subdivide(double t, Segment s0, Segment s1) { 230 Quadradic q0=null, q1=null; 231 if (s0 instanceof Quadradic) q0 = (Quadradic)s0; 232 if (s1 instanceof Quadradic) q1 = (Quadradic)s1; 233 subdivide(t, q0, q1); 234 } 235 236 static int count = 0; 237 protected double subLength(double leftLegLen, double rightLegLen, 238 double maxErr) { 239 count++; 240 double dx, dy; 241 dx = p3.x-p1.x; 242 dy = p3.y-p1.y; 243 double cordLen = Math.sqrt(dx*dx+dy*dy); 244 245 double hullLen = leftLegLen+rightLegLen; 246 if (hullLen < maxErr) return (hullLen+cordLen)*.5; 247 248 double err = (hullLen-cordLen); 249 if (err < maxErr) 250 return (hullLen+cordLen)*.5; 251 252 Quadradic q = new Quadradic(); 253 double x = (p1.x+2*p2.x+p3.x)*.25; 254 double y = (p1.y+2*p2.y+p3.y)*.25; 255 256 dx = .25*dx; 257 dy = .25*dy; 258 259 q.p1.x = p1.x; 260 q.p1.y = p1.y; 261 q.p2.x = x-dx; 262 q.p2.y = y-dy; 263 q.p3.x = x; 264 q.p3.y = y; 265 266 double midLen = .25*cordLen; 267 double len = q.subLength(leftLegLen*.5, midLen, maxErr*.5); 268 269 q.p1.x = x; 270 q.p1.y = y; 271 q.p2.x = x+dx; 272 q.p2.y = y+dy; 273 q.p3.x = p3.x; 274 q.p3.y = p3.y; 275 276 len += q.subLength(midLen, rightLegLen*.5, maxErr*.5); 277 return len; 278 } 279 280 public double getLength() { 281 return getLength(0.000001); 282 } 283 284 public double getLength(double maxErr) { 285 double dx, dy; 286 dx = p2.x-p1.x; 287 dy = p2.y-p1.y; 288 double leftLegLen = Math.sqrt(dx*dx+dy*dy); 289 dx = p3.x-p2.x; 290 dy = p3.y-p2.y; 291 double rightLegLen = Math.sqrt(dx*dx+dy*dy); 292 293 double eps = maxErr*(leftLegLen+rightLegLen); 294 295 return subLength(leftLegLen, rightLegLen, eps); 296 } 297 298 public String toString() { 299 return ("M" + p1.x + "," + p1.y + 300 "Q" + p2.x + "," + p2.y + " " + 301 p3.x + "," + p3.y ); 302 } 303 304 373 } 374 | Popular Tags |