Pergunta

preciso desenhar um polígono de "n" lados com 2 pontos (o centro e 1 de seu vértice), só que sou péssimo em matemática.Tenho lido muito e tudo isso é o que consegui descobrir (não sei se está correto):

Ok, calculo a distância entre os 2 pontos (raio) com o teorema de Pitágoras:

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

E o ângulo entre estes 2 pontos com atan2, assim:

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

Onde xc, yc é o ponto central e x, y é o único vértice conhecido.

E com esses dados eu faço:

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]);
}

O problema é que o programa não funciona corretamente porque desenha as linhas não como um polígono.

Alguém sabe o suficiente de matemática para ajudar?estou trabalhando nessas primitivas gráficas com C e turbo C.


Editar:não quero preencher o polígono, apenas desenhe-o.

Foi útil?

Solução

Considere o que 360/sides na verdade retorna se sides não é um fator de 360 ​​(esta é uma divisão inteira - veja o que 360/7 realmente retorna).

Não há necessidade de usar graus - use 2*Math_PI/(double)nsides e trabalhe em radianos.

você também pode omitir a linha final usando a função módulo (módulo nsides).

Se você tiver mais de 7 lados não conseguirá armazenar todos os pontos.Você não precisa armazenar todos os pontos se estiver simplesmente desenhando o polígono em vez de armazená-lo - apenas o último ponto e o atual.

Outras dicas

Você deve usar radianos em todos os seus cálculos. Aqui está um programa completo que ilustra a melhor forma de fazer isso:

#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;
}

Quais saídas (sem gráficos sofisticados aqui, mas você deve ter a ideia):

===
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)

Eu escrevi o polygon Função de acordo com sua especificação original, passando apenas nas duas coordenadas. Como um aparte, você não querer Essa abs chamadas em seus cálculos de raio e ângulo porque:

  • Eles são inúteis para o raio (desde -n2 = n2 para todos n).
  • Eles são ruins para o ângulo, pois isso o forçará a um quadrante específico (ponto de partida errado).

Não vou apenas dar a resposta, mas tenho alguns conselhos. Primeiro, saiba como o desenho de linha funciona por dentro e por fora. Quando você tiver isso, tente escrever um renderizador de triângulo preenchido. Geralmente, os polígonos preenchidos são desenhados 1 linha de varredura horizontal de cada vez, de cima para baixo. Seu trabalho é determinar a coordenada X de partida e parada para cada linha de varredura. Observe que a borda de um polígono segue uma linha reta (dica, dica) ... :)

Você está tentando desenhar um poli preenchido, eu acho?

Se você tentar desenhar os polys usando uma linha primitiva, terá muita dor vindo até você. A Dicroce realmente lhe deu alguns bons conselhos nessa frente.

Sua melhor aposta é encontrar um primitivo que preencha para você e forneça uma lista de coordenadas. Cabe a você determinar as coordenadas para dar.

Eu acho que o principal problema é: atan2(abs(y - yc), abs(x - xc)); está dando a você radianos, não graus, apenas convertê -lo em graus e tente.

/* 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;
}

Ou você pode salvar os pontos em uma matriz e chamar a rotina de drawpoly se tiver uma.

Se você quiser um polígono preenchido, ligue para o FillPoly se você tiver um.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top