自定义形状旋转问题

我试图围绕其中心旋转自定义形状,但无法按预期获得结果。

我想要的是什么

* 形状应围绕其中心旋转而不会自行移动。 *

我的解决方案目前正在做的是围绕其中心旋转整个形状,每次旋转都会改变其位置。

我有多个形状,所以我创建了一个类来封装一个形状,其变换在下面的类中

public abstract class Shoe implements Shape, ShoeShape { // variable declaration /** * */ public Shoe() { position = new Point(); lastPosition = new Point(); } public void draw(Graphics2D g2, AffineTransform transform, boolean firstTime) { AffineTransform af = firstTime ? getInitTransform() : getCompositeTransform(); if (af != null) { Shape s = af.createTransformedShape(this); if (getFillColor() != null) { g2.setColor(getFillColor()); g2.fill(s); } else { g2.draw(s); } } } } public AffineTransform getCompositeTransform() { AffineTransform af = new AffineTransform(); af.setToIdentity(); af.translate(position.getX(), position.getY()); Point2D centerP = calculateShapeCenter(); af.rotate(orientation, centerP.getX(), centerP.getY()); return af; } public void onMouseDrag(MouseEvent me, Rectangle2D canvasBoundary, int selectionOperation) { // shape operation can be either resize , rotate , translate , switch (selectionOperation) { case MmgShoeViewer.SHAPE_OPERATION_MOVE: // MOVEMENT break; case MmgShoeViewer.SHAPE_OPERATION_ROTATE: Point2D origin = calculateShapeCenter(); Point2D.Double starting = new Point2D.Double(me.getX(), me.getY()); currentAngle = RotationHelper.getAngle(origin, starting); rotationAngle = currentAngle - startingAngle; rotate(rotationAngle); break; case MmgShoeViewer.SHAPE_OPERATION_RESIZE: break; default: System.out.println(" invalid select operation"); } } public void onMousePress(MouseEvent me, Rectangle2D canvasBoundary, int selectionOperation) { // shape operation can be either resize , rotate , translate , switch (selectionOperation) { case MmgShoeViewer.SHAPE_OPERATION_MOVE: break; case MmgShoeViewer.SHAPE_OPERATION_ROTATE: Point2D origin = calculateShapeCenter(); Point2D.Double starting = new Point2D.Double(me.getX(), me.getY()); startingAngle = RotationHelper.getAngle(origin, starting); setShapeOperation(selectionOperation); break; case MmgShoeViewer.SHAPE_OPERATION_RESIZE: break; default: System.out.println(" invalid select operation"); } } public void onMouseRelease(MouseEvent me, Rectangle2D canvasBoundary, int selectionOperation) { // shape operation can be either resize , rotate , translate , switch (selectionOperation) { case MmgShoeViewer.SHAPE_OPERATION_MOVE: break; case MmgShoeViewer.SHAPE_OPERATION_ROTATE: // FIXME rotation angle computation setShapeOperation(-1); break; case MmgShoeViewer.SHAPE_OPERATION_RESIZE: break; default: System.out.println(" invalid select operation"); } } public void rotate(double angle) { orientation = (float) angle; } public void translate(double deltaX, double deltaY) { position.setLocation(deltaX, deltaY); lastPosition.setLocation(deltaX, deltaY); } // another getter and setter 

我正在使用以下方法计算旋转角度

 public static double getAngle(Point2D origin, Point2D other) { double dy = other.getY() - origin.getY(); double dx = other.getX() - origin.getX(); double angle; if (dx == 0) {// special case angle = dy >= 0 ? Math.PI / 2 : -Math.PI / 2; } else { angle = Math.atan(dy / dx); if (dx < 0) // hemisphere correction angle += Math.PI; } // all between 0 and 2PI if (angle < 0) // between -PI/2 and 0 angle += 2 * Math.PI; return angle; } 

在canvas鼠标监听器的鼠标按下事件中

 selectedShape.onMousePress(me, canvasBoundary, shoeViewer .getShapeOperation()); 

我只是调用选定形状的onMousePress方法

在我的鼠标拖动方法的canvas鼠标监听器,我只是调用选定的形状的onMouseDrag方法,它更新旋转角度,你可以从第一堂课看到

 selectedShape.onMouseDrag(me, canvasBoundary, shoeViewer .getShapeOperation()); 

你可以看到单个形状的绘制方法,根据当前变换绘制形状,我从paintComponent调用

 Iterator shoeIter = shoeShapeMap.values().iterator(); while (shoeIter.hasNext()) { Shoe shoe = shoeIter.next(); shoe.draw(g2, firstTime); } 

其中shoeShapeMap包含当前在canvas上的所有自定义形状。

我在计算角度或确定锚点时犯了错误吗? 我现在的解决方案通过检查所有条件[90度等]旋转形状360度,如上所述。

我希望形状应围绕其中心旋转而不调整其位置? 在这个词中很难解释,所以请建议我在这里展示我想要完成的任何更好的方法吗?

我想我已经提到了与这个问题有关的所有事情。 如果您有任何疑问,请随时问我。

我在这里发现了2个相关的post,但我找不到他们的大量信息。

我认为解决方案可能是(或/和):

  • 颠倒你的AffineTransform上的操作顺序,旋转后放置翻译
  • 使用-x和-y作为翻译值