Given a list of
n
circles, each of diameterd
, I want to generate an n-gon (polygon of n lengths), with side lengthsd
, and draw a circle on each of its edges.
I encountered this problem while developing an application.
The formula for the radius of the polygon with N sides, given a length a
for each side, is
import javax.swing.JFrame;
public class gameFrame extends JFrame{
static int width = 400;
static int height = 400;
public static void main(String[] args) {
gameFrame frame = new gameFrame();
gamePanel panel = new gamePanel();
frame.add(panel);
frame.setTitle("Tutorial");
frame.setSize(400, 400);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.setResizable(true);
panel.initializeList();
panel.fpsTimer.start();
}
}
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Arc2D;
import java.util.ArrayList;
import javax.swing.JPanel;
import javax.swing.Timer;
public class gamePanel extends JPanel{
static ArrayList<Point2D> coordinates = new ArrayList<Point2D>();
static int d = 20;
Timer fpsTimer = new Timer(10, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
repaint();
}
});
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
//paint the circles with the coordinates in list 'coordinates'
for(Point2D point : coordinates) {
g2d.setColor(Color.BLACK);
Shape circle = new Arc2D.Double(point.x,
point.y,
d,
d,
0 , 360, Arc2D.CHORD);
g2d.fill(circle);
}
}
public void initializeList() {
Point2D center = new Point2D(0,0);
int n = 15; // number of sides of polygon
float alpha = 360/ n; // angle of each triangle in the polygon
float angle = 0; // incremental angle for the loop
float side = d; // desired length of each side
float radius = (float) (side / (2*Math.sin(Math.PI / n))); // R = a / (2*(sin(PI/n))) formula
//verifying that the circle radius isn't larger than the frame
if(!(radius >= gameFrame.width || radius >= gameFrame.height)) {
//center of the circle
center.x = (gameFrame.width)/2;
center.y = (gameFrame.height)/2;
for(int i = 0 ; i < n ; i++) {
coordinates.add(new Point2D((center.x + Math.sin(angle)*radius),
(center.y -Math.cos(angle)*radius)));
angle += alpha;
}
}
}
}
public class Point2D {
double x;
double y;
public Point2D(double x , double y) {
this.x = x;
this.y = y;
}
}
For n=15
and d=20
as shown above, the output is
Some circles overlap.
Surprisingly, if I modify angle += alpha
to angle += alpha+0.295;
in GamePanel initializeList()
, I get the desired result :
For n=14
the output is even scarier :
I have spent a ridiculous amount of time on this bug. Does anyone have any idea what is going wrong?
Java Math uses angles in radians.
So calculate alpha in radians like this:
double alpha = Math.toRadians(360.0/ n);
Just update the line and it should fix the issue.
Also, for more accuracy use double
type instead of float
for each variable.