Need some mathematics assistance. Imagine you are given a circle that acts as a bounding box. How do you accurately draw a polygon in such a way that it fits the circle just nice? Note that I meant a polygon, meaning that the algorithm must be able to cater for any number of sides 3 or above. I will really appreciate it if any one of you can post the code to accomplish this. You can start your code with:
public void paintComponent(Graphics g)
{
super.paintComponent(g);
// For sake of clarity, assume that the radius of the bounding box (circle) is 100 pixels
// Now draw a polygon to fit this circle
}
I have an idea of what to do, but I cannot code it because I have forgotten all my trigonometry. The idea is this:
In order to draw a polygon that fits in a circle perfectly, the theory is that all the points must touch the circle. In order to make this happen, I take 360 degrees and divide by the number of points (which happens to be equal to the number of sides). Once I know the answer, the problem becomes simpler. All I need to do is start from the center of the circle, draw an imaginary line outwards until it touches the circle (and if you notice, this line happens to be the radius). Everytime after I draw a line this way, I will rotate the same angle as the angle I just found out, then I draw an imaginary line the same way, and keep continuing until I finish drawing all the lines. Once all imaginary lines are drawn, just connect all the points (a point is defined as the location where the imaginary line and circle intersect) together to form a polygon. Although I know the theory, but, I do not know how to find out the x and y coordinates of the point where the imaginary line touches the circle.
Can anyone please help? Thanks a lot. Also, if your theory of drawing a polygon in a circle is simpler than mine, feel free to use your own.
of course a polygon with n points requires all n points to satisfy the condition. Meaning you can cut short the loop if one point doesn't satisfy the condition.
0
With monday.comâ€™s project management tool, you can see what everyone on your team is working in a single glance. Its intuitive dashboards are customizable, so you can create systems that work for you.
Sorry, but will it be possible for you to write the method? It seems that CEHJ's algorithm does not take the radius into account, so I still do not know what to do.
using your radius of 100 pixels, we can draw circle on a minimum screensize 200X200 which gives us a center(100,100) so:
g.drawOval(0,0,200,200); // read up on reference
assumming your polygon has n=4 points, therefore angle(theta) = 2pi/4 (or 360/4)
double theta = Math.PI*2/n;
using starting (x',y') = (100,0)
Dimension[] pointCoords = new Dimension[n];
we can have a loop like this
//i=1
for(i<n)
pointCoords[i-1] = new Dimension((int)Math.sin(theta*i)*x',(int)Math.cos(theta*i)*y');
public class CirclePolygon extends JPanel
{
private Polygon Poly = createPolygon(8, 105, 105, 100);
public static void main(String[] args)
{
JFrame f = new JFrame();
f.getContentPane().add(new CirclePolygon());
f.setSize(220, 240);
f.show();
}
public void paintComponent(Graphics g)
{
g.drawPolygon(Poly);
}
public static Polygon createPolygon(int n, int cx, int cy, int r)
{
double delta = 2 * Math.PI / n;
Polygon p = new Polygon();
double theta = 0.0;
for (int i=0; i<n; i++)
{
int x = cx + (int) (r * Math.cos(theta));
int y = cy + (int) (r * Math.sin(theta));
theta += delta;
p.addPoint(x, y);
Except that it's reusability by dr0zaxx is limited. It would have been better to do something more like:
public class CirclePolygon extends JPanel {
private Polygon poly;
public static void main(String[] args) {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.getContentPane().add(new CirclePolygon());
f.setSize(220, 240);
f.show();
}
public CirclePolygon(int n, int cx, int cy, int r) {
poly = createPolygon(n, cx, cy, r);
}
public CirclePolygon() {
// Create default hexagon in top left of component
poly = createPolygon(6, 50, 50, 50);
}
public void paintComponent(Graphics g) {
g.drawPolygon(poly);
}
/**
* Description of the Method
*
* @param n Number of sides
* @param cx x coordinate of polgon's centre
* @param cy y coordinate of polgon's centre
* @param r Radius of polygone
* @return The polygon created
*/
public static Polygon createPolygon(int n, int cx, int cy, int r) {
double delta = 2 * Math.PI / n;
Polygon p = new Polygon();
double theta = 0.0;
for (int i = 0; i < n; i++) {
int x = cx + (int) (r * Math.cos(theta));
int y = cy + (int) (r * Math.sin(theta));
theta += delta;
p.addPoint(x, y);
>>The code you posted does not improve it reuse one little bit,
On the contrary - a simple alteration allows either the JPanel subclass or a Polygon to be returned - which makes it more reusable
>>but my reference to "radius" is important after all :0
The most important thing is you corrected the error in my first equation thanks ;-) The 'radius' is merely points on a line, or a point on the line, depending on how you want to look at it. The points are transformed as stated in their rotation about the origin.
That class is not intended to be reusable (and you wouldn't want it to be anyway).
As mentioned above it is merely provided as a driver program to allow you to easily test it.
To use the code you just need to copy the createPolygon method into your code where appropriate, and call it (from any class) that needs circular polygon.
A much more reusable approach :)
Divide the circle up and get your angle of rotation (theta) between n points
theta = Math.PI / n
Apply theta in a tranformation of your starting coordinates (x1,y1)
x2 = x1 * sin theta
y2 = y1 * cos theta