java - derecha - rotacion simple a la izquierda
Rotación simple del círculo(simular movimiento) (1)
Tengo una animación simple en Java que consiste en una rueda que se mueve a través de una ventana. Es solo un círculo simple que comienza desde la pantalla desde la izquierda, entra y continúa hacia la derecha hasta que se apaga de la pantalla. Luego se repite y repite este proceso.
X
es una variable que contiene la posición de la rueda. Puede estar entre - (ancho de la rueda) y el tamaño de la ventana + el ancho de la rueda.
Me gustaría simular la rotación dibujando un círculo dentro de esta rueda, que gira alrededor del círculo como si estuviera unida.
Imagine una rueda de bicicleta en la vida real con una bandera roja en el volante. A medida que la rueda gira, la bandera roja estaría en el borde de la rueda moviéndose a medida que avanza la rueda. Este es el comportamiento que quiero.
Estoy obteniendo un porcentaje para pasar a mi clase de rueda así:
int percentage = x/windowWidth;
Cada cuadro que mueve la rueda, lo llamo wheel.rotate(percentage)
.
Esta es la implementación:
private int diameter = 50;
private final int SPOKE_DIAMETER = diameter/5;
public void rotate(double percent){
this.percent = percent;
this.theta = percent*(PI*2);
System.out.println(percent*PI);
}
public void paintComponent(Graphics canvas)
{
// wheel
canvas.setColor(Color.gray);
canvas.fillOval(0, 0, diameter, diameter);
// spinning flag
canvas.setColor(Color.red);
canvas.fillOval((int)(percent*diameter),(int)((sin((percent*(PI*2)))*diameter)), SPOKE_DIAMETER,SPOKE_DIAMETER);
}
La ubicación x funciona más o menos como yo quería, pero el y no funciona. Se menea como una ola de pecado, que se espera ( sí usé el pecado ...), sin embargo, no estoy seguro de cómo alterar mis cálculos para seguir el círculo alrededor.
¿Qué pasa con mi implementación? (No soy muy bueno dibujando con funciones trigonométricas)
Básicamente, debe calcular el punto en el círculo, en función del ángulo en que debería aparecer el objeto ...
Como la mayoría de las cosas, robé esto de Internet en algún lado, pero funciona ...
protected Point getPointOnCircle(float degress, float radius) {
int x = Math.round(getWidth() / 2);
int y = Math.round(getHeight() / 2);
double rads = Math.toRadians(degress - 90); // 0 becomes the top
// Calculate the outter point of the line
int xPosy = Math.round((float) (x + Math.cos(rads) * radius));
int yPosy = Math.round((float) (y + Math.sin(rads) * radius));
return new Point(xPosy, yPosy);
}
Basado en un ángel (en grados) y el radio del círculo, esto devolverá la posición x / y a lo largo de la circunferencia del círculo ...
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class RotateWheel {
public static void main(String[] args) {
new RotateWheel();
}
public RotateWheel() {
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 float degrees = 0;
public TestPane() {
Timer timer = new Timer(40, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
degrees += 0.5f;
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();
int diameter = Math.min(getWidth(), getHeight());
int x = (getWidth() - diameter) / 2;
int y = (getHeight() - diameter) / 2;
g2d.setColor(Color.GREEN);
g2d.drawOval(x, y, diameter, diameter);
g2d.setColor(Color.RED);
float innerDiameter = 20;
Point p = getPointOnCircle(degrees, (diameter / 2f) - (innerDiameter / 2));
g2d.drawOval(x + p.x - (int) (innerDiameter / 2), y + p.y - (int) (innerDiameter / 2), (int) innerDiameter, (int) innerDiameter);
g2d.dispose();
}
protected Point getPointOnCircle(float degress, float radius) {
int x = Math.round(getWidth() / 2);
int y = Math.round(getHeight() / 2);
double rads = Math.toRadians(degress - 90); // 0 becomes the top
// Calculate the outter point of the line
int xPosy = Math.round((float) (x + Math.cos(rads) * radius));
int yPosy = Math.round((float) (y + Math.sin(rads) * radius));
return new Point(xPosy, yPosy);
}
}
}