繁体   English   中英

自定义形状旋转问题

[英]custom shape rotation issue

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

我想要的是

* 形状应绕其中心旋转而不移动。 *

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

我有多个形状,所以我创建了一个类来封装形状,并在后续类中对其进行转换

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;
    }

在画布鼠标侦听器的鼠标按下事件中

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

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

在画布鼠标侦听器的鼠标拖动方法中,我只是调用所选形状的onMouseDrag方法,该方法将更新旋转角度,如您在第一类中看到的那样

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

并且您可以看到单个形状的draw方法,根据当前变换绘制形状,我从paintComponent像

Iterator<Shoe> shoeIter = shoeShapeMap.values().iterator();

        while (shoeIter.hasNext()) {

            Shoe shoe = shoeIter.next();
            shoe.draw(g2, firstTime);

        }

shoeShapeMap包含当前画布上的所有自定义形状。

我在计算角度或确定锚点时做错了吗? 我当前的解决方案通过检查所有条件(90度等)将形状旋转360度,如您在上述方法中所见。

我希望形状应绕其中心旋转而不调整其位置? 一句话很难解释,所以请建议我一些更好的方法来说明我要完成的工作?

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

我在这里找到2条相关的帖子,但是我从他们那里找不到很多信息。

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

  • 反转AffineTransform上的操作顺序,旋转后放入平移
  • 使用-x和-y作为您的翻译值

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM