Как нарисовать правильный прямоугольник в декартовых координатах? - PullRequest
22 голосов
/ 26 августа 2011

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

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

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

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

Ответы [ 6 ]

39 голосов
/ 26 августа 2011

Предположим, вы хотите нарисовать N -сторонний многоугольник радиуса r с центром в (0,0). Тогда вершины n определяются как:

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

, где 0 <= <em>n <<em> 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
6 голосов
/ 26 августа 2011
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.

2 голосов
/ 15 апреля 2012

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

Если вы хотите сделать это быстрее за счет некоторого накопления ошибок, используйте (сложный) примитив 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 */
}
1 голос
/ 03 января 2013

Ответ "для 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)
1 голос
/ 05 июля 2012

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

...