Inverse Kinematik

Fragen zu Grafik- & Soundproblemen und zur Spieleprogrammierung haben hier ihren Platz.
Skiller
Beiträge: 151
Registriert: 04.02.2005 22:26

Inverse Kinematik

Beitrag 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
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8812
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Beitrag von NicTheQuick »

Was ist denn Inverse Kinematik.
Benutzeravatar
Kiffi
Beiträge: 10715
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Beitrag von Kiffi »

> Was ist denn Inverse Kinematik.

http://de.wikipedia.org/wiki/Inverse_Kinematik
Benutzeravatar
Zaphod
Beiträge: 2875
Registriert: 29.08.2004 00:40

Beitrag 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.
Skiller
Beiträge: 151
Registriert: 04.02.2005 22:26

Beitrag 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
Benutzeravatar
Zaphod
Beiträge: 2875
Registriert: 29.08.2004 00:40

Beitrag von Zaphod »

Skiller
Beiträge: 151
Registriert: 04.02.2005 22:26

Beitrag 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
robink
Beiträge: 33
Registriert: 29.08.2004 15:11
Wohnort: Rinteln
Kontaktdaten:

Beitrag 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...
robink
Beiträge: 33
Registriert: 29.08.2004 15:11
Wohnort: Rinteln
Kontaktdaten:

Beitrag 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 ;)
Zuletzt geändert von robink am 24.04.2005 12:50, insgesamt 1-mal geändert.
Benutzeravatar
AndyX
Beiträge: 1272
Registriert: 17.12.2004 20:10
Wohnort: Niederösterreich
Kontaktdaten:

Beitrag von AndyX »

Ehm sag mal, ist das nicht beides der selbe Code?! :? Ansonsten sieht es gut aus! :allright:

Greetz,
AndyX
Antworten