OBS! Changed as part of the question has been answered.
My math has been fixed due to your help and input, the same with StackOverflowError but I still can get my head around how to make the circle move from one x,y point to another. Currently I just repeat the drawing multiple places.
public class MyFrame extends JPanel {
int xc = 300, yc = 300, r = 100, diam = 50;
double inc = Math.PI / 360, theta = 0;
public void paintComponent(Graphics g) {
Timer timer = new Timer(0, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
theta = theta inc;
repaint();
}
});
timer.setDelay(2);
timer.start();
}
@Override
public void paint(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON ); //smooth the border around the circle
g2d.rotate(theta, xc, yc);
g2d.setColor(Color.blue);
g2d.drawOval(xc r - diam / 2, yc r - diam / 2, diam, diam);
}
}
CodePudding user response:
Math.sin
and Math.cos
methods expect a value in radians. You can convert degrees to radians by multiplying with Math.PI/180
Therefore, try changing Math.cos(i * 360 / n)
and Math.sin(i * 360 / n)
to Math.cos((i * 360 / n)*(Math.PI/180))
and Math.sin((i * 360 / n)*(Math.PI/180))
.
CodePudding user response:
This should help you get started. You can modify it as you see fit. It simply has an outer circle revolve around an inner red dot at the center of the panel.
- First, rotate the graphics context, and not the circle location around the center. Thus, no trig is required.
Anti-aliasing
simply fools the eye into thinking the graphics are smoother.BasicStroke
sets the thickness of the line- you need to put the panel in a frame.
- and
super.paintComponent(g)
should be first statement inpaintComponent
to clear panel (and do other things). - the timer updates the angle by increment and invokes repaint. A larger increment will make a quicker but more "jerky" motion about the center. If you set the angle to
Math.PI/4
, then you need to increase the timer delay (try about 1000ms). - Check out the Java Tutorials for more on painting.
- Anything else I omitted or forgot should be documented in the JavaDocs.
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
public class DrawCircle extends JPanel {
int width = 500, height = 500;
final int xc = width/2, yc = height/2;
int r = 100; // radius from center of panel to center of outer circle
int diam = 50; // outer circle diamter
double inc = Math.PI/360;
double theta = 0;
JFrame f = new JFrame();
public static void main(String[] args) {
SwingUtilities.invokeLater(()-> new DrawCircle().start());
}
public void start() {
f.add(this);
f.pack();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setLocationRelativeTo(null);
f.setVisible(true);
Timer timer = new Timer(0, (ae)-> { theta = inc; repaint();});
timer.setDelay(20);
timer.start();
}
@Override
public Dimension getPreferredSize() {
return new Dimension(width, height);
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON );
g2d.rotate(theta, xc, yc);
g2d.setColor(Color.red);
g2d.fillOval(xc-3, yc-3, 6, 6); // center of panel
g2d.setStroke(new BasicStroke(3));
g2d.setColor(Color.blue);
// g2d.drawLine(xc,yc, xc r, yc r); // tether between centers
g2d.drawOval(xc r-diam/2, yc r-diam/2, diam,diam);
}
}