package org.geogebra.common.euclidian.modes; import java.util.ArrayList; import org.geogebra.common.awt.GColor; import org.geogebra.common.awt.GEllipse2DDouble; import org.geogebra.common.awt.GGeneralPath; import org.geogebra.common.awt.GLine2D; import org.geogebra.common.awt.GPoint; import org.geogebra.common.awt.GRectangle; import org.geogebra.common.euclidian.EuclidianConstants; import org.geogebra.common.euclidian.EuclidianController; import org.geogebra.common.euclidian.EuclidianView; import org.geogebra.common.euclidian.event.AbstractEvent; import org.geogebra.common.factories.AwtFactory; import org.geogebra.common.kernel.algos.AlgoElement; import org.geogebra.common.kernel.algos.AlgoJoinPointsSegment; import org.geogebra.common.kernel.algos.AlgoPolygon; import org.geogebra.common.kernel.arithmetic.Equation; import org.geogebra.common.kernel.arithmetic.ExpressionNode; import org.geogebra.common.kernel.arithmetic.FunctionVariable; import org.geogebra.common.kernel.geos.GeoConic; import org.geogebra.common.kernel.geos.GeoElement; import org.geogebra.common.kernel.geos.GeoPoint; import org.geogebra.common.kernel.geos.GeoPolygon; import org.geogebra.common.kernel.geos.GeoSegment; import org.geogebra.common.kernel.kernelND.GeoPointND; import org.geogebra.common.kernel.kernelND.GeoSegmentND; import org.geogebra.common.plugin.Operation; /** * @author csilla * * mouse handlers for shape tools */ public class ModeShape { private EuclidianView view; private EuclidianController ec; /** * start point of dragging movement */ protected final GPoint dragStartPoint = new GPoint(); private boolean dragPointSet = false; private boolean moveEnded = false; private boolean wasDragged = false; /** * preview for ShapeRectangle/ShapeRectangleRoundEdges/ShapeSquare */ protected GRectangle rectangle = AwtFactory.getPrototype().newRectangle(0, 0); /** * preview for ShapeEllipse/ShapeCircle */ protected GEllipse2DDouble ellipse = AwtFactory.getPrototype() .newEllipse2DDouble(0, 0, 0, 0); /** * preview for ShapeLine */ protected GLine2D line = AwtFactory.getPrototype().newLine2D(); /** * preview for ShapeTriangle */ protected GGeneralPath polygon = AwtFactory.getPrototype() .newGeneralPath(); private AlgoElement algo = null; private ArrayList<GPoint> pointListFreePoly = new ArrayList<GPoint>(); /** * @param view * - euclidianView */ public ModeShape(EuclidianView view) { this.ec = view.getEuclidianController(); this.view = view; } /** * @return true if dragStartPoint is set */ public boolean isDragStartPointSet() { return dragPointSet; } /** * @param isSet * - false if we want to ignore that dragPoit was set */ public void setDragStartPointSet(boolean isSet) { dragPointSet = isSet; } /** * if tool was changed clear data points */ public void clearPointList() { pointListFreePoly.clear(); } /** * get start point of dragging * * @param event * - mouse event */ public void handleMousePressedForShapeMode(AbstractEvent event) { moveEnded = true; if (!dragPointSet || (pointListFreePoly.isEmpty() && ec.getMode() == EuclidianConstants.MODE_SHAPE_FREEFORM)) { dragStartPoint.setLocation(event.getX(), event.getY()); view.setBoundingBox(null); pointListFreePoly.clear(); pointListFreePoly.add(new GPoint(event.getX(), event.getY())); dragPointSet = true; return; } if (ec.getMode() == EuclidianConstants.MODE_SHAPE_FREEFORM) { if (pointListFreePoly.get(0) .distance(new GPoint(event.getX(), event.getY())) < 15 && pointListFreePoly.size() > 1) { pointListFreePoly.add(pointListFreePoly.get(0)); pointListFreePoly.add(pointListFreePoly.get(0)); } else { pointListFreePoly.add(new GPoint(event.getX(), event.getY())); } } } /** * draw shape preview for mouse dragging * * @param event * - mouse event */ public void handleMouseDraggedForShapeMode(AbstractEvent event) { wasDragged = true; if (ec.getMode() != EuclidianConstants.MODE_SHAPE_FREEFORM) { dragPointSet = false; } if (ec.getMode() == EuclidianConstants.MODE_SHAPE_RECTANGLE || ec .getMode() == EuclidianConstants.MODE_SHAPE_RECTANGLE_ROUND_EDGES) { updateRectangle(event, false); if (ec.getMode() == EuclidianConstants.MODE_SHAPE_RECTANGLE_ROUND_EDGES) { view.setRounded(true); } else { view.setRounded(false); } view.setShapeRectangle(rectangle); view.repaintView(); } else if (ec.getMode() == EuclidianConstants.MODE_SHAPE_SQUARE) { updateRectangle(event, true); view.setRounded(false); view.setShapeRectangle(rectangle); view.repaintView(); } else if (ec.getMode() == EuclidianConstants.MODE_SHAPE_ELLIPSE || ec.getMode() == EuclidianConstants.MODE_SHAPE_CIRCLE) { if (ec.getMode() == EuclidianConstants.MODE_SHAPE_ELLIPSE) { updateEllipse(event, false); } else { updateEllipse(event, true); } view.setShapeEllipse(ellipse); view.repaintView(); } else if (ec.getMode() == EuclidianConstants.MODE_SHAPE_LINE) { line.setLine(dragStartPoint.getX(), dragStartPoint.getY(), event.getX(), event.getY()); view.setShapeLine(line); view.repaintView(); } else if (ec.getMode() == EuclidianConstants.MODE_SHAPE_TRIANGLE) { updateTriangle(event); view.setShapePolygon(polygon); view.repaintView(); } else if (ec.getMode() == EuclidianConstants.MODE_SHAPE_POLYGON) { updateRegularPolygon(event); view.setShapePolygon(polygon); view.repaintView(); } else if (ec.getMode() == EuclidianConstants.MODE_SHAPE_FREEFORM) { updateFreeFormPolygon(event, wasDragged); } } /** * array of points of shape * * @param event * - mouse event * @param isSquare * - true if we have square */ private GeoPointND[] getPointArray(AbstractEvent event, boolean isSquare) { GeoPointND[] points = new GeoPointND[4]; double startPointX = view.toRealWorldCoordX(dragStartPoint.x); double startPointY = view.toRealWorldCoordY(dragStartPoint.y); double endPointX, endPointY; // for width of square take the width of rectangle if (isSquare) { double[] coords = getEndPointRealCoords(event, true); endPointX = coords[0]; endPointY = coords[1]; } else { endPointX = view.toRealWorldCoordX(event.getX()); endPointY = view.toRealWorldCoordY(event.getY()); } GeoPoint startPoint = new GeoPoint(view.getKernel().getConstruction(), null, startPointX, startPointY, 1); startPoint.setEuclidianVisible(false); startPoint.updateRepaint(); points[0] = startPoint; GeoPoint leftPoint = new GeoPoint(view.getKernel().getConstruction(), null, endPointX, startPointY, 1); leftPoint.setEuclidianVisible(false); leftPoint.updateRepaint(); points[1] = leftPoint; GeoPoint endPoint = new GeoPoint(view.getKernel().getConstruction(), null, endPointX, endPointY, 1); endPoint.setEuclidianVisible(false); endPoint.updateRepaint(); points[2] = endPoint; GeoPoint rightPoint = new GeoPoint(view.getKernel().getConstruction(), null, startPointX, endPointY, 1); rightPoint.setEuclidianVisible(false); rightPoint.updateRepaint(); points[3] = rightPoint; view.repaintView(); return points; } private double[] getEndPointRealCoords(AbstractEvent event, boolean isSquare) { double[] coords = new double[2]; if (dragStartPoint.x >= event.getX()) { if (dragStartPoint.y >= event.getY()) { coords[0] = view.toRealWorldCoordX( dragStartPoint.x - (isSquare ? rectangle.getWidth() : ellipse.getBounds().getWidth())); coords[1] = view.toRealWorldCoordY( dragStartPoint.y - (isSquare ? rectangle.getWidth() : ellipse.getBounds().getWidth())); } else { coords[0] = view.toRealWorldCoordX( dragStartPoint.x - (isSquare ? rectangle.getWidth() : ellipse.getBounds().getWidth())); coords[1] = view.toRealWorldCoordY( dragStartPoint.y - (isSquare ? -rectangle.getWidth() : -ellipse.getBounds().getWidth())); } } else { if (dragStartPoint.y >= event.getY()) { coords[0] = view .toRealWorldCoordX( dragStartPoint.x - (isSquare ? -rectangle.getWidth() : -ellipse.getBounds().getWidth())); coords[1] = view .toRealWorldCoordY( dragStartPoint.y - (isSquare ? rectangle.getWidth() : ellipse.getBounds() .getWidth())); } else { coords[0] = view .toRealWorldCoordX( dragStartPoint.x + (isSquare ? rectangle.getWidth() : ellipse.getBounds().getWidth())); coords[1] = view .toRealWorldCoordY( dragStartPoint.y + (isSquare ? rectangle.getWidth() : ellipse.getBounds().getWidth())); } } return coords; } /** * with mouse release create geoElement * * @param event * - mouse event * @return geo was created */ public GeoElement handleMouseReleasedForShapeMode(AbstractEvent event) { view.setRounded(false); // make sure we set new start point after ignoring simple click if (ec.getMode() != EuclidianConstants.MODE_SHAPE_FREEFORM && !wasDragged) { dragPointSet = false; return null; } if (ec.getMode() == EuclidianConstants.MODE_SHAPE_RECTANGLE || ec .getMode() == EuclidianConstants.MODE_SHAPE_RECTANGLE_ROUND_EDGES || ec.getMode() == EuclidianConstants.MODE_SHAPE_SQUARE) { if (ec.getMode() == EuclidianConstants.MODE_SHAPE_SQUARE) { algo = new AlgoPolygon(view.getKernel().getConstruction(), null, getPointArray(event, true), false); } else { algo = new AlgoPolygon( view.getKernel().getConstruction(), null, getPointArray(event,false), false); } createPolygon(algo); view.setShapeRectangle(null); view.repaintView(); wasDragged = false; return algo.getOutput(0); } else if (ec.getMode() == EuclidianConstants.MODE_SHAPE_ELLIPSE || ec.getMode() == EuclidianConstants.MODE_SHAPE_CIRCLE) { Equation conicEqu; if (ec.getMode() == EuclidianConstants.MODE_SHAPE_ELLIPSE) { conicEqu = getEquationOfConic(event, false); } else { conicEqu = getEquationOfConic(event, true); } conicEqu.initEquation(); GeoElement[] geos = view.getKernel().getAlgebraProcessor() .processConic(conicEqu, conicEqu.wrap()); geos[0].setLabelVisible(false); ((GeoConic) geos[0]).setIsShape(true); geos[0].updateRepaint(); view.setShapeEllipse(null); view.repaintView(); wasDragged = false; return geos[0]; } else if (ec.getMode() == EuclidianConstants.MODE_SHAPE_LINE) { GeoPoint[] points = getRealPointsOfLine(event); algo = new AlgoJoinPointsSegment(view.getKernel().getConstruction(), null, points[0], points[1]); GeoElement segment = algo.getOutput(0); segment.setLabelVisible(false); ((GeoSegment) segment).setIsShape(true); segment.updateRepaint(); view.setShapeLine(null); view.repaintView(); wasDragged = false; return segment; } else if (ec.getMode() == EuclidianConstants.MODE_SHAPE_TRIANGLE || ec.getMode() == EuclidianConstants.MODE_SHAPE_POLYGON) { GeoPoint[] points = null; if (ec.getMode() == EuclidianConstants.MODE_SHAPE_TRIANGLE) { points = getRealPointsOfTriangle(event); } else { points = getRealPointsOfPolygon(event); } algo = new AlgoPolygon(view.getKernel().getConstruction(), null, points, false); // do not show edge points for (GeoPoint geoPoint : points) { geoPoint.setEuclidianVisible(false); geoPoint.updateRepaint(); } createPolygon(algo); view.setShapePolygon(null); view.repaintView(); wasDragged = false; return algo.getOutput(0); } else if (ec.getMode() == EuclidianConstants.MODE_SHAPE_FREEFORM) { if (wasDragged) { if (pointListFreePoly.size() > 1 && pointListFreePoly.get(0).distance( new GPoint(event.getX(), event.getY())) < 15) { pointListFreePoly.add(pointListFreePoly.get(0)); pointListFreePoly.add(pointListFreePoly.get(0)); } else { pointListFreePoly .add(new GPoint(event.getX(), event.getY())); } } updateFreeFormPolygon(event, false); // close with double click if (pointListFreePoly.size() > 2 && pointListFreePoly.get(pointListFreePoly.size() - 1) .distance( pointListFreePoly.get( pointListFreePoly.size() - 2)) == 0) { // polygon.closePath(); algo = new AlgoPolygon(view.getKernel().getConstruction(), null, getRealPointsOfFreeFormPolygon(), false); createPolygon(algo); pointListFreePoly.clear(); dragPointSet = false; polygon.reset(); view.setShapePolygon(null); view.repaintView(); return algo.getOutput(0); } } // if was drag finished with release wasDragged = false; return null; } private static void createPolygon(AlgoElement algo) { GeoPolygon poly = (GeoPolygon) algo.getOutput(0); // do not show segment labels hideSegments(poly); poly.setIsShape(true); poly.setLabelVisible(false); poly.setAlphaValue(0); poly.setBackgroundColor(GColor.WHITE); poly.setObjColor(GColor.BLACK); poly.updateRepaint(); } /** * needed only for free form polygon * * @param event * - mouse event */ public void handleMouseMoveForShapeMode(AbstractEvent event) { if (ec.getMode() == EuclidianConstants.MODE_SHAPE_FREEFORM) { if (dragPointSet) { if (moveEnded) { polygon.lineTo(event.getX(), event.getY()); moveEnded = false; } else { if (pointListFreePoly.isEmpty()) { return; } polygon.reset(); polygon.moveTo(pointListFreePoly.get(0).x, pointListFreePoly.get(0).y); for (int index = 1; index < pointListFreePoly .size(); index++) { polygon.lineTo(pointListFreePoly.get(index).x, pointListFreePoly.get(index).y); } polygon.lineTo(event.getX(), event.getY()); } view.setShapePolygon(polygon); view.repaintView(); } } } private static void hideSegments(GeoPolygon poly) { for (GeoSegmentND geoSeg : poly.getSegments()) { ((GeoSegment) geoSeg).setLabelVisible(false); ((GeoSegment) geoSeg).setSelectionAllowed(false); } } private GeoPoint[] getRealPointsOfFreeFormPolygon() { pointListFreePoly.remove(pointListFreePoly.size() - 1); GeoPoint[] realPoints = new GeoPoint[pointListFreePoly.size()]; int i = 0; for (GPoint gPoint : pointListFreePoly) { realPoints[i] = new GeoPoint(view.getKernel().getConstruction(), null, view.toRealWorldCoordX(gPoint.getX()), view.toRealWorldCoordY(gPoint.getY()), 1); realPoints[i].setEuclidianVisible(false); realPoints[i].updateRepaint(); i++; } return realPoints; } private GeoPoint[] getRealPointsOfPolygon(AbstractEvent event) { GeoPoint[] points = new GeoPoint[5]; int pointsX[]; int pointsY[]; int height = event.getY() - dragStartPoint.y; int radius = event.getY() - (dragStartPoint.y + event.getY()) / 2; if (height >= 0) { pointsX = getXCoordinates((dragStartPoint.x + event.getX()) / 2, radius, 5, -Math.PI / 2); pointsY = getYCoordinates((dragStartPoint.y + event.getY()) / 2, radius, 5, -Math.PI / 2); for (int i = 0; i < pointsX.length; i++) { points[i] = new GeoPoint(view.getKernel().getConstruction(), null, view.toRealWorldCoordX(pointsX[i]), view.toRealWorldCoordY(pointsY[i]), 1); } } else { pointsX = getXCoordinates((dragStartPoint.x + event.getX()) / 2, radius, 5, Math.PI / 2); pointsY = getYCoordinates((dragStartPoint.y + event.getY()) / 2, radius, 5, Math.PI / 2); for (int i = 0; i < pointsX.length; i++) { points[i] = new GeoPoint(view.getKernel().getConstruction(), null, view.toRealWorldCoordX(pointsX[i]), view.toRealWorldCoordY(pointsY[i]), 1); } } return points; } private GeoPoint[] getRealPointsOfTriangle(AbstractEvent event) { GeoPoint[] points = new GeoPoint[3]; int height = event.getY() - dragStartPoint.y; if (height >= 0) { points[0] = new GeoPoint(view.getKernel().getConstruction(), null, view.toRealWorldCoordX(dragStartPoint.x), view.toRealWorldCoordY(event.getY()), 1); points[1] = new GeoPoint(view.getKernel().getConstruction(), null, view.toRealWorldCoordX(event.getX()), view.toRealWorldCoordY(event.getY()), 1); points[2] = new GeoPoint(view.getKernel().getConstruction(), null, view.toRealWorldCoordX( (dragStartPoint.x + event.getX()) / 2.0), view.toRealWorldCoordY(dragStartPoint.y), 1); } else { points[0] = new GeoPoint(view.getKernel().getConstruction(), null, view.toRealWorldCoordX( (dragStartPoint.x + event.getX()) / 2.0), view.toRealWorldCoordY(event.getY()), 1); points[1] = new GeoPoint(view.getKernel().getConstruction(), null, view.toRealWorldCoordX(dragStartPoint.x), view.toRealWorldCoordY(dragStartPoint.y), 1); points[2] = new GeoPoint(view.getKernel().getConstruction(), null, view.toRealWorldCoordX(event.getX()), view.toRealWorldCoordY(dragStartPoint.y), 1); } return points; } private GeoPoint[] getRealPointsOfLine(AbstractEvent event) { GeoPoint[] points = new GeoPoint[2]; double startX = view.toRealWorldCoordX(dragStartPoint.getX()); double startY = view.toRealWorldCoordY(dragStartPoint.getY()); GeoPoint startPoint = new GeoPoint(view.getKernel().getConstruction(), null, startX, startY, 1); startPoint.setEuclidianVisible(false); startPoint.updateRepaint(); double endX = view.toRealWorldCoordX(event.getX()); double endY = view.toRealWorldCoordY(event.getY()); GeoPoint endPoint = new GeoPoint(view.getKernel().getConstruction(), null, endX, endY, 1); endPoint.setEuclidianVisible(false); endPoint.updateRepaint(); points[0] = startPoint; points[1] = endPoint; return points; } private Equation getEquationOfConic(AbstractEvent event, boolean isCircle) { // real coords double startX = view.toRealWorldCoordX(dragStartPoint.x); double startY = view.toRealWorldCoordY(dragStartPoint.y); double endX, endY; if (isCircle) { double[] coords = getEndPointRealCoords(event, false); endX = coords[0]; endY = coords[1]; } else { endX = view.toRealWorldCoordX(event.getX()); endY = view.toRealWorldCoordY(event.getY()); } // coords of center double centerX = (startX + endX) / 2; double centerY = (startY + endY) / 2; // minor and major axis double a = Math.hypot(centerX - centerX, centerY - endY); double b = Math.hypot(centerX - endX, centerY - centerY); // construct equation (x-center_x)^2 / b^2 + (y-center_y)^2 / a^2 = 1 FunctionVariable xx = new FunctionVariable(view.getKernel(), "x"); FunctionVariable yy = new FunctionVariable(view.getKernel(), "y"); ExpressionNode rhs = new ExpressionNode(view.getKernel(), 1); ExpressionNode expCenterX = new ExpressionNode(view.getKernel(), centerX); ExpressionNode expCenterY = new ExpressionNode(view.getKernel(), centerY); ExpressionNode expA = new ExpressionNode(view.getKernel(), a); ExpressionNode expB = new ExpressionNode(view.getKernel(), b); ExpressionNode leftNumerator = new ExpressionNode(view.getKernel(), xx, Operation.MINUS, expCenterX); ExpressionNode leftNumeratorSqr = new ExpressionNode(view.getKernel(), leftNumerator, Operation.POWER, new ExpressionNode(view.getKernel(), 2)); ExpressionNode leftDenom = new ExpressionNode(view.getKernel(), expB, Operation.POWER, new ExpressionNode(view.getKernel(), 2)); ExpressionNode leftLhs = new ExpressionNode(view.getKernel(), leftNumeratorSqr, Operation.DIVIDE, leftDenom); ExpressionNode rightNumerator = new ExpressionNode(view.getKernel(), yy, Operation.MINUS, expCenterY); ExpressionNode rightNumeatorSqr = new ExpressionNode(view.getKernel(), rightNumerator, Operation.POWER, new ExpressionNode(view.getKernel(), 2)); ExpressionNode rightDenom = new ExpressionNode(view.getKernel(), expA, Operation.POWER, new ExpressionNode(view.getKernel(), 2)); ExpressionNode rightLhs = new ExpressionNode(view.getKernel(), rightNumeatorSqr, Operation.DIVIDE, rightDenom); ExpressionNode lhs = new ExpressionNode(view.getKernel(), leftLhs, Operation.PLUS, rightLhs); Equation equ = new Equation(view.getKernel(), lhs, rhs); return equ; } /** * update the coords of rectangle * * @param event * - mouse event * @param isSquare * - true if we want square instead of rectangle */ protected void updateRectangle(AbstractEvent event, boolean isSquare) { if (rectangle == null) { rectangle = AwtFactory.getPrototype().newRectangle(); } int dx = event.getX() - dragStartPoint.x; int dy = event.getY() - dragStartPoint.y; int width = dx; int height = dy; if (height >= 0) { if (width >= 0) { rectangle.setLocation(dragStartPoint.x, dragStartPoint.y); if (isSquare) { rectangle.setSize(width, width); } else { rectangle.setSize(width, height); } } else { // width < 0 rectangle.setLocation(dragStartPoint.x + width, dragStartPoint.y); if (isSquare) { rectangle.setSize(-width, -width); } else { rectangle.setSize(-width, height); } } } else { // height < 0 if (width >= 0) { if (isSquare) { rectangle.setLocation(dragStartPoint.x, dragStartPoint.y - width); rectangle.setSize(width, width); } else { rectangle.setLocation(dragStartPoint.x, dragStartPoint.y + height); rectangle.setSize(width, -height); } } else { // width < 0 if (isSquare) { rectangle.setLocation(dragStartPoint.x + width, dragStartPoint.y + width); rectangle.setSize(-width, -width); } else { rectangle.setLocation(dragStartPoint.x + width, dragStartPoint.y + height); rectangle.setSize(-width, -height); } } } } /** * update the coords of ellipse * * @param event * - mouse event * @param isCircle * - true if we want circle instead of ellipse */ protected void updateEllipse(AbstractEvent event, boolean isCircle) { if (ellipse == null) { ellipse = AwtFactory.getPrototype().newEllipse2DDouble(0, 0, 0, 0); } int dx = event.getX() - dragStartPoint.x; int dy = event.getY() - dragStartPoint.y; int width = dx; int height = dy; if (height >= 0) { if (width >= 0) { if (isCircle) { ellipse.setFrame(dragStartPoint.x, dragStartPoint.y, width, width); } else { ellipse.setFrame(dragStartPoint.x, dragStartPoint.y, width, height); } } else { // width < 0 if (isCircle) { ellipse.setFrame(dragStartPoint.x + width, dragStartPoint.y, -width, -width); } else { ellipse.setFrame(dragStartPoint.x + width, dragStartPoint.y, -width, height); } } } else { // height < 0 if (width >= 0) { if (isCircle) { ellipse.setFrame(dragStartPoint.x, dragStartPoint.y - width, width, width); } else { ellipse.setFrame(dragStartPoint.x, dragStartPoint.y + height, width, -height); } } else { // width < 0 if (isCircle) { ellipse.setFrame(dragStartPoint.x + width, dragStartPoint.y + width, -width, -width); } else { ellipse.setFrame(dragStartPoint.x + width, dragStartPoint.y + height, -width, -height); } } } } /** * update the coords of triangle * * @param event * - mouse event */ protected void updateTriangle(AbstractEvent event) { int pointsX[] = new int[3]; int pointsY[] = new int[3]; if (polygon == null) { polygon = AwtFactory.getPrototype().newGeneralPath(); } polygon.reset(); int height = event.getY() - dragStartPoint.y; if (height >= 0) { pointsX[0] = dragStartPoint.x; pointsX[1] = event.getX(); pointsX[2] = Math.round((dragStartPoint.x + event.getX()) / 2.0f); pointsY[0] = event.getY(); pointsY[1] = event.getY(); pointsY[2] = dragStartPoint.y; } else { pointsX[0] = Math.round((dragStartPoint.x + event.getX()) / 2.0f); pointsX[1] = dragStartPoint.x; pointsX[2] = event.getX(); pointsY[0] = event.getY(); pointsY[1] = dragStartPoint.y; pointsY[2] = dragStartPoint.y; } polygon.moveTo(pointsX[0], pointsY[0]); for (int index = 1; index < pointsX.length; index++) { polygon.lineTo(pointsX[index], pointsY[index]); } polygon.closePath(); } /** * update the coords of regular polygon * * @param event * - mouse event */ protected void updateRegularPolygon(AbstractEvent event) { int pointsX[]; int pointsY[]; if (polygon == null) { polygon = AwtFactory.getPrototype().newGeneralPath(); } polygon.reset(); int height = event.getY() - dragStartPoint.y; int radius = event.getY() - (dragStartPoint.y + event.getY()) / 2; if (height >= 0) { pointsX = getXCoordinates((dragStartPoint.x + event.getX()) / 2, radius, 5, -Math.PI / 2); pointsY = getYCoordinates((dragStartPoint.y + event.getY()) / 2, radius, 5, -Math.PI / 2); } else { pointsX = getXCoordinates((dragStartPoint.x + event.getX()) / 2, radius, 5, Math.PI / 2); pointsY = getYCoordinates((dragStartPoint.y + event.getY()) / 2, radius, 5, Math.PI / 2); } polygon.moveTo(pointsX[0], pointsY[0]); for (int index = 1; index < pointsX.length; index++) { polygon.lineTo(pointsX[index], pointsY[index]); } polygon.closePath(); } /** * update coords of free form polygon * * @param event * - mouse event * @param wasDrag * - true if mouse was dragged */ protected void updateFreeFormPolygon(AbstractEvent event, boolean wasDrag) { if (pointListFreePoly.isEmpty()) { return; } polygon.reset(); polygon.moveTo(pointListFreePoly.get(0).x, pointListFreePoly.get(0).y); if (pointListFreePoly.size()<2) { return; } for (int index = 1; index < pointListFreePoly.size(); index++) { polygon.lineTo(pointListFreePoly.get(index).x, pointListFreePoly.get(index).y); } if (wasDrag) { polygon.lineTo(event.getX(), event.getY()); } view.setShapePolygon(polygon); view.repaintView(); } private static int[] getXCoordinates(int centerX, int radius, int vertexNr, double startAngle) { int res[] = new int[vertexNr]; double addAngle = 2 * Math.PI / vertexNr; double angle = startAngle; for (int i = 0; i < vertexNr; i++) { res[i] = (int) Math.round(radius * Math.cos(angle)) + centerX; angle += addAngle; } return res; } private static int[] getYCoordinates(int centerY, int radius, int vertexNr, double startAngle) { int res[] = new int[vertexNr]; double addAngle = 2 * Math.PI / vertexNr; double angle = startAngle; for (int i = 0; i < vertexNr; i++) { res[i] = (int) Math.round(radius * Math.sin(angle)) + centerY; angle += addAngle; } return res; } }