关于语言不可知论:如何在笛卡尔坐标系中绘制一个n边正多边形?

How to draw a n sided regular polygon in cartesian coordinates?

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

  • 从半径和圆心开始选取一个角度
  • 以某种方式计算x,y在距离中心的位置(如何?)
  • 将360除以边数,移动该距离并从第一个x,y点绘制下一条线。
  • 继续,直到角度=360除以该数字。
  • 假设我的假设是正确的,主要的事情是理解如何计算x,y点。

    更喜欢用VisualBasic(甚至是老式的Microsoft/Atari/CommodoreBasic)或一组人类可读的英文步骤回答。如果你必须用数学公式回答,那就用计算机语言做,这样我就可以阅读它,即使在C或C++中我也能理解,但我不知道怎样读数学符号。我使用的语言是一种类似于VisualBasic的语言,除了线条绘制,几乎没有其他图形原语。


    假设你想画一个半径为r,以(0,0)为中心的N边多边形。然后n个顶点由以下公式给出:

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

    其中0<=ncos和sin是以弧度工作的,而不是以度数(这在大多数编程语言中很常见)。

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

    1
    2
    x[n] = r * cos(2*pi*n/N + theta) + x_centre
    y[n] = r * sin(2*pi*n/N + theta) + y_centre


    1
    2
    3
    4
    5
    6
    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()cos()以弧度而不是度数工作,则需要2 * PI而不是360


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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    //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
    ",i,x,i,y);
      i++;
     }
    }

    如果你想以错误积累为代价使它更快,可以使用一个(复杂的)单位的n个根,并利用它的力量(或者在你的语言中使用内置的复数支持,或者手工编码乘法)。在C:

    1
    2
    3
    4
    complex double omega=cexp(2*M_PI*I/n), z;
    for (i=0, z=1; i<n; i++, z*=omega) {
        /* do something with z */
    }


    答案是最简单的。对于建议通过使用复数来简化计算的人来说,几乎所有的数学库都有基于表的cos()和sin()例程以及高效的插值,因此无需深入研究相对模糊的解决方案。通常,一个规则的n-gon可以被初始化,OpenGL的硬件伸缩用于为任何特定实例缩放/转换它。

    如果你想成为它的核心,可以预先生成你需要的所有n-gon,并将它们加载到顶点缓冲区中。

    顺便说一句,这是上面在Lua中的解决方案。它只打印出坐标,但您当然可以自由返回数组/表中的坐标。返回的坐标可用于初始化OpenGL GL_Line_Loop Mesh原语。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    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
    Vertex",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)

    我知道你在VisualBasic中要求答案,但是这里有一个JavaScript解决方案。