From 197e42a2a0a56b686d6e471d06765655634b72da Mon Sep 17 00:00:00 2001 From: creme332 <65414576+creme332@users.noreply.github.com> Date: Mon, 22 Jul 2024 15:49:28 +0400 Subject: [PATCH] implement shape rotation partially --- .../controller/canvas/CanvasController.java | 2 + .../controller/canvas/transform/Rotator.java | 38 +++++++++++++++++ .../github/creme332/model/ShapeWrapper.java | 41 +++++++++++++++++++ 3 files changed, 81 insertions(+) create mode 100644 src/main/java/com/github/creme332/controller/canvas/transform/Rotator.java diff --git a/src/main/java/com/github/creme332/controller/canvas/CanvasController.java b/src/main/java/com/github/creme332/controller/canvas/CanvasController.java index d208f242..596931a1 100644 --- a/src/main/java/com/github/creme332/controller/canvas/CanvasController.java +++ b/src/main/java/com/github/creme332/controller/canvas/CanvasController.java @@ -34,6 +34,7 @@ import com.github.creme332.controller.canvas.drawing.DrawIrregularPolygon; import com.github.creme332.controller.canvas.drawing.DrawLine; import com.github.creme332.controller.canvas.drawing.DrawRegularPolygon; +import com.github.creme332.controller.canvas.transform.Rotator; import com.github.creme332.controller.canvas.transform.Translator; import com.github.creme332.model.AppState; import com.github.creme332.model.CanvasModel; @@ -77,6 +78,7 @@ public CanvasController(AppState app, Canvas canvas) { // initialize other canvas sub-controllers new Translator(app, canvas); + new Rotator(app, canvas); // when canvas is resized, update dimensions and reset zoom canvas.addComponentListener(new ComponentAdapter() { diff --git a/src/main/java/com/github/creme332/controller/canvas/transform/Rotator.java b/src/main/java/com/github/creme332/controller/canvas/transform/Rotator.java new file mode 100644 index 00000000..e604af09 --- /dev/null +++ b/src/main/java/com/github/creme332/controller/canvas/transform/Rotator.java @@ -0,0 +1,38 @@ +package com.github.creme332.controller.canvas.transform; + +import java.awt.geom.Point2D; + +import com.github.creme332.model.AppState; +import com.github.creme332.model.Mode; +import com.github.creme332.model.ShapeWrapper; +import com.github.creme332.view.Canvas; + +public class Rotator extends AbstractTransformer { + + public Rotator(AppState app, Canvas canvas) { + super(app, canvas); + } + + @Override + public void handleShapeSelection(int shapeIndex) { + // get copy of selected shape + ShapeWrapper selectedWrapperCopy = canvasModel.getShapeManager().getShapes().get(shapeIndex); + + // TODO: Get rotation details + + // perform rotation + selectedWrapperCopy.rotate(30, new Point2D.Double(0, 0)); + + // replace old shape with new one + canvasModel.getShapeManager().editShape(shapeIndex, selectedWrapperCopy); + + // repaint canvas + canvas.repaint(); + } + + @Override + public boolean shouldDraw() { + return getCanvasMode() == Mode.ROTATE_ABOUT_POINT; + } + +} diff --git a/src/main/java/com/github/creme332/model/ShapeWrapper.java b/src/main/java/com/github/creme332/model/ShapeWrapper.java index 1786424a..26ca0f56 100644 --- a/src/main/java/com/github/creme332/model/ShapeWrapper.java +++ b/src/main/java/com/github/creme332/model/ShapeWrapper.java @@ -130,6 +130,47 @@ public void translate(final Point2D translationVector) { } } + /** + * Rotates shape and plotted points clockwise about a specified point. + * + * @param radAngle the angle of rotation in radians + * @param pivot the x-y coordinates of the rotation point + */ + public void rotate(double radAngle, Point2D pivot) { + AffineTransform transform = new AffineTransform(); + + // Step 1: Translate the shape to the origin (negative of the rotation point) + transform.translate(pivot.getX(), pivot.getY()); + + // Step 2: Rotate the shape + transform.rotate(radAngle); + + // Step 3: Translate the shape back to its original position + transform.translate(-pivot.getX(), -pivot.getY()); + + final Shape oldShape = shape; + Shape transformedShape; + + if (oldShape instanceof Polygon) { + // if selected shape is of type polygon, ensure that the transformed shape is of + // type Polygon as well + transformedShape = PolygonCalculator.transformPolygon((Polygon) oldShape, + transform); + } else { + transformedShape = transform.createTransformedShape(oldShape); + } + + // replace old shape with transformed shape + setShape(transformedShape); + + // rotate plotted points + for (int i = 0; i < plottedPoints.size(); i++) { + Point2D oldPoint = plottedPoints.get(i); + Point2D rotatedPoint = PolygonCalculator.rotatePointAboutPivot(oldPoint, pivot, radAngle); + plottedPoints.set(i, rotatedPoint); + } + } + public Shape getShape() { return shape; }