Я хочу реализовать простой пример рисования на Java, имитирующий траекторию движения автомобиля / трактора. Для этого я хочу добавить только простую строку в середине JPanel
(это мой автомобиль / трактор :-)). Когда я пользуюсь клавишами вверх, вниз, влево, вправо на клавиатуре, на панели должна быть нарисована траектория движения.
Я смог понять это, но только если я переместил линию на панели (это означает, что я перемещаю автомобиль / трактор на панели). Но то, что я хочу сделать, это не перемещать линию (автомобиль / трактор). Автомобиль / трактор всегда должен быть посередине панели, но путь должен быть нарисован позади автомобиля. Должно выглядеть фон движется? Подобно автомобильным навигационным системам.
Я не уверен, как я могу это понять.
Я добавил следующую картинку, чтобы подробно объяснить, что я хочу реализовать:
Синяя стрелка в серединекартина автомобиль / трактор. За этим черная линия нарисована на экране. Путь движения автомобиля / трактора окрашен в синий цвет за черной линией. В моем приложении у меня есть GPS-координаты, которые я могу использовать для вычисления точек с координатами x и y. С помощью этих рассчитанных точек я хочу нарисовать траекторию движения автомобиля / трактора. Но автомобиль / трактор всегда должен быть в центре JPanel. Только путь должен двигаться и вращаться.
Пример:
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JFrame;
public class Start {
public static void main(String[] args)
{
JFrame frame = new JFrame("AutoPilot");
frame.setSize(800,600);
Stage e1 = new Stage();
frame.getContentPane().add(e1);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.addKeyListener(new KeyListener() {
@Override
public void keyPressed(KeyEvent e)
{
switch(e.getKeyCode())
{
case KeyEvent.VK_LEFT:
e1.moveLine(e);
break;
case KeyEvent.VK_RIGHT:
e1.moveLine(e);
break;
case KeyEvent.VK_UP:
e1.moveLine(e);
break;
case KeyEvent.VK_DOWN:
e1.moveLine(e);
break;
case KeyEvent.VK_PLUS:
e1.moveLine(e);
break;
case KeyEvent.VK_MINUS:
e1.moveLine(e);
break;
case KeyEvent.VK_Z:
e1.moveLine(e);
break;
}
}
@Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
}
@Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
});
frame.setVisible(true);
}
}
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.geom.AffineTransform;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import java.awt.image.BufferedImage;
import javax.swing.JPanel;
public class Stage extends JPanel
{
int pW = 800;
int pH = 600;
double centerX, centerY;
double x,y,angle, angleLine, xpic,ypic;
double w = 15;
double x1,y1,x2,y2,x3,y3;
BufferedImage bi;
private boolean gf_rotate;
private boolean gf_bgSet;
private boolean gf_rotated;
public Stage()
{
setLayout(null);
setBounds(0,0,pW,pH);
setBackground(Color.WHITE);
centerX = this.getWidth()/2;
centerY = this.getHeight()/2;
x = centerX;
y = centerY;
xpic = centerX;
ypic = centerY;
bi = new BufferedImage(pW, pH, BufferedImage.TYPE_INT_RGB);
addMouseListener(new MouseListener() {
@Override
public void mouseClicked(MouseEvent arg0) {
System.out.println(arg0.getX() +","+ arg0.getY()); // TODO Auto-generated method stub
}
@Override
public void mouseEntered(MouseEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void mouseExited(MouseEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void mousePressed(MouseEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void mouseReleased(MouseEvent arg0) {
// TODO Auto-generated method stub
}
});
}
public void moveLine(KeyEvent e)
{
switch(e.getKeyCode())
{
case KeyEvent.VK_PLUS:
angle--;
angleLine--;
gf_rotate = true;
repaint();
break;
case KeyEvent.VK_MINUS:
angle++;
angleLine++;
gf_rotate = true;
repaint();
break;
case KeyEvent.VK_LEFT:
break;
case KeyEvent.VK_RIGHT:
break;
case KeyEvent.VK_UP:
y--;
ypic++;
if (gf_rotate == true)
{
gf_rotated = true;
}
gf_rotate = false;
repaint();
break;
case KeyEvent.VK_DOWN:
y++;
ypic--;
if (gf_rotate == true)
{
gf_rotated = true;
}
gf_rotate = false;
repaint();
break;
case KeyEvent.VK_Z:
repaint();
break;
}
}
@Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) bi.createGraphics();
Graphics2D g2dMain = (Graphics2D) g;
double _x,_y;
//Hintergrundfarbe (Bild) setzen
if (gf_bgSet==false)
{
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
g2d.setColor(Color.WHITE);
g2d.fillRect(0, 0, pW, pH);
g2d.setColor(Color.BLUE);
Line2D line = new Line2D.Double(x, y, x+100,y);
g2d.draw(line);
gf_bgSet=true;
}
float[] fa = {1};
BasicStroke s = new BasicStroke(1, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_ROUND,15,fa,15);
g2d.setStroke(s);
_x =x;
_y = y;
if (gf_rotated==true)
{
_x=400;
_y=300;
}
Point2D p1 = new Point2D.Double(_x,_y);
Point2D p2 = new Point2D.Double(p1.getX()+100,p1.getY());
Line2D line = null;
if (gf_rotate==true)
{
line = new Line2D.Double(p1.getX(), p1.getY(), p2.getX(),p2.getY());
}
else
{
Point2D p3 = rotateLine(p1,p2,angleLine);
line = new Line2D.Double(p1.getX(), p1.getY(), p3.getX(),p3.getY());
}
g2d.setColor(new Color(255,80,90,100));
AffineTransform atLine = null;
if (gf_rotated == true)
{
atLine = new AffineTransform();
atLine = g2d.getTransform();
g2d.setColor(Color.GREEN);
Point2D newP2 = rotateLine(p1,p2,angleLine);
line = new Line2D.Double(p1.getX()-(centerX-x), p1.getY()-(centerY-y), newP2.getX()-(centerX-x),newP2.getY()-(centerY-y));
}
else
{
//Rotate line
atLine = new AffineTransform();
atLine.translate(x,y);
if (gf_rotate==true)
{
atLine.rotate(Math.toRadians(angle));
}
atLine.translate(-x,-y);
}
g2d.draw(atLine.createTransformedShape(line));
g2d.dispose();
AffineTransform at = new AffineTransform();
AffineTransform old = g2d.getTransform();
at.translate(xpic,ypic);
at.rotate(Math.toRadians(-angle),centerX-xpic,centerY-ypic);
at.translate(-centerX,-centerY);
g2dMain.drawImage(bi, at , null);
g2d.setTransform(old);
g2dMain.dispose();
}
private Point2D rotateLine(Point2D center, Point2D edge, double angle2) {
double xRot = (int) center.getX() + Math.cos(Math.toRadians(angle2)) * (edge.getX() - center.getX()) - Math.sin(Math.toRadians(angle2)) * (edge.getY() - center.getY());
double yRot = (int) center.getY() + Math.sin(Math.toRadians(angle2)) * (edge.getX() - center.getX()) + Math.cos(Math.toRadians(angle2)) * (edge.getY() - center.getY());
return new Point2D.Double(xRot, yRot);
}
}