到达指定位置后如何旋转矩形?
我想旋转一个矩形,例如y 位置达到指定位置.我想在路口表现出一个矩形作为汽车 - 只需转动例如对.我更喜欢旋转并继续.
I would like to rotate a rectangle when e.g. y position achieve specified position. I would like to behave a rectangle as a car on a junction - just turn e.g. right. I prefer just rotate and continue.
草稿代码如下所示:
Graphics2D g2d = (Graphics2D) g.create();
g2d.setPaint(new Color(150, 150, 0));
//1. when rectangle achieve 500 on y dimension just rotate left/right
if(y==500) {
_rotate = true;
g2d.rotate(Math.toRadians(90.));
}
if(_rotate) { //if rotate, continue way on x dimension
++x ;
g2d.fillRect(x, y, 20, 40);
} else { //else go to the north
--y;
g2d.fillRect(x, y, 20, 40);
}
推荐答案
您的问题缺少很多信息.
There is a lot of information which is missing from your question.
为了能够旋转一个形状,你需要知道一些事情,你需要知道它的当前位置和它的下一个目标位置,然后你可以简单地计算这两个点之间的角度.
In order to be able to rotate a shape, you need to know a few things, you need to know it's current position and it's next target position, then you can simply calculate the angle between these two points.
那么问题就变成了,你如何计算这些位置.有很多方法可以实现这一点,以下是一个简单的路径跟踪过程.
The question then becomes, how do you calculate these positions. There are plenty of ways you might achieve this, the following is a simple path following process.
首先,我们生成一条我们需要遵循的路径,我们使用 Shape
API 来计算沿路径的点.我们使用一个简单的基于时间的动画(而不是通过点循环,我们通过计算动画播放的时间除以我们希望它花费的时间来计算沿路径的进度)并选择最佳的点符合我们目前的进度.
First, we generate a path which we need to follow, we use the Shape
API to calculate the points along the path. We use a simple time based animation (rather the looping through the points, we calculate the progress along the path by calculating amount of time the animation has been playing divided by the amount of time we want it to take) and picking the point which best matches our current progress.
我们使用 AffineTransform
来旋转玩家形状并将生成的 Shape
转换到所需的位置.轻松
We use a AffineTransform
to rotate the player shape and the translate the resulting Shape
to the required position. Ease
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.geom.AffineTransform;
import java.awt.geom.Path2D;
import java.awt.geom.PathIterator;
import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.List;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class PathFollow {
public static void main(String[] args) {
new PathFollow();
}
public PathFollow() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private Shape pathShape;
private List<Point2D> points;
private Shape car;
private double angle;
private Point2D pos;
private int index;
protected static final double PLAY_TIME = 5000; // 5 seconds...
private Long startTime;
public TestPane() {
Path2D path = new Path2D.Double();
path.moveTo(0, 200);
path.curveTo(100, 200, 0, 100, 100, 100);
path.curveTo(200, 100, 0, 0, 200, 0);
pathShape = path;
car = new Rectangle(0, 0, 10, 10);
points = new ArrayList<>(25);
PathIterator pi = pathShape.getPathIterator(null, 0.01);
while (!pi.isDone()) {
double[] coords = new double[6];
switch (pi.currentSegment(coords)) {
case PathIterator.SEG_MOVETO:
case PathIterator.SEG_LINETO:
points.add(new Point2D.Double(coords[0], coords[1]));
break;
}
pi.next();
}
// System.out.println(points.size());
// pos = points.get(0);
// index = 1;
Timer timer = new Timer(40, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (startTime == null) {
startTime = System.currentTimeMillis();
}
long playTime = System.currentTimeMillis() - startTime;
double progress = playTime / PLAY_TIME;
if (progress >= 1.0) {
progress = 1d;
((Timer) e.getSource()).stop();
}
int index = Math.min(Math.max(0, (int) (points.size() * progress)), points.size() - 1);
pos = points.get(index);
if (index < points.size() - 1) {
angle = angleTo(pos, points.get(index + 1));
}
repaint();
}
});
timer.start();
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.draw(pathShape);
AffineTransform at = new AffineTransform();
if (pos != null) {
Rectangle bounds = car.getBounds();
at.rotate(angle, (bounds.width / 2), (bounds.width / 2));
Path2D player = new Path2D.Double(car, at);
g2d.translate(pos.getX() - (bounds.width / 2), pos.getY() - (bounds.height / 2));
g2d.draw(player);
}
g2d.dispose();
}
// In radians...
protected double angleTo(Point2D from, Point2D to) {
double angle = Math.atan2(to.getY() - from.getY(), to.getX() - from.getX());
return angle;
}
}
}
相关文章