Как нарисовать правильный прямоугольник в декартовых координатах?

Я пытался выяснить, как написать простую программу для вычисления точек x,y для создания правильного многоугольника из n сторон. Может кто-нибудь дать мне несколько примеров кода, в которых не используются уже существующие функции, которые рисуют полигоны? Я хочу понять процесс, который я предполагаю, что-то вроде этого:

  1. выберите угол, чтобы начать с радиуса и центральной точки
  2. каким-то образом рассчитать положение x,y на этом расстоянии от центра (как?)
  3. разделите 360 на количество сторон, переместите это расстояние и нарисуйте следующую линию от первой точки x,y
  4. продолжайте, пока угол =360 не делится на это число.

Предполагая, что мои предположения верны, главное - понять, как вычислить точки x,y.

Предпочитайте ответы в визуальной базовой форме (или даже в старом стиле Microsoft/Atari/Commodore BASIC) или в удобочитаемом наборе шагов на английском языке. Если вам нужно ответить математической формулой, сделайте это на компьютерном языке, чтобы я мог ее прочитать, даже в C или C++ я могу это понять, но я не знаю, как читать математические обозначения. Язык, который я использую, похож на язык Visual Basic, который почти не имеет графических примитивов, кроме рисования линий.

6 ответов

Решение

Предположим, вы хотите нарисовать N- сторонний многоугольник радиуса r с центром в (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
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,

Ответ "for n_sides:" является самым простым. Для парня, который предположил, что вы могли бы упростить вычисления с помощью комплексных чисел, почти во всех математических библиотеках есть основанные на таблицах подпрограммы cos() и sin() с эффективной интерполяцией, поэтому нет необходимости углубляться в относительно неясные решения. Обычно обычный n-gon может быть инициализирован, а аппаратное масштабирование 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)

Вот полная программа на С ++, которая распечатывает точки правильного многоугольника. В этом случае 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++;
 }
}

Если вы хотите сделать это быстрее за счет накопления некоторых ошибок, используйте (сложный) примитив n-го корня единицы и возьмите его полномочия (либо используя встроенную поддержку комплексных чисел в вашем языке, либо кодируя умножение вручную), В С:

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

Я знаю, что вы просили дать ответ в Visual Basic, однако здесь есть решение в JavaScript.

Другие вопросы по тегам