Jak narysować N jednostronny wielokąt regularny we współrzędnych kartezjańskich?

Próbowałem dowiedzieć się, jak napisać prosty program do obliczania punktów x,y do tworzenia regularnego wielokąta N boków. Może mi ktoś podać jakieś przykłady kodu, które nie używają wcześniej istniejących funkcji rysujących wielokąty? Chcę zrozumieć proces, który zakładam, że jest podobny do tego:

  1. Wybierz kąt, aby rozpocząć od promienia i punktu środkowego
  2. jakoś obliczyć pozycję x,y w tej odległości od centrum(jak?)
  3. podziel 360 przez liczba boków, przesuń tę odległość i narysuj następną linię od pierwszego punktu x, Y
  4. Kontynuuj do kąta = 360 podzielonego przez tę liczbę.

Zakładając, że moje założenia są poprawne, najważniejsze jest zrozumienie, jak obliczyć punkty x, y.

Preferuj odpowiedzi w visual basic (lub nawet w starym stylu Microsoft / Atari / Commodore BASIC) lub czytelny dla człowieka zestaw kroków w języku angielskim. Jeśli musisz odpowiedzieć formułą matematyczną, zrób to w języku komputerowym, żebym mógł czytać to, nawet w C lub c++ mogę to rozgryźć, ale nie wiem jak czytać notację matematyczną. Język, którego używam, jest językiem podobnym do Visual Basica, który nie ma prawie żadnych prymitywów graficznych innych niż rysowanie linii.

Author: alphablender, 2011-08-26

6 answers

Załóżmy, że chcesz narysować N-wielokąt o promieniu r , wyśrodkowany na (0,0). Następnie N wierzchołki są podane przez:

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

Gdzie 0 n N . Zauważ, że cos i sin tutaj działają w radianach, a nie stopniach (jest to dość powszechne w większości języków programowania).

Jeśli chcesz mieć inny środek, po prostu dodaj współrzędne punktu środkowego do każdego ( x [n], y [n] ). Jeśli chcesz inny orientacja, wystarczy dodać stały kąt. Tak więc ogólna forma to:

x[n] = r * cos(2*pi*n/N + theta) + x_centre
y[n] = r * sin(2*pi*n/N + theta) + y_centre
 35
Author: Oliver Charlesworth,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-08-25 22:58:33
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

W praktyce, podczas rysowania linii zamiast tylko obliczania punktów narożnych, należy również" połączyć " wielokąt powtarzając pierwszy punkt.

Również, Jeśli sin() i cos() pracują w radianach, a nie stopniach, chcesz 2 * PI zamiast 360.

 6
Author: andrew cooke,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-08-25 22:57:18

Oto pełny program c++, który wypisuje punkty regularnego wielokąta. W tym przypadku p to liczba boków, r to promień wielokąta, A d to kierunek lub kąt pierwszego punktu od środka. Może to pomoże.

//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
Author: Chandler Isaac Klebs,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-04-15 02:59:14

Jeśli chcesz zrobić to szybciej kosztem jakiejś nagromadzenia błędów, użyj (złożonego) prymitywnego n-tego pierwiastka jedności i przejmij jego moce (albo używając wbudowanej obsługi liczb złożonych w Twoim języku lub kodując mnożenie ręcznie). W 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 */
}
 2
Author: R..,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-08 00:02:43

Wiem, że prosiłeś o odpowiedź w Visual Basic, jednak Oto rozwiązanie w JavaScript.

 1
Author: CrazyTim,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-07-04 20:47:04

ODPOWIEDŹ "for n_sides:" jest najłatwiejsza. Dla faceta, który zasugerował, że można uprościć obliczenia używając liczb złożonych, prawie wszystkie biblioteki matematyczne mają procedury cos() i sin() oparte na tabelach z efektywną interpolacją, więc nie ma potrzeby zagłębiania się w stosunkowo niejasne rozwiązania. Zazwyczaj zwykły n-gon może być zainicjalizowany i sprzętowe skalowanie OpenGL używane do skalowania / przekształcania go dla dowolnej konkretnej instancji.

If you want to be hardcore about it, wstępnie Wygeneruj wszystkie potrzebne n-gony i załaduj je do buforów wierzchołków.

Na marginesie, oto powyższe rozwiązanie w Lua. Po prostu wypisuje współrzędne, ale oczywiście możesz zwrócić współrzędne w tablicy / tabeli. Zwrócone współrzędne mogą być użyte do zainicjalizowania siatki 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
Author: eris0xff,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-03 17:45:48