简体   繁体   English

使用Graphics2D旋转

[英]Rotation with Graphics2D

I am currently experimenting with the Graphics2D and the KeyListener, and I am currently testing out rotating objects (in this case a pentagon). 我目前正在试验Graphics2D和KeyListener,我目前正在测试旋转对象(在这种情况下是五边形)。 Now, it's working in the sense that it rotates, except it is supposed to rotate by 1 radian each time VK_RIGHT or VK_LEFT are pressed. 现在,它在旋转的意义上工作,除了每次按下VK_RIGHT或VK_LEFT时它应该旋转1弧度。

However, currently it does that for the first key press only. 但是,目前它仅用于第一次按键。 From then on, it creates a pattern of rotating it by 1, 2, 3, 4, 5... and so on radians each time (the nth keypress rotates it by nth radians) instead of just 1 radian per keypress. 从那时起,它创建了一个旋转模式的模式,每次旋转1,2,3,4,5 ......等等(第n个按键旋转第n个弧度),而不是每个按键只有1个弧度。

Creating the JFrame: 创建JFrame:

import javax.swing.JFrame;


    public class Main {

        public Main() {
            JFrame window = new JFrame("Rotating Hexagons");
            window.setSize(800,600);
            window.setLocationRelativeTo(null);
            window.setResizable(false);
            window.setContentPane(new RotatingHexagon());
            window.pack();
            window.setVisible(true);
        }

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

    }

RotatingHexagon Class: RotatingHexagon类:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Polygon;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.JPanel;


public class RotatingHexagon extends JPanel implements KeyListener {

    private Polygon poly;

    private int[] xpoints = { 0, -10, -7, 7, 10 };
    private int[] ypoints = { -10, -2, 10, 10, -2 };

    private int rotation = 0;

    public RotatingHexagon() {
        setPreferredSize(new Dimension(800,600));
        setFocusable(true);
        requestFocus();
    }

    public void init() {
        poly = new Polygon(xpoints, ypoints, xpoints.length);

        addKeyListener(this);
    }

    public void paint(Graphics g) {
        init();

        Graphics2D g2d = (Graphics2D) g;

        int width = getSize().width;
        int height = getSize().height;

        g2d.setColor(Color.BLACK);
        g2d.fillRect(0, 0, width, height);

        g2d.setColor(Color.WHITE);
        g2d.drawString(rotation + " radians", 10, 20);

        g2d.translate(width / 2, height / 2);
        g2d.scale(20, 20);
        g2d.rotate(Math.toRadians(rotation));

        g2d.setColor(new Color(255, 100, 100));
        g2d.fill(poly);
        g2d.setColor(Color.WHITE);
        g2d.draw(poly);
    }

    public void keyPressed(KeyEvent k) {
        switch(k.getKeyCode()) {
        case KeyEvent.VK_LEFT:
            rotation--;
            if (rotation < 0) rotation = 359;
            repaint();
            break;
        case KeyEvent.VK_RIGHT:
            rotation++;
            if (rotation > 360) rotation = 0;
            repaint();
            break;
        }
    }

    public void keyReleased(KeyEvent k) {}
    public void keyTyped(KeyEvent k) {}

}

I really don't have any idea why it isn't just rotating 1 radian each time, so any help is appreciated. 我真的不知道为什么它不是每次只旋转1弧度,所以任何帮助都是值得赞赏的。 Thanks. 谢谢。

the reason is calling the init() function in the paint() method again and again. 原因是一次又一次地调用paint()方法中的init()函数。 So the KeyListener is added multiple times, causing that it is called multiple times, incrementing your counter more every time you press the key. 所以KeyListener被多次添加,导致它被多次调用,每次按下键都会增加你的计数器。

Move it to the constructor: 将其移动到构造函数:

public RotatingHexagon() {
    setPreferredSize(new Dimension(800,600));
    setFocusable(true);
    requestFocus();
    addKeyListener(this);
}

public void init() {
    poly = new Polygon(xpoints, ypoints, xpoints.length);        
}

Andy 安迪

You should probally just use a persistant AffineTransform to do the rotation. 你应该只使用持久的AffineTransform进行旋转。 They are a lot more powerfull. 它们更强大。

I also saw several issues in your code, you are calling the init method each frame - this could be 60 times per second. 我还在你的代码中看到了几个问题,你每帧调用init方法 - 这可能是每秒60次。 In this you are adding a new keylistener each frame. 在这里你每帧都添加一个新的keylistener。 You are also creating a new polygon which would slow down performance. 您还要创建一个新的多边形,这会降低性能。

I've made some changes to your code and and i've used AffineTransforms as an example. 我对您的代码进行了一些更改,并且我使用了AffineTransforms作为示例。 Have a look and see if this helps. 看看,看看这是否有帮助。

package com.joey.testing;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Polygon;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.geom.AffineTransform;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class AffineTransformTest extends JPanel implements KeyListener {

    private Polygon poly;

    private int[] xpoints = { 0, -10, -7, 7, 10 };
    private int[] ypoints = { -10, -2, 10, 10, -2 };

    private int rotation = 0;
    AffineTransform transform;
    AffineTransform rotationTransform;
    AffineTransform translateTransform;

    public AffineTransformTest() {
        setPreferredSize(new Dimension(800,600));
        setFocusable(true);
        requestFocus();

        //Do Init here - no point in creating new polygon each frame.
        //It also adds the key listener each time
        init();
        updateTransforms();
    }

    public void init() {
        poly = new Polygon(xpoints, ypoints, xpoints.length);
        transform = new AffineTransform();
        rotationTransform = new AffineTransform();
        translateTransform = new AffineTransform();
        addKeyListener(this);
    }

    //Use Paint Compoent
    @Override
    public void paintComponent(Graphics g) {
        //Always call super to clear the screen
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g;

        int width = getSize().width;
        int height = getSize().height;

        g2d.setColor(Color.BLACK);
        g2d.fillRect(0, 0, width, height);

        g2d.setColor(Color.WHITE);
        g2d.drawString(rotation + " radians", 10, 20);


        //Store old transform so we can apply it
        AffineTransform old = g2d.getTransform();
        //Add Transform and move polygon
        g2d.setTransform(transform);
        g2d.setColor(new Color(255, 100, 100));
        g2d.fill(poly);
        g2d.setColor(Color.WHITE);
        g2d.draw(poly);
        g2d.setTransform(old);
    }

    public void keyPressed(KeyEvent k) {
        switch(k.getKeyCode()) {
        case KeyEvent.VK_LEFT:
            rotation--;
            if (rotation < 0) rotation = 359;
            repaint();
            break;
        case KeyEvent.VK_RIGHT:
            rotation++;
            if (rotation > 360) rotation = 0;
            repaint();
            break;
        }
        updateTransforms();
    }

    public void updateTransforms(){
        //Resets transform to rotation
        rotationTransform.setToRotation(Math.toRadians(rotation));
        translateTransform.setToTranslation(getWidth()/2, getHeight()/2);

        //Chain the transforms (Note order matters)
        transform.setToIdentity();
        transform.concatenate(translateTransform);
        transform.concatenate(rotationTransform);
    }

    public void keyReleased(KeyEvent k) {}
    public void keyTyped(KeyEvent k) {}


    public static void main(String input[]){
        JFrame f= new JFrame("AffineTransform");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setSize(100, 100);
        f.setResizable(true);
        f.getContentPane().setLayout(new BorderLayout());
        f.getContentPane().add(new AffineTransformTest());
        f.show();

    }
}

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

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