2009-11-25 3 views
1

Мне нужно нарисовать многоугольник «n» сторон, учитывая 2 точки (центр и 1 его вершины), только чтобы сосать математику. Я читал много, и все это то, что я смог понять (я не знаю, правильно ли это):Нарисуйте многоугольник в C

Хорошо, я беру расстояние между двумя точками (радиус) с теоремой Пифагора :

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

и угол между этими 2 точками с atan2, как это:

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

Где хс, ус является точка центра и х, у есть только вершина знать.

И с этими данными я сделать:

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

Проблема заключается в том, что программа не работает правильно, потому что рисовать линии не как полигона.

Кто-то, кто знает достаточно математики, чтобы дать руку? им работать в этой графических примитивов с C и турбо С


Edit: я не хочу, чтобы заполнить полигон, просто сделать это.

+0

Можете ли вы уточнить, хотите ли вы заполненный полигон (в этом случае ответы о trangles может иметь отношение) или незаполненный один (где вы просто хотите по периметру линии, как вы предлагаете, и рисование линий все, что вам нужно –

ответ

2

Рассмотрите, что 360/sides действительно возвращается, если sides не является фактором 360 (это целочисленное деление - см., Что на самом деле 360/7 возвращается).

Нет необходимости использовать градусы вообще - используйте 2*Math_PI/(double)nsides и работайте повсюду в радианах.

также вы можете опустить финальную строку, используя функцию модуля (модуль nsides).

Если у вас более 7 сторон, вы не сможете сохранить все баллы. Вам не нужно сохранять все точки, если вы просто рисуете многоугольник, а не сохраняете его - только последнюю и текущую.

0

Я не собираюсь просто дать вам ответ, но у меня есть совет. Сначала узнайте, как работает линейный чертеж INSIDE AND OUT. Когда у вас это будет, попробуйте написать заполненный визуализатор треугольника. Как правило, заполненные многоугольники нарисованы по одной горизонтальной линии развертки за раз, сверху вниз. Вы работаете, чтобы определить начальную и конечную координаты x для каждой строки сканирования. Обратите внимание, что край многоугольника следует прямой (подсказка, подсказка) ... :)

0

Вы пытаетесь нарисовать заполненный поли, я думаю?

Если вы попытаетесь нарисовать полисы с помощью примитива линии, у вас будет много боли, приходящей к вам. dicroce действительно дал вам очень хороший совет на этом фронте.

Ваш лучший выбор - найти примитив, который заполняет вас и предоставить ему список координат. Вам решать определить координаты.

+0

Почему вы предположить, что это должны быть заполнены? вопрос не упоминает об этом. на самом деле он специально пытается нарисовать контур многоугольника, а не заполненная версии. – paxdiablo

0

Я думаю, что основная проблема: atan2(abs(y - yc), abs(x - xc)); дает вам радианы, а не градусы, просто преобразуйте их в градусы и попробуйте.

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

Или вы можете сохранить точки в массиве и вызвать процедуру DrawPoly, если у вас ее есть.

Если вы хотите заполнить многоугольник, позвоните в FillPoly, если у вас его есть.

1

Вы должны использовать радианы во всех своих расчетах. Вот полная программа, которая показывает, как лучше это сделать:

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

, который не выводит (не причудливой графики, но вы должны получить идею):

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

я написал функцию polygon как по вашей первоначальной спецификации, передавая только две координаты. Как и в стороне, вы не хотите тех abs вызовов в вычислениях для радиуса и угла, потому что:

  • они бесполезны для радиуса (с -n2 = n2 для всех n) ,
  • они плохие для угла, так как это приведет вас к определенному квадранту (неправильная стартовая точка).
+1

не хватают цифр. Попробуйте 3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113305305488204 665213841469519415116094330572703657595919530921861173819326117931173819326117931051185480744623799627495673518857527248912279381830119491298336733624406566430860213949463952247371907021798 – Pete

+0

@Pete, я не могу сказать, пытаетесь ли вы быть забавным от нет. Но даже приближения 355/113 достаточно, чтобы определить автомобиль (3 м) по кругу размером с Землю. Я подозреваю, что вашей версии может быть достаточно, чтобы найти атом в сфере размером с солнечную систему, возможно, немного переборщик для рисования на мониторе. – paxdiablo

+1

Я думаю, что более 8 цифр были бы чрезмерны для такого рода работ - так что помилуй мою хромую попытку шутки :) – Pete

Смежные вопросы