Question

i need to draw a polygon of "n" sides given 2 points (the center and 1 of his vertex) just that i suck in math. I have been reading a lot and all this is what i have been able to figure it (i dont know if it is correct):

Ok, i take the distance between the 2 points (radius) with the theorem of Pythagoras:

sqrt(pow(abs(x - xc), 2) + pow(abs(y - yc), 2));

And the angle between this 2 points with atan2, like this:

atan2(abs(y - yc), abs(x - xc));

Where xc, yc is the center point and x, y is the only vertex know.

And with that data i do:

void polygon(int xc, int yc, int radius, double angle, int sides)
{
    int i;
    double ang = 360/sides; //Every vertex is about "ang" degrees from each other
    radian = 180/M_PI;
    int points_x[7]; //Here i store the calculated vertexs
    int points_y[7]; //Here i store the calculated vertexs

    /*Here i calculate the vertexs of the polygon*/
    for(i=0; i<sides; i++)
    {
        points_x[i] = xc + ceil(radius * cos(angle/radian));
        points_y[i] = yc + ceil(radius * sin(angle/radian));
        angle = angle+ang;
    }

    /*Here i draw the polygon with the know vertexs just calculated*/
    for(i=0; i<sides-1; i++)
        line(points_x[i], points_y[i], points_x[i+1], points_y[i+1]);
    line(points_y[i], points_x[i], points_x[0], points_y[0]);
}

The problem is that the program dont work correctly because it draw the lines not like a polygon.

Someone how know enough of math to give a hand? im working in this graphics primitives with C and turbo C.


Edit: i dont want to fill the polygon, just draw it.

Was it helpful?

Solution

Consider what 360/sides actually returns if sides is not a factor of 360 (this is integer division - see what 360/7 actually returns).

There is no need to use degrees at all - use 2*Math_PI/(double)nsides and work throughout in radians.

also you can omit the final line by using the modulus function (module nsides).

If you have more than 7 sides you will not be able to store all the points. You don't need to store all the points if you are simply drawing the polygon rather than storing it - just the last point and the current one.

OTHER TIPS

You should be using radians in all your calculations. Here's a complete program that illustrates how best to do this:

#include <stdio.h>

#define PI 3.141592653589

static void line (int x1, int y1, int x2, int y2) {
    printf ("Line from (%3d,%3d) - (%3d,%3d)\n", x1, y1, x2, y2);
}

static void polygon (int xc, int yc, int x, int y, int n) {
    int lastx, lasty;
    double r = sqrt ((x - xc) * (x - xc) + (y - yc) * (y - yc));
    double a = atan2 (y - yc, x - xc);
    int i;

    for (i = 1; i <= n; i++) {
        lastx = x; lasty = y;
        a = a + PI * 2 / n;
        x = round ((double)xc + (double)r * cos(a));
        y = round ((double)yc + (double)r * sin(a));
        line (lastx, lasty, x, y);
    }
}

int main(int argc, char* argv[]) {
    polygon (0,0,0,10,4);   // A diamond.
    polygon (0,0,10,10,4);  // A square.
    polygon (0,0,0,10,8);   // An octagon.
    return 0;
}

which outputs (no fancy graphics here, but you should get the idea):

===
Line from (  0, 10) - (-10,  0)
Line from (-10,  0) - (  0,-10)
Line from (  0,-10) - ( 10,  0)
Line from ( 10,  0) - (  0, 10)
===
Line from ( 10, 10) - (-10, 10)
Line from (-10, 10) - (-10,-10)
Line from (-10,-10) - ( 10,-10)
Line from ( 10,-10) - ( 10, 10)
===
Line from (  0, 10) - ( -7,  7)
Line from ( -7,  7) - (-10,  0)
Line from (-10,  0) - ( -7, -7)
Line from ( -7, -7) - (  0,-10)
Line from (  0,-10) - (  7, -7)
Line from (  7, -7) - ( 10,  0)
Line from ( 10,  0) - (  7,  7)
Line from (  7,  7) - (  0, 10)

I've written the polygon function as per your original specification, passing in just the two co-ordinates. As an aside, you don't want those abs calls in your calculations for radius and angle because:

  • they're useless for radius (since -n2 = n2 for all n).
  • they're bad for angle since that will force you into a specific quadrant (wrong starting point).

I'm not going to just give you the answer, but I have some advice. First, learn how line drawing works INSIDE AND OUT. When you have this down, try to write a filled triangle renderer. Generally, filled polygons are drawn 1 horizontal scan line at a time, top to bottom. You're job is to determine the starting and stopping x coordinate for every scan line. Note that the edge of a polygon follows a straight line (hint, hint)... :)

You're trying to draw a filled poly I guess?

If you're going to try to draw the polys using a line primitive, you're going to have a lot of pain coming to you. dicroce actually gave you some very good advice on that front.

Your best bet is to find a primitive that fills for you and supply it a coordinates list. It's up to you to determine the coordinates to give it.

I think the main trouble is: atan2(abs(y - yc), abs(x - xc)); is giving you radians, not degrees, just convert it to degrees and try.

/* all angles in radians */
double ainc = PI*2 / sides;
int x1, y1;
for (i = 0; i <= sides; i++){
    double a = angle + ainc * i;
    int x = xc + radius * cos(a);
    int y = yc + radius * sin(a);
    if (i > 0) line(x1, y1, x, y);
    x1 = x; y1 = y;
}

Or, you could save the points in an array and call the DrawPoly routine if you've got one.

If you want a filled polygon, call FillPoly if you've got one.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top