Как нарисовать правильный прямоугольник в декартовых координатах?
Я пытался выяснить, как написать простую программу для вычисления точек x,y для создания правильного многоугольника из n сторон. Может кто-нибудь дать мне несколько примеров кода, в которых не используются уже существующие функции, которые рисуют полигоны? Я хочу понять процесс, который я предполагаю, что-то вроде этого:
- выберите угол, чтобы начать с радиуса и центральной точки
- каким-то образом рассчитать положение x,y на этом расстоянии от центра (как?)
- разделите 360 на количество сторон, переместите это расстояние и нарисуйте следующую линию от первой точки x,y
- продолжайте, пока угол =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.