1 7 8 package java.awt.geom; 9 10 import java.util.*; 11 12 19 class ArcIterator implements PathIterator { 20 double x, y, w, h, angStRad, increment, cv; 21 AffineTransform affine; 22 int index; 23 int arcSegs; 24 int lineSegs; 25 26 ArcIterator(Arc2D a, AffineTransform at) { 27 this.w = a.getWidth() / 2; 28 this.h = a.getHeight() / 2; 29 this.x = a.getX() + w; 30 this.y = a.getY() + h; 31 this.angStRad = -Math.toRadians(a.getAngleStart()); 32 this.affine = at; 33 double ext = -a.getAngleExtent(); 34 if (ext >= 360.0 || ext <= -360) { 35 arcSegs = 4; 36 this.increment = Math.PI / 2; 37 this.cv = 0.5522847498307933; 39 if (ext < 0) { 40 increment = -increment; 41 cv = -cv; 42 } 43 } else { 44 arcSegs = (int) Math.ceil(Math.abs(ext) / 90.0); 45 this.increment = Math.toRadians(ext / arcSegs); 46 this.cv = btan(increment); 47 if (cv == 0) { 48 arcSegs = 0; 49 } 50 } 51 switch (a.getArcType()) { 52 case Arc2D.OPEN: 53 lineSegs = 0; 54 break; 55 case Arc2D.CHORD: 56 lineSegs = 1; 57 break; 58 case Arc2D.PIE: 59 lineSegs = 2; 60 break; 61 } 62 if (w < 0 || h < 0) { 63 arcSegs = lineSegs = -1; 64 } 65 } 66 67 73 public int getWindingRule() { 74 return WIND_NON_ZERO; 75 } 76 77 81 public boolean isDone() { 82 return index > arcSegs + lineSegs; 83 } 84 85 90 public void next() { 91 index++; 92 } 93 94 171 private static double btan(double increment) { 172 increment /= 2.0; 173 return 4.0 / 3.0 * Math.sin(increment) / (1.0 + Math.cos(increment)); 174 } 175 176 194 public int currentSegment(float[] coords) { 195 if (isDone()) { 196 throw new NoSuchElementException("arc iterator out of bounds"); 197 } 198 double angle = angStRad; 199 if (index == 0) { 200 coords[0] = (float) (x + Math.cos(angle) * w); 201 coords[1] = (float) (y + Math.sin(angle) * h); 202 if (affine != null) { 203 affine.transform(coords, 0, coords, 0, 1); 204 } 205 return SEG_MOVETO; 206 } 207 if (index > arcSegs) { 208 if (index == arcSegs + lineSegs) { 209 return SEG_CLOSE; 210 } 211 coords[0] = (float) x; 212 coords[1] = (float) y; 213 if (affine != null) { 214 affine.transform(coords, 0, coords, 0, 1); 215 } 216 return SEG_LINETO; 217 } 218 angle += increment * (index - 1); 219 double relx = Math.cos(angle); 220 double rely = Math.sin(angle); 221 coords[0] = (float) (x + (relx - cv * rely) * w); 222 coords[1] = (float) (y + (rely + cv * relx) * h); 223 angle += increment; 224 relx = Math.cos(angle); 225 rely = Math.sin(angle); 226 coords[2] = (float) (x + (relx + cv * rely) * w); 227 coords[3] = (float) (y + (rely - cv * relx) * h); 228 coords[4] = (float) (x + relx * w); 229 coords[5] = (float) (y + rely * h); 230 if (affine != null) { 231 affine.transform(coords, 0, coords, 0, 3); 232 } 233 return SEG_CUBICTO; 234 } 235 236 254 public int currentSegment(double[] coords) { 255 if (isDone()) { 256 throw new NoSuchElementException("arc iterator out of bounds"); 257 } 258 double angle = angStRad; 259 if (index == 0) { 260 coords[0] = x + Math.cos(angle) * w; 261 coords[1] = y + Math.sin(angle) * h; 262 if (affine != null) { 263 affine.transform(coords, 0, coords, 0, 1); 264 } 265 return SEG_MOVETO; 266 } 267 if (index > arcSegs) { 268 if (index == arcSegs + lineSegs) { 269 return SEG_CLOSE; 270 } 271 coords[0] = x; 272 coords[1] = y; 273 if (affine != null) { 274 affine.transform(coords, 0, coords, 0, 1); 275 } 276 return SEG_LINETO; 277 } 278 angle += increment * (index - 1); 279 double relx = Math.cos(angle); 280 double rely = Math.sin(angle); 281 coords[0] = x + (relx - cv * rely) * w; 282 coords[1] = y + (rely + cv * relx) * h; 283 angle += increment; 284 relx = Math.cos(angle); 285 rely = Math.sin(angle); 286 coords[2] = x + (relx + cv * rely) * w; 287 coords[3] = y + (rely - cv * relx) * h; 288 coords[4] = x + relx * w; 289 coords[5] = y + rely * h; 290 if (affine != null) { 291 affine.transform(coords, 0, coords, 0, 3); 292 } 293 return SEG_CUBICTO; 294 } 295 } 296 | Popular Tags |