diff --git a/src/main/java/com/github/creme332/controller/canvas/drawing/DrawRegularPolygon.java b/src/main/java/com/github/creme332/controller/canvas/drawing/DrawRegularPolygon.java index 03a9610e..8541d52b 100644 --- a/src/main/java/com/github/creme332/controller/canvas/drawing/DrawRegularPolygon.java +++ b/src/main/java/com/github/creme332/controller/canvas/drawing/DrawRegularPolygon.java @@ -26,48 +26,54 @@ public DrawRegularPolygon(AppState app, Canvas canvas) { @Override protected void handleMouseMoved(Point2D polySpaceMousePosition) { - if (preview != null && firstVertex != null && secondVertex != null) { - Polygon polygon = calculator.getPolygonFromTwoPoints(firstVertex, secondVertex, numSides); - preview.setShape(polygon); - canvas.repaint(); - } + // do nothing } @Override protected void handleMousePressed(Point2D polySpaceMousePosition) { if (firstVertex == null) { + // user entered first vertex of polygon firstVertex = polySpaceMousePosition; + + // initialize shape preview + preview = new ShapeWrapper(canvasModel.getShapeColor(), + canvasModel.getLineType(), + canvasModel.getLineThickness()); + + // save first plotted point + preview.getPlottedPoints().add(polySpaceMousePosition); + + // update preview on canvas + canvasModel.getShapeManager().setShapePreview(preview); return; } + if (secondVertex == null) { + // user entered second vertex of polygon secondVertex = polySpaceMousePosition; + // save second plotted point + preview.getPlottedPoints().add(polySpaceMousePosition); + // ask user to enter number of sides numSides = inputVertices(); if (numSides < 3) { // invalid input => reset state and cancel operation - firstVertex = null; - secondVertex = null; disposePreview(); return; } - // initialize shape preview after getting valid input - preview = new ShapeWrapper(canvasModel.getShapeColor(), - canvasModel.getLineType(), - canvasModel.getLineThickness()); - preview.getPlottedPoints().add(firstVertex); - preview.getPlottedPoints().add(secondVertex); + // generate new polygon + Polygon polygon = calculator.getRegularPolygon(firstVertex, secondVertex, numSides); + preview.setShape(polygon); - // save preview - canvasModel.getShapeManager().setShapePreview(preview); + // save shape + canvasModel.getShapeManager().addShape(preview); - Polygon polygon = calculator.getPolygonFromTwoPoints(firstVertex, secondVertex, numSides); - preview.setShape(polygon); canvas.repaint(); - } else { - canvasModel.getShapeManager().addShape(preview); + + // discard preview disposePreview(); } } @@ -81,7 +87,8 @@ protected boolean shouldDraw() { * Asks user to enter number of vertices for polygon. If input value is invalid * or if operation is cancelled, -1 is returned. * - * @return The number of vertices entered by the user or -1 if invalid or cancelled. + * @return The number of vertices entered by the user or -1 if invalid or + * cancelled. */ private int inputVertices() { JTextField numSidesField = new JTextField(5); @@ -104,4 +111,13 @@ private int inputVertices() { } return -1; } + + @Override + public void disposePreview() { + // delete any preview shape + firstVertex = null; + secondVertex = null; + preview = null; + canvasModel.getShapeManager().setShapePreview(preview); + } } diff --git a/src/main/java/com/github/creme332/model/calculator/PolygonCalculator.java b/src/main/java/com/github/creme332/model/calculator/PolygonCalculator.java index 8eaec066..c7038884 100644 --- a/src/main/java/com/github/creme332/model/calculator/PolygonCalculator.java +++ b/src/main/java/com/github/creme332/model/calculator/PolygonCalculator.java @@ -36,7 +36,7 @@ public static Point2D rotateVector(Point2D vector, double radAngle) { * * @param point Point to be rotated. * @param pivot Point about which rotation takes place. - * @param radAngle Rotation angle in radians. + * @param radAngle Anti-clockwise rotation angle in radians. * @return The rotated point as a Point2D. */ public static Point2D rotatePointAboutPivot(Point2D point, Point2D pivot, double radAngle) { @@ -89,27 +89,38 @@ private Shape getRegularPolygon(int sidesCount, int length) { } /** - * Calculates a regular polygon given two adjacent vertices and the number of sides. + * Calculates a regular polygon given two adjacent vertices and the number of + * sides. * - * @param pointA First vertex. - * @param pointB Second vertex (adjacent to the first). + * @param pointA First vertex. + * @param pointB Second vertex (adjacent to the first). * @param sidesCount Number of sides in polygon. * @return The Polygon object representing the regular polygon. */ - private Polygon getRegularPolygon(Point2D pointA, Point2D pointB, int sidesCount) { - double length = pointA.distance(pointB); - double angle = Math.atan2(pointB.getY() - pointA.getY(), pointB.getX() - pointA.getX()); - - Point2D.Double[] points = new Point2D.Double[sidesCount]; + public Polygon getRegularPolygon(Point2D pointA, Point2D pointB, int sidesCount) { + final Point2D.Double[] points = new Point2D.Double[sidesCount]; points[0] = new Point2D.Double(pointA.getX(), pointA.getY()); points[1] = new Point2D.Double(pointB.getX(), pointB.getY()); - final double rotationAngleInRad = Math.toRadians(360.0 / sidesCount); + /** + * Size of 1 interior angle of polygon. + */ + final double interiorAngle = (180 * (sidesCount - 2)) / (double) sidesCount; + + /** + * Anticlockwise rotation angle mapping one edge to another. + */ + final double rotationAngleInRad = Math.toRadians(360 - interiorAngle); for (int i = 2; i < sidesCount; i++) { - points[i] = (Point2D.Double) rotatePointAboutPivot(points[i - 1], points[i - 2], rotationAngleInRad); + Point2D pivot = points[i - 1]; + Point2D vectorStart = points[i - 2]; + + // rotate vector about pivot + points[i] = (Point2D.Double) rotatePointAboutPivot(vectorStart, pivot, rotationAngleInRad); } + /// round off pixel coordinates to the nearest integer int[] x = new int[sidesCount]; int[] y = new int[sidesCount]; for (int i = 0; i < sidesCount; i++) { @@ -147,18 +158,6 @@ public int[][] getOrderedPoints(int sidesCount, int length, int centerX, int cen return new int[][] { xOrdered, yOrdered }; } - /** - * Calculates a regular polygon given two adjacent vertices and the number of sides. - * - * @param pointA First vertex. - * @param pointB Second vertex (adjacent to the first). - * @param sidesCount Number of sides in polygon. - * @return The Polygon object representing the regular polygon. - */ - public Polygon getPolygonFromTwoPoints(Point2D pointA, Point2D pointB, int sidesCount) { - return getRegularPolygon(pointA, pointB, sidesCount); - } - /** * Transforms a polygon using the given affine transformation. *