Josue Espinosa - 1 year ago 86

Java Question

I have a simple animation in Java that consists of a wheel moving across a window. It is just a plain circle that starts off of the screen from the left, enters and continues to the right until it goes off of the screen. Then it loops and repeats this process.

`X`

I would like to simulate rotation by drawing a circle within this wheel, that rotates around the circle as if it were attached.

Imagine a bike wheel in real life with a red flag on the wheel. As the wheel rotates, the red flag would be on the edge on the wheel moving as the wheel progresses. This is the behavior I want.

I am getting a percentage to pass into my wheel class like this:

`int percentage = x/windowWidth;`

Each frame that the wheel moves, I call

`wheel.rotate(percentage)`

This is the implementation:

`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);

}

The x location works more or less how I wanted, but the y does not. It wiggles like a sin wave, which is expected (I

What is wrong with my implementation? (I'm not very good with drawing with trigonometric functions)

Answer Source

Basically, you need to calculate the point on the circle, based on an angel that the object should appear...

Like most things, I stole this off the internet somewhere, but it works...

```
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);
}
```

Based on an angel (in degrees) and the radius of the circle, this will return the x/y position along the circumference of the circle...

```
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);
}
}
}
```