29

我一直试图弄清楚如何编写一个简单的程序来计算 x,y 点以创建 n 边的正多边形。有人可以给我一些不使用绘制多边形的现有函数的代码示例吗?我想了解这个过程,我假设是这样的:

  1. 选择一个角度从半径和中心点开始
  2. 以某种方式计算距中心该距离处的 x,y 位置(如何?)
  3. 将 360 除以边数,移动该距离并从第一个 x,y 点绘制下一条线
  4. 继续直到角度= 360除以该数字。

假设我的假设是正确的,主要是了解如何计算 x,y 点。

更喜欢 Visual Basic(甚至旧式 Microsoft/Atari/Commodore BASIC)或人类可读的英语步骤的答案。如果您必须用数学公式回答,请用计算机语言进行,以便我可以阅读它,即使在 C 或 C++ 中我也可以弄清楚,但我不知道如何阅读数学符号。我使用的语言是一种类似于 Visual Basic 的语言,除了线条绘制之外几乎没有图形基元。

4

6 回答 6

50

假设您要绘制一个半径为r的N边多边形,以 (0,0) 为中心。那么n个顶点由下式给出:

x[n] = r * cos(2*pi*n/N)
y[n] = r * sin(2*pi*n/N)

其中 0 <= n < N。请注意,cos这里sin使用的是弧度,而不是度数(这在大多数编程语言中很常见)。

如果你想要一个不同的中心,那么只需将中心点的坐标添加到每个(x[n]y[n])。如果你想要一个不同的方向,你只需要添加一个恒定的角度。所以一般形式是:

x[n] = r * cos(2*pi*n/N + theta) + x_centre
y[n] = r * sin(2*pi*n/N + theta) + y_centre
于 2011-08-25T22:58:33.717 回答
8
angle = start_angle
angle_increment = 360 / n_sides
for n_sides:
    x = x_centre + radius * cos(angle)
    y = y_centre + radius * sin(angle)
    angle += angle_increment

在实践中,当绘制线条而不是仅仅计算角点时,您还需要通过重复第一个点来“连接”多边形。

此外,如果sin()andcos()以弧度而不是度数工作,则您想要2 * PI而不是360.

于 2011-08-25T22:57:18.493 回答
2

如果您想以一些错误累积为代价使其更快,请使用(复杂的)原始第 n 个单位根并利用它的力量(使用您的语言中的内置复数支持或手动编码乘法) . 在 C 中:

complex double omega=cexp(2*M_PI*I/n), z;
for (i=0, z=1; i<n; i++, z*=omega) {
    /* do something with z */
}
于 2011-08-26T07:01:33.490 回答
2

这是一个完整的 c++ 程序,可以打印出正多边形的点。在这种情况下,p 是边数,r 是多边形的半径,d 是从中心开始的第一个点的方向或角度。也许这会有所帮助。

//g++ ck.cpp -o ck && ./ck
#include <stdio.h>
#include <math.h>

int p=3; //number of sides
double r=1000,d=3/4.0;

int main()
{
 int i=0;
 double x,y,t;
 while(i<p)
 {
  t=2*M_PI*((double)i/p+d);
  x=cos(t)*r;
  y=sin(t)*r;
  printf("x%i:%f y%i:%f\n",i,x,i,y);
  i++;
 }
}
于 2012-04-15T02:59:14.630 回答
1

我知道您在 Visual Basic 中要求回答,但是这里是 JavaScript 中的解决方案

于 2012-07-04T20:47:04.353 回答
1

“for n_sides:”答案是最简单的。对于建议您可以通过使用复数来简化计算的人来说,几乎所有数学库都具有基于表格的 cos() 和 sin() 例程以及有效的插值,因此无需深入研究相对晦涩的解决方案。通常可以初始化一个常规的 n 边形,并且 OpenGL 的硬件缩放用于针对任何特定实例对其进行缩放/转换。

如果您想成为硬核,请预先生成您需要的所有 n 边形并将它们加载到顶点缓冲区中。

顺便说一句,这是 Lua 中的上述解决方案。它只是打印出坐标,但您当然可以自由地在数组/表格中返回坐标。返回的坐标可用于初始化 OpenGL GL_LINE_LOOP 网格图元。

require 'math'

-- computes coordinates for n-sided, regular polygon of given radius and start angle
-- all values are in radians

function polypoints(sides, radius, start)
    local x_center = 0.0
    local y_center = 0.0
    local angle = start
    local angle_increment = 2 * math.pi / sides
    local x=0.0
    local y=0.0

    print(string.format("coordinates for a %d sided regular polygon of radius %d\nVertex",sides,radius),"X"," ","Y")
    for i=1,sides do
        x = x_center + radius * math.cos(angle)
        y = y_center + radius * math.sin(angle)
        print(string.format("%d\t%f\t%f",i,x,y))
        angle = angle + angle_increment
    end
end

-- Generate a regular hexagon inscribed in unit circle 
polypoints(6, 1.0, 0.0)
于 2013-01-03T17:45:48.503 回答