Нарисуйте многоугольник в C
Мне нужно нарисовать многоугольник из "n" сторон, учитывая 2 точки (центр и 1 его вершины), которые мне просто нужны. Я много читал, и все это то, что я смог понять (я не знаю, правильно ли это):
Хорошо, я беру расстояние между 2 точками (радиус) с теоремой Пифагора:
sqrt(pow(abs(x - xc), 2) + pow(abs(y - yc), 2));
И угол между этими 2 точками с atan2, вот так:
atan2(abs(y - yc), abs(x - xc));
Где xc, yc - центральная точка, а x, y - единственная известная вершина.
И с этими данными я делаю:
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 и Turbo C.
Изменить: я не хочу, чтобы заполнить многоугольник, просто нарисуйте его.
6 ответов
Посмотрим что 360/sides
на самом деле возвращается, если sides
не фактор 360 (это целочисленное деление - посмотрите, что на самом деле возвращает 360/7).
Нет необходимости использовать градусы вообще - используйте 2*Math_PI/(double)nsides
и работать в радианах.
также вы можете опустить последнюю строку, используя функцию модуля (модуль nsides).
Если у вас более 7 сторон, вы не сможете хранить все очки. Вам не нужно хранить все точки, если вы просто рисуете многоугольник, а не сохраняете его - только последнюю точку и текущую.
Вы должны использовать радианы во всех ваших расчетах. Вот полная программа, которая иллюстрирует, как лучше всего это сделать:
#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
вызывает в ваших расчетах радиус и угол, потому что:
- они бесполезны для радиуса (так как
-n
2
знак равноn
2
для всехn
). - они плохо влияют на угол, так как это приведет вас к определенному квадранту (неправильная отправная точка).
Вы пытаетесь нарисовать заполненную поли, я думаю?
Если вы попытаетесь нарисовать полис с помощью примитива линии, вам будет очень больно. Dicroce действительно дал вам очень хороший совет по этому вопросу.
Лучше всего найти примитив, который заполняет вас, и предоставить ему список координат. Это зависит от вас, чтобы определить координаты, чтобы дать его.
Я думаю, что главная проблема заключается в: atan2(abs(y - yc), abs(x - xc));
дает вам радианы, а не градусы, просто конвертируйте его в градусы и попробуйте.
/* 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 горизонтальной линии сканирования за раз, сверху вниз. Ваша задача - определить начальную и конечную координату x для каждой строки сканирования. Обратите внимание, что край многоугольника следует за прямой линией (подсказка, подсказка)...:)