* @param clip - the MultiRectArea object of clipping area
* @return a MultiRectArea of rasterizer arc
*/
public static MultiRectArea rasterize(int x, int y, int width, int height, double angleStart, double angleExtent, MultiRectArea clip) {
MultiRectArea mra = new MultiRectArea(false);
int cx1, cx2, cy1, cy2;
cx1 = cx2 = x + width / 2;
cy1 = cy2 = y + height / 2;
if (width % 2 == 0) {
cx2--;
}
if (height % 2 == 0) {
cy2--;
}
int a = width / 2;
int b = height / 2;
double c = Math.sqrt(a * a + b * b);
int xcount, ycount;
if (a < b) {
xcount = (int)Math.ceil(a * a / c);
ycount = (int)Math.floor(b * b / c);
} else {
xcount = (int)Math.floor(a * a / c);
ycount = (int)Math.ceil(b * b / c);
}
int[] xline = createLine(a, b, xcount, ycount);
int[] yline = createLine(b, a, ycount, xcount);
// Correct lines
int i = xline.length;
while(xline[--i] > xcount) {
xline[i] = xcount;
}
i = yline.length;
while(yline[--i] > ycount) {
yline[i] = ycount;
}
if (Math.abs(angleExtent) >= 360) {
// Rasterize CIRCLE
addX0Line(mra, xline, cx2, cy2, b);
addX1Line(mra, xline, cx2, cy1, b);
addX2Line(mra, xline, cx1, cy1, b);
addX3Line(mra, xline, cx1, cy2, b);
addY0Line(mra, yline, cx2, cy2, a);
addY1Line(mra, yline, cx1, cy2, a);
addY2Line(mra, yline, cx1, cy1, a);
addY3Line(mra, yline, cx2, cy1, a);
} else {
// Rasterize ARC
angleStart = getNormAngle(angleStart);
double angleFinish = getNormAngle(angleStart + angleExtent);
if (angleExtent < 0) {
double tmp = angleStart;
angleStart = angleFinish;
angleFinish = tmp;
}
double radStart = -Math.toRadians(angleStart);
double radFinish = -Math.toRadians(angleFinish);
int ax1 = (int)(a * Math.cos(radStart));
int ay1 = (int)(b * Math.sin(radStart));
int ax2 = (int)(a * Math.cos(radFinish));
int ay2 = (int)(b * Math.sin(radFinish));
int[] seg1 = getSegment1(angleStart, ax1, ay1, xcount, ycount);
int[] seg2 = getSegment2(angleFinish, ax2, ay2, xcount, ycount);
// Start and Finish located in the same quater
if (angleStart < angleFinish && seg1[0] == seg2[0]) {
if (seg1[0] % 2 == 0) {
seg1[2] = seg2[2];
} else {
seg1[1] = seg2[1];
}
addSeg(mra, cx1, cy1, cx2, cy2, a, b, xline, yline, seg1);
return mra;
}
addSeg(mra, cx1, cy1, cx2, cy2, a, b, xline, yline, seg1);
addSeg(mra, cx1, cy1, cx2, cy2, a, b, xline, yline, seg2);
int startSeg = (seg1[0] + 1) % 8;
int finishSeg = seg2[0];
while (startSeg != finishSeg) {
switch(startSeg) {
case 0:
addY3Line(mra, yline, cx2, cy1, a);
break;
case 1:
addX1Line(mra, xline, cx2, cy1, b);
break;
case 2:
addX2Line(mra, xline, cx1, cy1, b);
break;
case 3:
addY2Line(mra, yline, cx1, cy1, a);
break;
case 4:
addY1Line(mra, yline, cx1, cy2, a);
break;
case 5:
addX3Line(mra, xline, cx1, cy2, b);
break;
case 6:
addX0Line(mra, xline, cx2, cy2, b);
break;
case 7:
addY0Line(mra, yline, cx2, cy2, a);
break;
}
startSeg = (startSeg + 1) % 8;
}
}
if (clip != null) {
mra.intersect(clip);
}
return mra;
}