旋转矩形并在sin波中移动它 - 使用graphics2D帮助 [英] Rotate rectangle and move it in sin wave - Help using graphics2D
问题描述
嗨!
我使用之前的Stackoverflow帖子获得以下代码。
I have the code below using previous Stackoverflow posts.
我想要旋转矩形按一定角度移动并使其在sin波中移动。
I want to just rotate the rectangle by some angle and make it move in sin wave.
此代码也会旋转整个sin波。
This code rotates the whole sin wave too.
我理解为什么会这样,但我不知道如何实现我的意图。
I understand why it is happening , but I don't know how to achieve my intention.
请帮助!!!
非常感谢您花时间。
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();
}
}
}
推荐答案
+1 SSCCE
1)不要忘记调用 super.paintComponent();
作为重写的 paintComponent(..)
方法中的第一个语句。
1) Dont forget to have call to super.paintComponent();
as first statement in your overridden paintComponent(..)
method.
2)应在 EDT 并与 Swing Timers
3)类的Java变量命名约定是每个新单词的大写字母,即 WithRotation
。
3) Java variable naming convention for classes is uppercase letter for each new word i.e WithRotation
.
4)不需要 frame.getContentPane.add(..)
只需使用添加(..)
,因为所有呼叫都转发到 contentPane 。
4) No need for frame.getContentPane.add(..)
simply use add(..)
as all calls are forwarded to its contentPane.
以下是示例我做了(基本上你的代码实现了上面的修复),它只使用 AffineTransform #createTransformed Shape()
:
Here is the example I made (basically your code with above fixes implemented), which only rotates the rectangle which follows the graph and not the whole graphics object using 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);
}
}
}
这篇关于旋转矩形并在sin波中移动它 - 使用graphics2D帮助的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!