繁体   English   中英

旋转矩形并在正弦波中移动它-帮助使用graphics2D

[英]Rotate rectangle and move it in sin wave - Help using graphics2D

嗨!

我下面的代码使用以前的Stackoverflow帖子。

我只想将矩形旋转一定角度,使其沿正弦波移动。

该代码也旋转整个正弦波。

我了解为什么会发生这种情况,但我不知道如何实现我的意图。

请帮忙!!!

非常感谢您抽出宝贵的时间。

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.util.Timer;
import java.util.TimerTask;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class Withrotation {

    public static int i = 1;
    public static Ticker t;
    public static Repainter r;
    public static int newx, newy;

    public static void main(String[] args) {
        final JFrame frame = new JFrame("Wavy!");
        final WavyPanel wp = new WavyPanel();
        frame.getContentPane().add(wp, BorderLayout.CENTER);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        t = new Ticker(wp);
        r = new Repainter(wp);
        frame.pack();
        frame.setVisible(true);
        final Timer tickTimer = new Timer();
        final Timer paintTimer = new Timer();
        paintTimer.schedule(r, 1000, 50);
        tickTimer.schedule(t, 1000, 10);
    }

    private static class WavyPanel extends JPanel {

        private final Dimension size = new Dimension(640, 480);
        private int amplitude = 50;
        private int frequency = 5;
        private double x1 = 0;
        private double y1 = 500;
        private int yBase = 0;

        WavyPanel() {
            super(true);
        }

        @Override
        protected void paintComponent(final Graphics g) {
            final Graphics2D g2 = (Graphics2D) g;
            AffineTransform old = g2.getTransform();
            g2.rotate(Math.toRadians(-30));

            g2.clearRect(0, 0, this.getSize().width, this.getSize().height);
            g2.setColor(Color.BLACK);
            g2.fillRect((int) x1, (int) y1, 20, 80);
            g2.setTransform(old);


        }

        @Override
        public Dimension getPreferredSize() {
            return size;
        }

        @Override
        public Dimension getMinimumSize() {
            return size;
        }

        @Override
        public Dimension getMaximumSize() {
            return size;
        }

        public void tick() {
            x1 = x1 + 1;
            final int waveLength = size.width / frequency;
            yBase = (++yBase) % waveLength;
            final double normalized = (double) yBase / (double) waveLength;
            final double radians = normalized * Math.PI * 2;
            final double sine = Math.sin(radians);
            y1 = (int) (sine * amplitude);




        }
    }

    private static class Ticker extends TimerTask {

        private final WavyPanel panel;

        Ticker(final WavyPanel panel) {

            this.panel = panel;

        }

        @Override
        public void run() {
            panel.tick();
        }
    }

    private static class Repainter extends TimerTask {

        private final WavyPanel panel;

        Repainter(final WavyPanel panel) {

            this.panel = panel;

        }

        @Override
        public void run() {
            panel.repaint();

        }
    }
}

SSCCE +1

1)不要忘记调用super.paintComponent(); 作为重写的paintComponent(..)方法中的第一条语句。

2)Swing UI应在EDT上创建,并与Swing计时器结合使用

3)类的Java变量命名约定是每个新单词的大写字母,即WithRotation

4)不需要frame.getContentPane.add(..)只需使用add(..)因为所有调用都被转发到其contentPane

这是我制作的示例(基本上是实现了上述修复的代码),使用AffineTransform#createTransformedShape()仅旋转紧随图形的矩形,而不旋转整个图形对象:

在此处输入图片说明

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.event.ActionEvent;
import java.awt.geom.AffineTransform;
import javax.swing.AbstractAction;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;

public class WithRotation {

    private JFrame frame;
    private WavyPanel wp;

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new WithRotation();
            }
        });
    }

    public WithRotation() {
        initComponents();
    }

    private void initComponents() {
        frame = new JFrame("Wavy!");
        wp = new WavyPanel();
        frame.add(wp, BorderLayout.CENTER);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);

        createAndStartTimers();
    }

    private void createAndStartTimers() {
        new Timer(50, new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent ae) {

                wp.repaint();
            }
        }).start();
        new Timer(10, new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent ae) {

                wp.tick();
            }
        }).start();
    }

    class WavyPanel extends JPanel {

        private final Dimension size = new Dimension(640, 480);
        private int amplitude = 50;
        private int frequency = 5;
        private double x1 = 0;
        private double y1 = 500;
        private int yBase = 0;

        WavyPanel() {
            super(true);
        }

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

            g2.clearRect(0, 0, this.getSize().width, this.getSize().height);
            g2.setColor(Color.BLACK);

            Rectangle rect = new Rectangle((int) x1, (int) y1, 20, 80);

            AffineTransform transform = new AffineTransform();
            transform.rotate(Math.toRadians(-30), rect.getX() + rect.width / 2, rect.getY() + rect.height / 2);

            Shape transformed = transform.createTransformedShape(rect);
            g2.fill(transformed);
        }

        @Override
        public Dimension getPreferredSize() {
            return size;
        }

        @Override
        public Dimension getMinimumSize() {
            return size;
        }

        @Override
        public Dimension getMaximumSize() {
            return size;
        }

        public void tick() {
            x1 = x1 + 1;
            final int waveLength = size.width / frequency;
            yBase = (++yBase) % waveLength;
            final double normalized = (double) yBase / (double) waveLength;
            final double radians = normalized * Math.PI * 2;
            final double sine = Math.sin(radians);
            y1 = (int) (sine * amplitude);
        }
    }
}

暂无
暂无

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

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