Skocz do zawartości

Wielokrotne zaginanie liny.


kt1117

Rekomendowane odpowiedzi

Potrzebuję skryptu na wielokrotne zginanie liny, nie musicie mi go podawać na talerzu, wystarczy, że nasuniecie mi jakiś dobry pomysł wprowadzicie w dobry tok myślenia, w zamian mogę napisać skrypt szyfrujący, plecaka, craftowania, coś tego typu.

E:Wystarczy mi w zasadzie znalezienie miejsc zgięć.

Odnośnik do komentarza
Udostępnij na innych stronach

Mam już taki kod:

GML
if collision_line(x,y,czek[zag,0],czek[zag,1],teren,1,0)

{

p=0; //początek przedziału w którym wyszukujemy wyniku

k=10000000; //koniec przedziału

while(p!=k) //w pewnym momencie nasz przedział będzie tak krótki, że będzie zawierał jeden element (p==k). To będzie nasz wynik

{

q=floor((p+k)/2); //Strzelamy w połowę przedziału i zapisujemy do zmiennej q

if(collision_line(x,y,lengthdir_x(q, point_direction(x,y,czek[zag,0],czek[zag,1])),lengthdir_y(q, point_direction(x,y,czek[zag,0],czek[zag,1])),teren,1,0)) //jeśli q spełnia nasz warunek...

k=q; //ucinamy przedział o wszystkie liczby większe od q

else //w przeciwnym wypadku...

p=q+1; //ucinamy przedział o wszystkie liczby mniejsze i równe q (bo q też jest złe więc je też ucinamy, stąd q+1)

}

zag+=1

czek[zag,0]=lengthdir_x(p, point_direction(x,y,czek[zag,0],czek[zag,1]))

czek[zag,1]=lengthdir_y(p, point_direction(x,y,czek[zag,0],czek[zag,1]))

}

Dobrze do tej pory?

E:Już wiem źle, w while powinno być odwrotnie. ;)

E2:A jednak nie.

Odnośnik do komentarza
Udostępnij na innych stronach

Jak wiadomo do programowania trzeba zkwantować naturę :) . Podziel linę na tablicę punktów. Punkty muszą być oddalone o tą samą odległość od siebie. Im mniejsza odległość między punktami tym lepsza dokładność kosztem większej ilości obliczeń. Teraz traktuj każdy punkt jak obiekt (czyli np. działa na niego siła grawitacji) a między puntami rysuj linię. Pozostaje ci tylko zrobić odpowiedni kod, który będzie przesuwał punkty o niewielkie odległości tak, by odległość między punktami zawsze była taka sama. I teraz, jeżeli chwycisz jeden z punktów (czyli m.in zniwelujesz działanie siły grawitacji) pozostałe punkty dalej będą spadać. Ale twój kod nie pozwoli im na zbyt daleki odlot i w efekcie powstanie efekt linii :) .

 

Jedyny problem to ów kod. Poniższy kod pokazuje uogólnienie problemu. Ruchomy jest tylko pierwszy punkt. Ale może ci wystarczy:

GML (Create)
line_num = get_integer("Podaj liczbę punktów na linii", 10)+1; // liczba punktów

line_length = get_integer("Podaj długość linii", 200)/(line_num-1); // odległość między punktami

line_grav = 10; // przyśpieszenie grawitacyjne

// tworzenie tablicy punktów

for (i = 0; i < line_num; i += 1)

{

line_x = 100+line_length*i;

line_y = 100;

}

 

// zmienne zaznaczenia

point_act = -1; // mouse_over

point_sel = -1; // mouse_select</span></span>

 

GML (Step)
// ---------- zaznaczanie ---------- //

// zerowanie zaznaczenia przed aktualizacją

point_act = -1;

if (!mouse_check_button(mb_left)) point_sel = -1;

 

// wyszukiwanie zaznaczenia i najechania

for (i = 0; i < line_num; i += 1)

if (point_distance(line_x, line_y, mouse_x, mouse_y) < 5)

{

if (mouse_check_button_pressed(mb_left)) point_sel = i;

point_act = i;

}

 

// przesunięcie punktu do myszki (jeśli zaznaczony)

if (point_sel >= 0)

{

line_x[point_sel] = mouse_x;

line_y[point_sel] = mouse_y;

}

 

// ---------- kontrola odległości ---------- //

// pętla przyjmuje, że pierwszy punkt jest nieruchomy i tylko jego można przesuwać

// działanie następujące:

// zaczynamy od drugiego punktu (pierwszy niezmienny)

for (i = 1; i < line_num; i += 1)

{

// przesuwamy punkt zgodnie z grawitacją

line_y += line_grav;

// obliczamy, o ile trzeba przesunąć punkt do poprzedniego punktu

point_dist = point_distance(line_x, line_y, line_x[i-1], line_y[i-1])-line_length;

// ustalamy kąt przesunięcia

point_dir = point_direction(line_x, line_y, line_x[i-1], line_y[i-1]);

// przesuwamy ów punkt tam gdzie powinien być

line_x += lengthdir_x(point_dist, point_dir);

line_y += lengthdir_y(point_dist, point_dir);

}

 

GML (Draw)
// efekt zaznaczenia

if (point_sel >= 0)

{

draw_set_color(c_gray);

draw_circle(line_x[point_sel], line_y[point_sel], 3, false);

}

// efekt najechania

else if (point_act >= 0)

{

draw_set_color(c_ltgray);

draw_circle(line_x[point_act], line_y[point_act], 3, false);

}

 

draw_set_color(c_black);

// malowanie dwóch linii pierwszego punktu

draw_line(line_x[0]-10, line_y[0], line_x[0]+10, line_y[0]);

draw_line(line_x[0], line_y[0]-10, line_x[0], line_y[0]+10);

// malowanie linii między punktami

for (i = 1; i < line_num; i += 1)

draw_line_width(line_x[i-1], line_y[i-1], line_x, line_y, 3);

// malowanie punktów

for (i = 0; i < line_num; i += 1)

draw_circle(line_x, line_y, 3, true);

 

A co na to fizyka? Ona rozwiązuje to w ten sposób. Jeśli odległość jest większa niż ma być, "punkty" przyciągane są z tą samą siłą do środka tego odcinka, by odległość wynosiła odpowiednio dużo. Jeśli punkt ma być nieruchomy, to można uznać, że ta siła przechodzi na drugi punkt i tylko on się rusza.

Sposób dobry poza faktem, że te punkty bez przerwy są przesuwane. Jeśli jeden odcinek pasuje to po obliczeniu tego obok nie będzie pasował. Powstaje pętla nieskończona, nigdy odległość nie będzie równa dokładnie 100. Można zrobić oczywiście tylko kilka razy tą pętle i będzie jakiś przybliżony wynik, ale... przyrody całkiem nie odwzorujesz :) .

Odnośnik do komentarza
Udostępnij na innych stronach

Ja mam trochę inny pomysł, czyli taki:

-Sprawdzam czy jest kolizja liniowa między punktami: (czek[zag,0] ,czek[zag,1]) ,a (czek[zag+1,0] ,czek[zag+1,1])

Gdzie punkt (czek[0,0] ,czek[0,1]) to miejsce zaczepienia liny.

-Jeśli tak, to chcę znaleźć taki punkt zgięcia, który jej zapobiegnie.

-Dodaje 1 do zag i dodaje miejsce zagięcia do tablicy.

-Rysuję linę między punktami zgięć.

Odnośnik do komentarza
Udostępnij na innych stronach

Jeśli chcesz dodać odpowiedź, zaloguj się lub zarejestruj nowe konto

Jedynie zarejestrowani użytkownicy mogą komentować zawartość tej strony.

Zarejestruj nowe konto

Załóż nowe konto. To bardzo proste!

Zarejestruj się

Zaloguj się

Posiadasz już konto? Zaloguj się poniżej.

Zaloguj się
  • Ostatnio przeglądający   0 użytkowników

    • Brak zarejestrowanych użytkowników przeglądających tę stronę.
×
×
  • Dodaj nową pozycję...