import java.awt.*; public class PolyBezier { private int numCurves; private boolean closedPoly, smoothePoly; private int offset; // used by initCurves() for where to drop the shape private BezierCurve[] curves; // constructor // nc is used to define how many BezierCurves make up the shape public PolyBezier(int nc, boolean isClosed, boolean isSmooth, int startOffset) { numCurves = nc; curves = new BezierCurve[numCurves]; closedPoly = isClosed; smoothePoly = isSmooth; offset = startOffset; initCurves(); } public void smootheEdges() { int[] otherGuide, pivot; int x, dx, y, dy, curveToSet; for (int i = 0; i < numCurves; i++) { curveToSet = i - 1; //calculate reflection of point 2 on previous curve if (closedPoly || curveToSet > 0) { otherGuide = curves[(numCurves + curveToSet) % numCurves].getPoint(2); pivot = curves[(numCurves + curveToSet) % numCurves].getPoint(3); dx = otherGuide[0] - pivot[0]; dy = otherGuide[1] - pivot[1]; x = pivot[0] - dx; y = pivot[1] - dy; curves[i].setPoint(1, x, y); } } } public int getNumCurves() { return numCurves; } public int[] getPoint(int n) { return curves[n / 4].getPoint(n % 4); } // make the shape closed if it isn't already // effectively, links/unlinks the first point of first curve with last point of last curve public void setClosed(boolean closed) { closedPoly = closed; initCurves(); } public void setSmoothe(boolean smoothe) { smoothePoly = smoothe; } // set point coordinates to (x,y{ // where point describes which point such that // point / 4 = curve containing point // point % 4 = point within curve // // if moves a point common to two curves, makes sure to move for both curves public void setPoint(int point, int x, int y) { int curveToSet = point / 4; int pointToSet = point % 4; int[] origPoint = curves[curveToSet].getPoint(pointToSet); curves[curveToSet].setPoint(pointToSet, x, y); int dx = x - origPoint[0]; int dy = y - origPoint[1]; if (point % 4 == 3) { // moved last point of a curve // set first point of next curve, if it is linked to the one set above if (closedPoly || curveToSet < (numCurves - 2)) { curves[(curveToSet+1) % numCurves].setPoint(0, x, y); } if (smoothePoly) { origPoint = curves[curveToSet].getPoint(2); curves[curveToSet].setPoint(2, origPoint[0] + dx, origPoint[1] + dy); if (closedPoly || curveToSet < (numCurves - 2)) { origPoint = curves[(curveToSet+1) % numCurves].getPoint(1); curves[(curveToSet+1) % numCurves].setPoint(1, origPoint[0] + dx, origPoint[1] + dy); } } } else if (point % 4 == 0) { //moved first point of a curve if (closedPoly || curveToSet > 0) curves[curveToSet - 1].setPoint(3, x, y); if (smoothePoly) { origPoint = curves[curveToSet].getPoint(1); curves[curveToSet].setPoint(1, origPoint[0] + dx, origPoint[1] + dy); if (closedPoly || curveToSet > 0) { origPoint = curves[(numCurves + curveToSet -1) % numCurves].getPoint(2); curves[(numCurves + curveToSet -1) % numCurves].setPoint(2, origPoint[0] + dx, origPoint[1] + dy); } } } else if (point % 4 == 1) { // moved first guide if (smoothePoly && (closedPoly || curveToSet > 0)) { origPoint = curves[(numCurves + curveToSet-1) % numCurves].getPoint(2); curves[(numCurves + curveToSet-1) % numCurves].setPoint(2, origPoint[0] - dx, origPoint[1] - dy); } } else if (point % 4 == 2) { //moved second guide if (smoothePoly && (closedPoly || curveToSet < (numCurves - 1))) { origPoint = curves[(curveToSet+1) % numCurves].getPoint(1); curves[(curveToSet+1) % numCurves].setPoint(1, origPoint[0] - dx, origPoint[1] - dy); } } } // position all points in a circle public void initCurves() { for (int i = 0; i < numCurves; i++) curves[i] = new BezierCurve(); double wedge; if (closedPoly) wedge = 2 * Math.PI / (3 * numCurves); else wedge = 2 * Math.PI / (3 * numCurves + 1); double theta = 0; int r = offset / 2; for (int i = 0; i < numCurves; i++) { curves[i].setPoints( offset + (int)(r * Math.cos(theta)), offset + (int)(r * Math.sin(theta)), offset + (int)(r * Math.cos(theta + wedge)), offset + (int)(r * Math.sin(theta + wedge)), offset + (int)(r * Math.cos(theta + 2 * wedge)), offset + (int)(r * Math.sin(theta + 2 * wedge)), offset + (int)(r * Math.cos(theta + 3 * wedge)), offset + (int)(r * Math.sin(theta + 3 * wedge)) ); theta += 3 * wedge; } } /***************************************** *** MAKE CALLS ON ALL CONTAINED CURVES *** *****************************************/ public void drawCurve(Graphics g) { for (int i = 0; i < numCurves; i++) curves[i].drawCurve(g); } public void drawGuidelines(Graphics g) { for (int i = 0; i < numCurves; i++) curves[i].drawGuidelines(g); } public void drawPoints(Graphics g) { for (int i = 0; i < numCurves; i++) curves[i].drawPoints(g); } public void writeCoordinates(Graphics g) { for (int i = 0; i < numCurves; i++) curves[i].writeCoordinates(g); } }