Autor Wątek: Spreżyna 2D (x,y)  (Przeczytany 3463 razy)

Offline Vizzzard

  • Użytkownik

# Sierpień 09, 2007, 09:57:58
Witajcie Drodzy Fizycy, Naukowcy i Programiści :D

mam problem ze stowrzeniem liny spręzyonej która poruszała by sie nie tylko góra dół np ale w 2 wymiarach w zaleznosci od rozciągniecia, o ile 1D poszło głoadko to 2D juz jakies zagmatwane dla mnie jest  ??? znalazłem symulację http://www.myphysicslab.com/spring2d.html oraz kod do owej symualcji ftp://www.myphysicslab.com/source/code/com/myphysicslab/simlab/Spring2DSim.java ale jakos ni jak tego kodu idzie zrozumiec, implementacja tej sprezyny jest na samym dole pliku i zapewne wzory są całkiem ok ale brakuje kodu dodajacego wartosci do x i y :/

moze ktos zna prostrzą implementacje, bardziej zrozumiałą lub wie jak to przerobic zeby chodziło bez zarzutu, bo niebardzo wiem które zmienne w tamtym kodzie są X i Y kuli na spręzynie :D bo walcze z tym kodem z dobre 3 dni i nic.

oczywiscie inne porady i implementacje 2D Spręzyny mile widziane,

z góry dziekuje za wszelkie odpowiedzi.

zamieszczam ten kod gdyby sie komus link nie otwierał   /* 2-D spring simulation with gravity
    spring is suspended from top mass
    origin = bottomleft corner
    th = angle formed with vertical, positive is counter clockwise

    L = displacement of spring from rest length
    R = rest length
    U = position of CENTER of bob
    S = position of spring's X1,Y1 point
    V = velocity of bob
    k = spring constant
    b = damping constant
    m = mass of mass
    w = width (radius) of bob

    Fx = -kL sin(th) -bVx = m Vx'
    Fy = -mg +kL cos(th) -bVy = m Vy'
    xx = Ux - Sx
    yy = -Uy + Sy
    len = Sqrt(xx^2+yy^2)
    L = len - R
    th = atan(xx/yy)
    cos(th) = yy / len
    sin(th) = xx / len

    so here are the four variables and their diffeq's
    vars[0] = Ux
    vars[1] = Uy
    vars[2] = Vx
    vars[3] = Vy
    Ux' = Vx
    Uy' = Vy
    Vx' = -(k/m)L sin(th) -(b/m)Vx
    Vy' = g + (k/m)L cos(th) -(b/m)Vy
  */
  // implementation of DiffEq protocol
  public void evaluate(double[] x, double[] change) {
    double xx, yy, len, m, r, b;
    m = bob.m_Mass;
    b = m_Damping;
    // find current length of the spring
    xx = x[0] - spring.m_X1;  //xx = Ux - Sx
    yy = -x[1] + spring.m_Y1;  //yy = -Uy + Sy
    len = Math.sqrt(xx*xx + yy*yy);  //len = Sqrt(xx^2+yy^2)

    change[0] = x[2]; // Ux' = Vx

    change[1] = x[3]; // Uy' = Vy

    //Vx' = -(k/m)L sin(th) = -(k/m)*(len - R)*(xx/len)
    r = -(spring.m_SpringConst/m)*(len - spring.m_RestLength) * xx / len;
    if (b != 0)
      r -= (b/m)*x[2];  // damping:  - (b/m) Vx
    change[2] = r;

    //Vy' = -g + (k/m)L cos(th) = -g + (k/m)*(len-R)*(yy/len)
    r = -gravity + (spring.m_SpringConst/m)*(len - spring.m_RestLength) * yy / len;
    if (b != 0)
      r -= (b/m)*x[3];  // damping:  - (b/m) Vy
    change[3] = r;
  }

ostro pogmatwany :D

Offline Mr. Spam

  • Miłośnik przetworów mięsnych

Offline Złośliwiec

  • Użytkownik
    • Dark Cult

# Sierpień 09, 2007, 10:13:20
Pamiętam ze szkoły taki prosty wzorek:

[tex]
E_p = \frac{{kx^2 }}{2}
[/tex]

Jest prawdziwy tylko przy założeniu, że siła jest liniowo zależna od x, ale jeśli nie chcesz się babrać w takich rzeczach jak ta zacytowana, to powinno ci to wystarczyć :).

PS. Na drugi raz proszę pisać po polsku.
« Ostatnia zmiana: Sierpień 09, 2007, 10:31:26 wysłana przez Złośliwiec »

Offline Vizzzard

  • Użytkownik

# Sierpień 09, 2007, 11:10:01
twoj wzór jest na x, a ja potebuje x i y wiec nic to nieda. Pozatym jak otwierałes link który podałem wraz a Apletem tej symulacji to wiesz ze siła nie jest linjowo zalena od x a od x,y :)

Offline Hadrian W.

  • Użytkownik
    • Homepage

# Sierpień 09, 2007, 12:09:54
Vizzzard: x w tym wypadku to położenie końca sprężyny względem położenia równowagi (znak jest znaczący). Przy zastosowaniu wektorów wyliczenie całości jest banalne. Coś w ten deseń z tego pseudo kodu :P
// Początek sprężyny
vector begin;
// koniec sprężyny
vector end;
// położenie równowagi
float balance = 24.0f;
// no w sumie sprezyna :P
vector spring(end-begin);
float length=spring.length();
// sila
vector force=spring.normalise();

force *= (balance-length)*k;

// no i siłę przykładamy do końca sprężyny jak sobie chcemy

^MAŁY EDIT
« Ostatnia zmiana: Sierpień 09, 2007, 12:25:02 wysłana przez Queight »

Offline Vizzzard

  • Użytkownik

# Sierpień 09, 2007, 13:12:38
no ciekawe, a czemu nie uzyłes odległosci w postaci pierwiastka kwadratowego, bo w orginalny kodzie sie z tym spotkałem? No chyba ze masz to na myśli a ja tego nie widze bo zaspany jestem :D

oczywiscie sprawdze twój kod i napisze

Offline Hadrian W.

  • Użytkownik
    • Homepage

# Sierpień 09, 2007, 13:50:29
Ten kod jest przy założeniu posiadania klasy wektora z przeciążonymi operatorami i paroma dodatkowymi metodami jak length() i normalise(). No i właśnie w length() uzyskuje się długość wektora z pomocą pierwiastka kwadratowego.

Offline Vizzzard

  • Użytkownik

# Sierpień 09, 2007, 14:14:36
aha nie no orjentuje sie w przeciązeniach i wiem jak sobie z nimi poradzic, ja coprawda niemam tego w kodzie ale posiadam struktury i funckje w niej działajacą bardzo podbno :)

czas na implementacje, w razie niejasnosci napisze :)

Offline Vizzzard

  • Użytkownik

# Sierpień 09, 2007, 15:20:53
nic z tego, wiedziałem ze to bedzie twardy psiak :D, wynik jest taki ze bila przeskakuje z punktu do punku (pojawia sie i znika) ale to akurat wynika z predkosci podzielenie tego przez wartosc zwolni animacje. Lecz to nie jest to zupełnie, sprezyna z kulą spezynuje w 1 koncie tył przod, widze ze nikt nie pofatygowal sie o obejrzenie apletu ;D.

sprezyna 2D ma mozliwosc ruchomosci o 360 stopni zachowuje sie jak staw, lina tyle ze spręzynuje

o to mi codzi http://www.myphysicslab.com/spring2d.html

no chyba ze ten kod ma własnie tak działać, a ja go jakos zle przepisałem

float sx_begin = 100; //poczatek spezyny
float sy_begin = 100;

float sx_end = 110; //koniec spezyny
float sy_end = 110;

float balance = 37.0f;

// no w sumie sprezyna :P
float springx = (sx_end-sx_begin);
float springy = (sy_end-sy_begin);

float length= sqrt(springx*springx + springy*springy);
// sila
float forcex= springx/length;
float forcey= springy/length;

forcex *= (balance-length)*k; //k=3
forcey *= (balance-length)*k;

mBall[1].x += forcex; //dodawanie wektorów do pozycji kuli na sprezynie
mBall[1].y += forcey;

sx_end = mBall[1].x; //teraz koniec sprezyny jest w miejscu kuli
sy_end = mBall[1].y;

Offline Hadrian W.

  • Użytkownik
    • Homepage

# Sierpień 09, 2007, 15:36:46
Ekhem... Tak z grubsza. Jednostką siły jest N, a położenia metry (w tym wypadku pixele :P). Nie można dodać od tak sobie siły do położenia, bo mamy niezgodność jednostek.
siła = przyspieszenie*masa
No i sobie przelicz co trzeba, żeby dojść od siły do położenia.
« Ostatnia zmiana: Sierpień 09, 2007, 15:39:25 wysłana przez Queight »

Offline Vizzzard

  • Użytkownik

# Sierpień 09, 2007, 15:42:09
no i myślisz ze jak to poprawnie przelicze i wtedy dodam te Vektory do połozenia kuli to otrzymam cos na wzór tej animacji z Linka? ???

Offline snakeo

  • Użytkownik

# Sierpień 09, 2007, 15:47:50
Tutaj jest bardzo ładnie opisana sprężynka, korzystając z tego ostatnio sobie zaimplementowałem i dodałem tłumienie z tej stronki co ty podajesz ;]
Ogólnie ten kod z nehe jest bardzo przydatny, bo jest to niejako podstawa enginu fizycznego, który można potem rozbudowywać ;]
« Ostatnia zmiana: Sierpień 09, 2007, 15:49:42 wysłana przez snakeo »

Offline Hadrian W.

  • Użytkownik
    • Homepage

# Sierpień 09, 2007, 16:03:45
Vizzzard: ogólnie brakuje Ci zależności od czasu.... No i musisz pamiętać, że czasem trochę trzeba siedzieć przy dobieraniu poszczególnych współczynników. Można dodać jakąś grawitację etc.
« Ostatnia zmiana: Sierpień 09, 2007, 16:06:29 wysłana przez Queight »

Offline Vizzzard

  • Użytkownik

# Sierpień 09, 2007, 16:09:47
snakeo 1D sprezyne to ja juz mam i chce 2D odpaliłem exe z tej lekcji Nehe i jest to spręzynka 1D a to zupełnie mi sie nie przyda niestety  :'(

Offline Vizzzard

  • Użytkownik

# Sierpień 09, 2007, 16:13:32
Queight, moge pomnożyć te vektory sił przez dt ale niewiele mi to da, pozatym w mojej symuacji mam grawitacje. Dlatego te kody nie są raczej odpowiednie, te co podałem na początku których nietety nie rozumiem zbytnio najpewniej są ok poniewarz to jest kod apletu symulujący tą sprężynę, ale weź pan to zrozum :D

moze jeszcze jakies propozycje, bo mnie sie juz pomysły kończą na ta symulacje 1D idzie 2D wydawało by sie ze trzeba dodac Vektor Y ale jak widac to duzo bardziej skomplikowane. :(

Offline snakeo

  • Użytkownik

# Sierpień 09, 2007, 16:19:09
Vizzard: ale to nie jest sprezyna 1d, to jest jak najbardziej sprezyna 3d, musisz tylko w konstruktorze klasy odpowiedzialnej za symulacje sprezyny, czyli MassConnectedWithSpring w linijce gdzie masz cos takiego: masses[0]->vel = Vector3d(0.0f, 0.0f, 0.0f); zmienic np na 1, ktorys z parametrow, w ten sposob nadajesz predkosc poczatkowa masie wiszacej na sprezynie, w ktoryms z kierunkow (x,y,z) ;] Chyba, ze przez sprezyne 3d rozumiesz cos innego... Domyslnie predkosc ta jest na 0 w kazdym z kierunkow, wiec symulacja tej sprezyny to tylko jakby powieszenie masy na niej, a tamto co napisalem to jak pchniecie/pociagniecie palcem ;)
« Ostatnia zmiana: Sierpień 09, 2007, 16:23:53 wysłana przez snakeo »