Seite 1 von 2

Inverse Kinematik

Verfasst: 22.04.2005 13:35
von Skiller
Hi Folks,

keine Beiträge dazu!! Hat sich noch nie jemand damit beschäftigt?
Wollte mal die Basics wissen, bevor ich da richtig einsteigen würde. Weil wenn mit PB nicht möglich fang ich gar nicht erst an.

Skiller

Verfasst: 22.04.2005 14:29
von NicTheQuick
Was ist denn Inverse Kinematik.

Verfasst: 22.04.2005 14:38
von Kiffi
> Was ist denn Inverse Kinematik.

http://de.wikipedia.org/wiki/Inverse_Kinematik

Verfasst: 22.04.2005 14:54
von Zaphod
inverse kinematik ist mit praktisch jeder programmiersprache möglich umzusetzen. wenn du aber meinst, ob purebasic dafür funktionen gleich mitbringt, dann ist die antwort nein.

Verfasst: 22.04.2005 18:45
von Skiller
Cool wäre jetzt natürlich irgend ein kleines Programmbeispiel, um zu sehen wie man z. B. zwei Glieder in Abhängigkeit zu einander bewegt. Also welche programmtischen Regeln. Alles was ich bisher gesehen habe stand als Makro in z. B. Max o. Studio 3D Designern etc. zur Verfügung. Daraus geht aber nicht hervor wie. Ich könnte natürlich experiemtiern, aber besser wäre natürlich ein "souveränes" Beispiel in PB. Vielleicht Google ich mal durch und finde was um es zu übertragen. Ansonsten könnt Ihr mir ja vielleicht noch ein paar Links o. Tips bereithalten. So long...
Skiller

Verfasst: 22.04.2005 18:49
von Zaphod

Verfasst: 22.04.2005 21:26
von Skiller
Danke Zaphod, jetzt sind wir schon ein Schritt weiter. Werde aber zusätzlich weiter nach Progrämmchen suchen müssen. In der zwischenzeit kann ich ja mal mit dem aufdröseln anfange u. versuchen nen primitives PB-Beispiel zu realisiern. Melde mich in spätestens 6 Monaten zu diesem thema zurück. :mrgreen: . Trotzdem sollte dieses thema im Thread nicht vernachlässigt werden!!!! Wäre gut, wenn ihr dranbleibt.

Skiller

Verfasst: 24.04.2005 09:07
von robink
Hier ist auch noch was dazu:
http://freespace.virgin.net/hugo.elias/models/m_ik.htm
http://freespace.virgin.net/hugo.elias/models/m_ik2.htm
Ich habe natürlich keine Ahnung ob es nützlich ist da ich
mich damit nicht auskenne...

Verfasst: 24.04.2005 10:55
von robink
Mir war gerade mal langweilig, da habe ich ein wenig rumgespielt,
ein code der ein array mit den entfernungen anlegt und sich die
niedrigste raus sucht: (ist langsam, aber sieht schön aus)

Code: Alles auswählen

Dim DistArray.f(359, 359)

#PI = 3.14159265
Global ta, tb, tx, ty, a, b
a = 180
ax = 0
ay = 0
b = 0
bx = 0
by = 0
tx = 250
ty = 500
speeda = 1
speedb = 1


Procedure.f Dist(x1, y1, x2, y2)
  ProcedureReturn Sqr((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1))
EndProcedure 

Procedure CreateDistArray()
  For ca = -180 To 179
    For cb = -180 To 179
      ax = 512 + Sin(ca * #PI/180) * 300
      ay = 767 + Cos(ca * #PI/180) * 300 
      bx = ax + Sin((ca+cb) * #PI/180) * 200
      by = ay + Cos((ca+cb) * #PI/180) * 200
      If ay > 767 Or by > 767
        DistArray(ca + 180, cb + 180) = 999999999
      Else
        DistArray(ca + 180, cb + 180) = Dist(bx, by, tx, ty)
      EndIf       
    Next
  Next
EndProcedure

Procedure SearchNearestPoint()
  dist.f = 9999999999
  dd = 9999999999
  For ca = -180 To 179
    For cb = -180 To 179
      da = a - ca
      If da > 180
        da = da - 360
      EndIf 
      If da < -180
        da = da + 360
      EndIf   
  
      db = b - cb
  
    
      If db > 180
        db = db - 360
      EndIf 
      If db < -180
        db = db + 360
      EndIf   
      d = Abs(da) + Abs(db)
      If DistArray(ca + 180, cb + 180) < dist Or (DistArray(ca + 180, cb + 180) = dist And  d < dd)
        ta = ca
        tb = cb
        dd = d                  
        
        dist = DistArray(ca + 180, cb + 180)
      EndIf 
    Next
  Next
EndProcedure

If InitSprite() = 0 Or InitMouse() = 0 Or InitKeyboard() = 0 Or OpenScreen(1024, 768, 32, "") = 0
  End
EndIf

Repeat  
  tx = MouseX()
  ty = MouseY()
  If tx <> otx Or ty <> oty
    CreateDistArray()
    SearchNearestPoint()
  EndIf   
  otx = tx
  oty = ty
  
  da = a - ta    
  
  If da > 180
    da = da - 360
  EndIf 
  If da < -180
    da = da + 360
  EndIf   
  
  If speeda > 1
    speeda - 1
  EndIf 
  If Abs(da) >= 20 And speeda < 5
    speeda + 2
  EndIf 
  
  db = b - tb
  
    
  If db > 180
    db = db - 360
  EndIf 
  If db < -180
    db = db + 360
  EndIf   
  
  If speedb > 1
    speedb - 1
  EndIf 

  If Abs(db) >= 20 And speedb < 5
    speedb + 2
  EndIf 
     
  If da > 0    
    a - speeda
  ElseIf da < 0
    a + speeda
  EndIf 
  
  If db > 0
    b - speedb
  ElseIf db < 0
    b + speedb
  EndIf 
  
  StartDrawing(ScreenOutput())  
  Circle(tx, ty, 2, RGB(255, 0, 0))  
  LineXY(tx - 4, ty - 4, tx + 4, ty + 4, RGB(255, 0, 0))
  LineXY(tx + 4, ty - 4, tx - 4, ty + 4, RGB(255, 0, 0))  
  
  ax = 512 + Sin(a * #PI/180) * 300
  ay = 767 + Cos(a * #PI/180) * 300
  LineXY(512, 767, ax, ay, RGB(0, 0, 0))
  Circle(ax, ay, 4, RGB(0, 0, 0))
  Circle(ax, ay, 3, RGB(0, 0, 0))
  Circle(ax, ay, 2, RGB(0, 0, 0))
  Circle(ax, ay, 1, RGB(0, 0, 0))
  
  bx = ax + Sin((a+b) * #PI/180) * 200
  by = ay + Cos((a+b) * #PI/180) * 200
  LineXY(ax, ay, bx, by, RGB(0, 0, 0))
  Circle(bx, by, 4, RGB(0, 0, 0))
  Circle(bx, by, 3, RGB(0, 0, 0))
  Circle(bx, by, 2, RGB(0, 0, 0))
  Circle(bx, by, 1, RGB(0, 0, 0))
  
  StopDrawing()
  FlipBuffers()
  ClearScreen(255, 255, 255)
  Delay(10)
  ExamineKeyboard()
  ExamineMouse()
Until KeyboardPushed(#PB_Key_Escape) 
Und eins das nach dem Gefälle geht, ohne vorher viel zu rechnen,
ist deswegen auch schneller sieht aber nicht so schön aus und
schafft es manchmal nicht ;) :

Code: Alles auswählen

#PI = 3.14159265
a = 180
Global ax, ay, bx, by
ax = 0
ay = 0
b = 0
bx = 0
by = 0
tx = 250
ty = 500
dist1.f
dist2.f
gradienta.f
gradientb.f

Procedure Vector(a, b) 
  ax = 512 + Sin(a * #PI/180) * 200
  ay = 767 + Cos(a * #PI/180) * 200  
  bx = ax + Sin((a+b) * #PI/180) * 200
  by = ay + Cos((a+b) * #PI/180) * 200  
EndProcedure 

Procedure.f Dist(x1, y1, x2, y2)
  ProcedureReturn Sqr((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1))
EndProcedure 

If InitSprite() = 0 Or InitMouse() = 0 Or InitKeyboard() = 0 Or OpenScreen(1024, 768, 32, "") = 0
  End
EndIf

Repeat  
  tx = MouseX()
  ty = MouseY()  
  
  StartDrawing(ScreenOutput())  
  Circle(tx, ty, 2, RGB(255, 0, 0))  
  LineXY(tx - 4, ty - 4, tx + 4, ty + 4, RGB(255, 0, 0))
  LineXY(tx + 4, ty - 4, tx - 4, ty + 4, RGB(255, 0, 0))  
  
  Vector(a, b)
  
  LineXY(512, 767, ax, ay, RGB(0, 0, 0))
  Circle(ax, ay, 4, RGB(0, 0, 0))
  Circle(ax, ay, 3, RGB(0, 0, 0))
  Circle(ax, ay, 2, RGB(0, 0, 0))
  Circle(ax, ay, 1, RGB(0, 0, 0))
  
  LineXY(ax, ay, bx, by, RGB(0, 0, 0))
  Circle(bx, by, 4, RGB(0, 0, 0))
  Circle(bx, by, 3, RGB(0, 0, 0))
  Circle(bx, by, 2, RGB(0, 0, 0))
  Circle(bx, by, 1, RGB(0, 0, 0))  
  StopDrawing()
  Vector(a + 1, b)
  If ay > 767 Or by > 767 
    dist1 = 999999999
  Else
    dist1 = Dist(tx, ty, bx, by)
  EndIf   
  Vector(a - 1, b)  
  If ay > 767 Or by > 767 
    dist2 = 999999999
  Else
    dist2 = Dist(tx, ty, bx, by)
  EndIf   
  gradienta = dist1 - dist2
  Vector(a, b + 1)
  If ay > 767 Or by > 767 
    dist1 = 999999999
  Else
    dist1 = Dist(tx, ty, bx, by)
  EndIf 
  Vector(a, b  - 1)  
  If ay > 767 Or by > 767 
    dist2 = 999999999
  Else
    dist2 = Dist(tx, ty, bx, by)
  EndIf   
  gradientb = dist1 - dist2  
  
  If gradienta > 0
    a - 1
  ElseIf gradienta < 0
    a + 1
  EndIf 
  
  If gradientb > 0
    b - 1
  ElseIf gradientb < 0
    b + 1
  EndIf 
  
  FlipBuffers()
  ClearScreen(255, 255, 255)
  Delay(10)
  ExamineKeyboard()
  ExamineMouse()
Until KeyboardPushed(#PB_Key_Escape) 
Entschuldigt den total unübersichtlichen code, es ist einfach noch
zu früh morgens ;)

Verfasst: 24.04.2005 12:40
von AndyX
Ehm sag mal, ist das nicht beides der selbe Code?! :? Ansonsten sieht es gut aus! :allright:

Greetz,
AndyX