【问题标题】:how to rotate a circle around it's axis i9n java2D如何围绕它的轴旋转一个圆圈i9n java2D
【发布时间】:2021-11-11 08:29:13
【问题描述】:

所以我刚刚了解了 java 2D 中的仿射变换以及每个变换的行为方式。所以我作为一个辅助项目尝试的是创建一个围绕它的轴程序旋转的圆圈,我尝试先翻译到 (0,0) 然后旋转一个度然后平移回初始位置,通过 360 次迭代以 1 度增量但圆仍然旋转出该中心点(尽管它在最后一次迭代时回到其原始点)。 以下是迄今为止所做的:

public void paint(Graphics g)
  {
    Graphics2D g2d = (Graphics2D) g;

    //Use of antialiasing to have nicer lines.
    g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);

    //The lines should have a thickness of 3.0 instead of 1.0.
    BasicStroke bs = new BasicStroke(3.0f);
    g2d.setStroke(bs);

    //The GeneralPath to decribe the car.
    //GeneralPath gp = new GeneralPath();

    //Start at the lower front of the car.
    g2d.setPaint(new Color(110, 100, 0));

    RenderingHints rh = new RenderingHints(
            RenderingHints.KEY_ANTIALIASING,
            RenderingHints.VALUE_ANTIALIAS_ON);

    //Draw the car.
    
    //g2d.fillOval(215, 135, 50, 50);
    Shape s = new Ellipse2D.Double(160,160,40,40);
    sustain(1000);
    for(int i=0;i<360;i++) {
        AffineTransform rotation = new AffineTransform();
        rotation.setToRotation(Math.PI/180+i);
        AffineTransform translate = new AffineTransform();
        translate.setToTranslation(-160, -160);
        AffineTransform translate2 = new AffineTransform();
        translate2.setToTranslation(160, 160);
        rotation.concatenate(translate);
        translate2.concatenate(rotation);
        clearWindow(g2d);
        g2d.setPaint(new Color(110, 100, 0));
        g2d.fill(translate2.createTransformedShape(s));
        
        
    }

【问题讨论】:

  • 你需要记住的一点是,变换是累积的
  • 我需要它围绕它的轴旋转(相对于它自己的中心做圆周运动 - 我不明白。一个围绕它的中心旋转的圆会似乎没有任何运动。或者您是在谈论围绕地球旋转的月亮?我不明白为什么下面的答案没有帮助?

标签: java graphics rotation affinetransform


【解决方案1】:

我花了一些时间重新阅读您的问题并查看您的代码,但我仍然不清楚

  1. 你想做什么和
  2. 你的问题是什么

但是什么时候阻止我玩游戏?

好的,所以这有两个圆圈(相同形状)围绕一个中心点(平移)点。

需要记住的是,变换是累积的,所以你可以看到,在第二个和第三个圆圈之间,我重置了变换(处理图形并拍摄另一个快照),所以我受挑战的可怜的大脑不会完全恢复搞砸了

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.AffineTransform;
import java.awt.geom.Ellipse2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame();
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private int angle = 0;

        public TestPane() {
            Timer timer = new Timer(5, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    angle += 1;
                    repaint();
                }
            });
            timer.start();
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(120, 120);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();

            //Use of antialiasing to have nicer lines.
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

            g2d.drawLine(getWidth() / 2, 0, getWidth() / 2, getHeight());
            g2d.drawLine(0, getHeight() / 2, getWidth(), getHeight() / 2);

            RenderingHints rh = new RenderingHints(
                    RenderingHints.KEY_ANTIALIASING,
                    RenderingHints.VALUE_ANTIALIAS_ON);

            Shape s = new Ellipse2D.Double(0, 0, 40, 40);
            g2d.transform(AffineTransform.getTranslateInstance(40, 40));
            g2d.setPaint(Color.RED);
            g2d.draw(s);
            g2d.transform(AffineTransform.getTranslateInstance(-30, -30));
            g2d.transform(AffineTransform.getRotateInstance(Math.toRadians(angle), 50, 50));
            g2d.setPaint(new Color(110, 100, 0));
            g2d.drawRect(0, 0, 40, 40);
            g2d.draw(s);
            g2d.dispose();

            g2d = (Graphics2D) g.create();
            g2d.transform(AffineTransform.getTranslateInstance(40, 40));
            g2d.transform(AffineTransform.getTranslateInstance(-20, -20));
            g2d.transform(AffineTransform.getRotateInstance(Math.toRadians(angle / 2), 40, 40));
            g2d.setPaint(Color.BLUE);
            g2d.drawRect(0, 0, 40, 40);
            g2d.draw(s);
        }

    }
}

我需要它围绕它的轴旋转(相对于它自己的中心做圆周运动而不改变位置)

好的,还是不清楚。如果您想围绕它的中心点旋转对象,但同时让它移动,那么应用变换的顺序很重要。

例如,我会先平移它的位置,然后旋转它,因为它更容易绕它的中心点旋转而无需计算额外的偏移量

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.AffineTransform;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Path2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame();
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private int angle = 0;
        private Path2D path;

        public TestPane() {

            path = new Path2D.Double();
            path.moveTo(20, 20);
            path.lineTo(0, 20);
            path.append(new Ellipse2D.Double(0, 0, 40, 40), false);

            Timer timer = new Timer(5, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    angle += 1;
                    repaint();
                }
            });
            timer.start();
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(120, 120);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();

            //Use of antialiasing to have nicer lines.
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

            RenderingHints rh = new RenderingHints(
                    RenderingHints.KEY_ANTIALIASING,
                    RenderingHints.VALUE_ANTIALIAS_ON);

            g2d.transform(AffineTransform.getTranslateInstance(40, 40));
            g2d.transform(AffineTransform.getRotateInstance(Math.toRadians(angle), 20, 20));
            g2d.setPaint(Color.RED);
            g2d.draw(path);
            g2d.dispose();
        }

    }
}

此外,您还可以查看How to rotate an object around another moving object in java?

【讨论】:

  • 我真正需要的是对于一个特定的形状,我需要它围绕它的轴旋转(相对于它自己的中心做圆周运动而不改变位置)我的代码所做的是旋转但改变位置,但在所有迭代完成后回到其初始位置,但我希望它有一个固定的旋转运动
猜你喜欢
  • 2019-04-25
  • 2021-07-30
  • 2011-10-13
  • 1970-01-01
  • 2020-10-02
  • 2018-07-01
  • 1970-01-01
  • 2016-12-28
  • 1970-01-01
相关资源
最近更新 更多