I am developing an application which draws various shapes on a canvas and fills them with color; simply a painting application using java. I have implemented rectangular selection and filling the shapes. What I want more is, to draw an irregular shape i.e. shape with some curved surfaces, and to fill it with color.
The basic flow for drawing a shape is; first, an outline is drawn using mouse, and once the path is closed, the shapes can be resized by dragging end points. Then, it can be filled with a default color (GRAY) upon clicking a 'Done' button.
Regarding the curve surfaces, I succeeded on drawing outline with curved surfaces, though some bugs are there. Now once I click the 'Done' button, undesired shape(s) gets drawn. Actually, I wanted to fill the inner part of the outline with color, no matter how the outline looks.
Code for drawing curve with the help of control points.
public static Path2D.Double createPathWithCurve(ArrayList<EndPointRect> endPoints, ArrayList<MidPointRect> midPoints, MidPointRect midPoint, Point curPoint) {
Path2D.Double path = new Path2D.Double();
Point start = midPoint.getStart();
Point end = midPoint.getEnd();
int x[] = Utility.fetchArrayOfXFromPoint(endPoints);
int y[] = Utility.fetchArrayOfYFromPoint(endPoints);
for(int i = 0; i < x.length; i++) {
MidPointRect mp = hasCurve(new Point(x[i], y[i]), midPoints);
if(i == 0) {
path.moveTo(x[i], y[i]); // Moves drawer to first point
if(x[i] == start.getX() && y[i] == start.getY()) {
path.curveTo(start.getX(), start.getY(),
curPoint.getX(), curPoint.getY(),
end.getX(), end.getY());
midPoint.setXy(curPoint);
midPoint.setControlPoint(curPoint);
}
else if(mp != null)
path.curveTo(mp.getStart().getX(), mp.getStart().getY(),
mp.getControlPoint().getX(), mp.getControlPoint().getY(),
mp.getEnd().getX(), mp.getEnd().getY());
}
else if(x[i] == start.getX() && y[i] == start.getY()) {
path.lineTo(x[i], y[i]);
path.moveTo(start.getX(), start.getY());
path.curveTo(start.getX(), start.getY(),
curPoint.getX(), curPoint.getY(),
end.getX(), end.getY());
path.moveTo(end.getX(), end.getY());
midPoint.setXy(curPoint);
midPoint.setControlPoint(curPoint);
}
else {
if(mp != null) {
path.lineTo(x[i], y[i]);
path.moveTo(mp.getStart().getX(), mp.getStart().getY());
path.curveTo(mp.getStart().getX(), mp.getStart().getY(),
mp.getControlPoint().getX(), mp.getControlPoint().getY(),
mp.getEnd().getX(), mp.getEnd().getY());
path.moveTo(mp.getEnd().getX(), mp.getEnd().getY());
}
else
path.lineTo(x[i], y[i]);
}
if((i+1) == x.length) {
path.lineTo(x[0], y[0]); // Draws line from last point to first point
//path.closePath();
}
}
return path;
}
'Done' button click method and custom curve class:
public void doneButtonCalled() {
if (!tempRectList.isEmpty()) {
CustomCurve area = createCurveFromPoints(getCurrentShape(), getTempRectList());
repaint();
} }
public CustomCurve createCurveFromPoints(Path2D.Double shape, ArrayList<EndPointRect> points) {
int x[] = Utility.fetchArrayOfXFromPoint(points);
int y[] = Utility.fetchArrayOfYFromPoint(points);
return new CustomCurve(shape, x, y, x.length); }
public class CustomCurve extends Area implements ShapeModel, Serializable {
private Color color;
private int[] xPoints;
private int[] yPoints;
private boolean visible;
public CustomCurve(Path2D.Double shape, int[] xPoints, int[] yPoints, int nPoints) {
super(shape);
this.xPoints = xPoints;
this.yPoints = yPoints;
this.color = Color.darkGray;
visible = true;
}
/* setters and getters */ }