Kiste hängt an zwei Seilen (bischen Physik)

Übersicht BlitzMax, BlitzMax NG Codearchiv & Module

Neue Antwort erstellen

Markus2

Betreff: Kiste hängt an zwei Seilen (bischen Physik)

BeitragSo, Dez 03, 2006 0:36
Antworten mit Zitat
Benutzer-Profile anzeigen
Simples Beispiel was aus Punkten und Verbindern besteht .
Mit der linken Maustaste kann man einen Punkt bewegen
und die Rechte Maustaste löscht einen Verbinder .

Mit sowas hat hectic seine 4wd Buggy Physik gemacht (siehe BB3D Codearchiv von ihm !)

Code: [AUSKLAPPEN]


'MR 02.12.2006

Strict

Graphics 800,600',16,72

Global Verbinder:TList=CreateList()
Global Punkte:TList=CreateList()

Type TPunkt
 Field xp:Float 'Position
 Field yp:Float
 Field zp:Float
 Field xs:Float 'Speed
 Field ys:Float
 Field zs:Float
 Field Fest:Int
 Field Masse:Float

 Function Create:TPunkt(x:Float,y:Float,z:Float)
  Local P:TPunkt = New TPunkt
  P.Fest=False
  P.Masse=1.0
  P.xp=x
  P.yp=y
  P.zp=z
  P.xs=0
  P.ys=0
  P.zs=0
  Punkte.AddLast P
  Return P
 End Function
 
 Method Draw()
  'Einfach nur ein Punkt malen
  DrawOval xp-2,yp-2,4,4
 End Method

End Type

Type TVerbinder
 Field P1:TPunkt
 Field P2:TPunkt
 Field Federung:Float
 Field Daempfung:Float
 Field Laenge:Float 'wird berechnet kann man aber auch nachträglich ändern
 Field Sichtbar:Int

 Function Create:TVerbinder(P1:TPunkt,P2:TPunkt,F:Float,D:Float,Sichtbar:Int=1)
  Local V:TVerbinder=New TVerbinder
  V.P1=P1
  V.P2=P2
  V.Sichtbar=Sichtbar
  If F<1 Then F=1
  F=(F+1)^2
  If D<1 Then D=1
  D=(D+1)^2
  V.Federung=F
  V.Daempfung=D
  V.Laenge=Sqr( ( P1.xp - P2.xp )^2 + ( P1.yp - P2.yp )^2 + ( P1.zp - P2.zp )^2 )

  Verbinder.AddLast V
  Return V
 End Function

 Method Draw()
  'Zeigt die Linie zwischen Punkt 1 und 2
  If Sichtbar Then
   DrawLine P1.xp,P1.yp,P2.xp,P2.yp
  EndIf
 End Method

 Method Boing()
  Local dx:Float
  Local dy:Float
  Local dz:Float
  Local entf:Float

  'Die Punkte sollen wieder auf den Abstand kommen
  'welcher durch die Länge vorgeben wurde (P1-P2)

  'da raus kommt die Linie von P1 in Richtung P2
  dx=P2.xp-P1.xp
  dy=P2.yp-P1.yp
  dz=P2.zp-P1.zp

  entf=Sqr(dx*dx + dy*dy + dz*dz)
  'Vector wird zuerst normiert auf länge = 1

  dx=P1.xp+(dx/entf)*Laenge-P2.xp
  dy=P1.yp+(dy/entf)*Laenge-P2.yp
  dz=P1.zp+(dz/entf)*Laenge-P2.zp

  If P1.Fest=0 Then
   P1.xp=P1.xp - dx / Federung
   P1.yp=P1.yp - dy / Federung
   P1.zp=P1.zp - dz / Federung

   P1.xs=P1.xs - dx / Daempfung
   P1.ys=P1.ys - dy / Daempfung
   P1.zs=P1.zs - dz / Daempfung
  EndIf

  If P2.Fest=0 Then
   P2.xp=P2.xp + dx / Federung
   P2.yp=P2.yp + dy / Federung
   P2.zp=P2.zp + dz / Federung

   P2.xs=P2.xs + dx / Daempfung
   P2.ys=P2.ys + dy / Daempfung
   P2.zs=P2.zs + dz / Daempfung
  EndIf

 End Method

End Type

'-------------------------------------------------- Punkte

Local PAr:TPunkt[20]

Local x:Float,y:Float,s:Float
x=400
y=250
s=50

'Würfel Mitte
PAr[0]=TPunkt.Create(x,y,0)

'Würfel Eckpunkte
PAr[1]=TPunkt.Create(x-s,y-s,0)
PAr[2]=TPunkt.Create(x+s,y-s,0)
PAr[3]=TPunkt.Create(x+s,y+s,0)
PAr[4]=TPunkt.Create(x-s,y+s,0)

PAr[0].Masse=10
PAr[1].Masse=10
PAr[2].Masse=10
PAr[3].Masse=10
PAr[4].Masse=10

'Seil 1
PAr[5]=TPunkt.Create(300,150,0)
PAr[6]=TPunkt.Create(300,100,0)
PAr[7]=TPunkt.Create(300, 50,0)
PAr[8]=TPunkt.Create(250,  0,0)
PAr[8].Fest=True

'Seil 2
PAr[10]=TPunkt.Create(500,150,0)
PAr[11]=TPunkt.Create(500,100,0)
PAr[12]=TPunkt.Create(500, 50,0)
PAr[13]=TPunkt.Create(550,  0,0)
PAr[13].Fest=True

'-------------------------------------------------- Verbinden

Local F:Float=10
Local D:Float=1

'Kanten
TVerbinder.Create(PAr[1],PAr[2],F,D)
TVerbinder.Create(PAr[2],PAr[3],F,D)
TVerbinder.Create(PAr[3],PAr[4],F,D)
TVerbinder.Create(PAr[4],PAr[1],F,D)

'Würfel Quer
TVerbinder.Create(PAr[1],PAr[0],F,D)
TVerbinder.Create(PAr[2],PAr[0],F,D)
TVerbinder.Create(PAr[3],PAr[0],F,D)
TVerbinder.Create(PAr[4],PAr[0],F,D)

'Seil 1
F=4
D=2
TVerbinder.Create(PAr[1],PAr[5],F,D)'.Laenge=50
TVerbinder.Create(PAr[5],PAr[6],F,D)'.Laenge=50
TVerbinder.Create(PAr[6],PAr[7],F,D)'.Laenge=50
TVerbinder.Create(PAr[7],PAr[8],F,D)'.Laenge=50

'Seil 2
TVerbinder.Create(PAr[ 2],PAr[10],F,D)'.Laenge=50
TVerbinder.Create(PAr[10],PAr[11],F,D)'.Laenge=50
TVerbinder.Create(PAr[11],PAr[12],F,D)'.Laenge=50
TVerbinder.Create(PAr[12],PAr[13],F,D)'.Laenge=50

'--------------------------------------------------

MainLoop()
End

Function MainLoop()

 Local V:TVerbinder
 Local P:TPunkt
 Local PM:TPunkt
 Local w:Float

 Local mx:Int
 Local my:Int

 While Not KeyHit(KEY_ESCAPE)
  Cls

  mx=MouseX()
  my=MouseY()

  If MouseHit(1)>0 Then
   'in der nähe der Maus einen Punkt suchen zum anfassen
   PM=Nahe(mx,my)
  EndIf

  If MouseDown(1)=True Then
   If PM<>Null Then
    'Punkt ziehen wenn man darf
    w=ATan2(my-PM.yp,mx-PM.xp)
    If PM.Fest=0 Then
     PM.xs=PM.xs+Cos(w)
     PM.ys=PM.ys+Sin(w)
    EndIf
    SetColor 255,128,64
    DrawLine PM.xp,PM.yp,PM.xp+Cos(w)*50.0,PM.yp+Sin(w)*50.0
   EndIf
  EndIf

  If MouseHit(2)>0 Then
   'Verbinder entfernen
   Cut mx,my
  EndIf

  'Durch die vorgegebene Länge die Punkte wieder an die gewollte Stelle bewegen
  For V = EachIn Verbinder
   V.Boing
  Next

  For P = EachIn Punkte

   If P.Fest=0 Then
    P.ys=P.ys+0.01*P.Masse 'Gravitation bzw. nach unten beschleunigen

    'Bewegen wie errechnet
    P.xp=P.xp+P.xs
    P.yp=P.yp+P.ys
    P.zp=P.zp+P.zs
   EndIf

   'Im Fenster halten
   If P.xp<  0 Then P.xp=  0;P.xs=-P.xs*0.97
   If P.xp>800 Then P.xp=800;P.xs=-P.xs*0.97 
   If P.yp>600 Then P.yp=600;P.ys=-P.ys*0.97;P.xs=P.xs*0.97
  Next

  'Alle Verbinder als Linien zeigen
  SetColor 128,128,128
  For V = EachIn Verbinder
   V.Draw
  Next

  'Alle Punkte zeigen
  SetColor 255,255,0
  For P = EachIn Punkte
   P.Draw
  Next

  Flip
 Wend

End Function

Function Cut(x:Float,y:Float)

  Local P:TPunkt
  Local PM:TPunkt
  Local V:TVerbinder
  Local gefunden:Int

   PM=Nahe(x,y)
   If PM<>Null Then
    For V = EachIn Verbinder
     If V.P1=Pm Or V.P2=PM Then
      Verbinder.Remove V
      V=Null
     EndIf
    Next
   EndIf
   'gucken einer der Punkte noch wo dran hängt , wenn nicht löschen
   For P = EachIn Punkte
    gefunden=False
    For V = EachIn Verbinder
     If V.P1=P Or V.P2=P Then
      gefunden=True
      Exit
     EndIf
    Next
    If gefunden=False Then Punkte.Remove P
   Next   

End Function

Function Nahe:TPunkt(x:Float,y:Float)

  Local P:TPunkt
  Local PM:TPunkt
  Local dx:Float
  Local dy:Float
  Local entf:Float
  Local entfm:Float

   PM=Null
   entfm=100000
   'Punkt in der nähe suchen
   For P = EachIn Punkte
    dx=x-p.xp
    dy=y-p.yp
    entf=Sqr(dx*dx + dy*dy)
    If entf<128 Then If entf<entfm Then entfm=entf;PM=P
   Next 
   Return PM

End Function

Blitzcoder

Newsposter

BeitragSo, Dez 03, 2006 11:04
Antworten mit Zitat
Benutzer-Profile anzeigen
Irgendwie reagieren die Seile ein wenig über. Wenn man sie ganz leicht nach unten zieht, fliegen die schon extrem hoch. Aber sonst nett.
P4 3 Ghz@3,55Ghz|GF 6600GT 256MB|Samsung 80GB | 2x Samsung 160GB|2048MB DDR-400 RAM|6 Mbit Flatrate | Logitech G15 | Samsung 225BW-TFT | Ubuntu Gutsy Linux | Windows Vista | Desktop | Blog | CollIDE | Worklog
________________
|°°°°°°°°°°°°°°||'""|""\__,_
|______________ ||__ |__|__ |)
|(@) |(@)"""**|(@)(@)****|(@)

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG Codearchiv & Module

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group