views:

262

answers:

4

I am writing a program in which I need to draw polygons of an arbitrary number of sides, each one being translated by a given formula which changes dynamically. There is some rather interesting mathematics involved but I am stuck on this probelm.

How can I calculate the coordinates of the vertices of a regular polygon (one in which all angles are equal), given only the number of sides, and ideally (but not neccessarily) having the origin at the centre?

For example: a hexagon might have the following points (all are floats):

( 1.5  ,  0.5 *Math.Sqrt(3) )
( 0    ,  1   *Math.Sqrt(3) )
(-1.5  ,  0.5 *Math.Sqrt(3) )
(-1.5  , -0.5 *Math.Sqrt(3) )
( 0    , -1   *Math.Sqrt(3) )
( 1.5  , -0.5 *Math.Sqrt(3) )

My method looks like this:

void InitPolygonVertexCoords(RegularPolygon poly)

and the coordinates need to be added to this (or something similar, like a list):

Point[] _polygonVertexPoints;

I'm interested mainly in the algorithm here but examples in C# would be useful. I don't even know where to start. How should I implement it? Is it even possible?!

Thank you.

+6  A: 
for (i = 0; i < n; i++) {
  printf("%f %f\n",r * Math.cos(2 * Math.PI * i / n), r * Math.sin(2 * Math.PI * i / n));
}

where r is the radius of the circumsribing circle. Sorry for the wrong language No Habla C#.

Basically the angle between any two vertices is 2 pi / n and all the vertices are at distance r from the origin.

EDIT: If you want to have the center somewher other than the origin, say at (x,y)

for (i = 0; i < n; i++) {
  printf("%f %f\n",x + r * Math.cos(2 * Math.PI * i / n), y + r * Math.sin(2 * Math.PI * i / n));
}
deinst
To generalize, I'd add XC and YC (the coordinates of the circle's center) and the angle of the 1st vertex A to the cos/sin terms: px = xc + r * cos(2 * pi * i / n + A); py = yc + r * sin(2 * pi * i / n + A);
ysap
He asked for the origin as the center.
deinst
Wow I didnt expect an answer so quickly. OK, so r is the distance from the origin to any of the vertices, right? And I assume n is the number of sides. I think I get this... Thanks - top notch answer :-)
rmx
@dentist - he said "not necessarily"
ysap
@rmx: Well, it's a Math problem, not a programming one. I guess you know the equation of a circle is `x^2 + y^2 = r^2`. However, to make it into a program, you have to separate `x` and `y`. This parametric equation does this: `{ x = r * cos(theta), y = r * sin(theta), where 0 <= theta < 2 * PI }`. To make an n-side polygon, just assign n different values to theta. To make regular polygons, just do 2 * PI / n * i, where 0 <= i < n. Please refer to [Parametric equation - Wikipedia](http://en.wikipedia.org/wiki/Parametric_equation) for more information.
Siu Ching Pong - Asuka Kenji
Thanks Asuka - I have it working very nicely now. I used this method with `double circumcircleRadius = (poly.SideLength / Math.Sin(angle)) / 2;` to get the value of r. It's actually far easier than it first seemed.
rmx
+1  A: 

Sorry, I dont have a full solution at hand right now, but you should try looking for 2D-Rendering of Circles. All classic implementations of circle(x,y,r) use a polygon like you described for drawing (but with 50+ sides).

Rock
+1  A: 

The number of points equals the number of sides.

The angle you need is angle = 2 * pi / numPoints.

Then starting vertically above the origin with the size of the polygon being given by radius:

for (int i = 0; i < numPoints; i++)
{
    x = centreX + radius * sin(i * angle);
    y = centreY + radius * cos(i * angle);
}

If your centre is the origin then simply ignore the centreX and centreY terms as they'll be 0,0.

Swapping the cos and sin over will point the first point horizontally to the right of the origin.

ChrisF
Should be **sin(i + angle)**, and not as written!
ysap
@ysap - are you sure? This gives the points at 0, angle, 2*angle, 3*angle etc around the circle. So for a square (4 points, angle = 90) you get points at 0, 90, 180 and 270.
ChrisF
@ChrisF - Sorry, I thought I read in your post that angle was the offset. Re-reading it (and assuming you did not edit that after my comment), you are right, the way it appears now. Anyway, adding an Angle term to the sin/cos argument (which is actually the phase), will make the 1st point's place arbitrary.
ysap
@ysap - I think I did briefly have a comment about offsetting the angle, but realised it was confusing and removed it.
ChrisF
+1  A: 

Say the distance of the vertices to the origin is 1. And say (1, 0) is always a coordinate of the polygon.

Given the number of vertices (say n), the rotation angle required to position the (1, 0) to the next coordinate would be (360/n).

The computation required here is to rotate the coordinates. Here is what it is; Rotation Matrix.

Say theta = 360/n;

[cos(theta) -sin(theta)]
[sin(theta) cos(theta)]

would be your rotation matrix.

If you know linear algebra you already know what i mean. If dont just have a look at Matrix Multiplication

tafa