用C语言画一个多边形
题
我需要绘制一个“n”边的多边形,给定 2 个点(中心和顶点 1),只是我在数学上很烂。我读了很多书,所有这些都是我能够弄清楚的(我不知道它是否正确):
好的,我用毕达哥拉斯定理计算两点之间的距离(半径):
sqrt(pow(abs(x - xc), 2) + pow(abs(y - yc), 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 处理这个图形基元。
编辑:我不想填充多边形,只是绘制它。
解决方案
考虑什么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
). - 它们不利于角度,因为这会迫使您进入特定的象限(错误的起点)。
我不会只给你答案,但我有一些建议。首先,学习白描是如何工作的专家。当你有这样下来,试着写一个实心三角形渲染器。 通常,填充多边形绘制在时间1条水平扫描线,从上到下。你的任务是确定启动和停止x坐标为每一个扫描线。请注意,一个多边形的边如下的直线(提示,提示)...:)
您正在尝试绘制填充聚我猜?
如果你要尝试绘制使用线原始的多边形,你将有很多的痛苦来给你的。 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如果你有一个。