 |
Das deutsche QBasic- und FreeBASIC-Forum Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
|
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
Lloyd

Anmeldungsdatum: 27.06.2008 Beiträge: 37 Wohnort: Nähe Frankfurt
|
Verfasst am: 21.06.2009, 23:11 Titel: Rigid Body Dynamics - Constraints |
|
|
Hallöle!
Ich habe grade eine Festkörpersimulation zum funktionieren gebracht. Es ist noch nicht sehr optimiert, was ich in den nöchsten Tagen wohl ändern müsste.
Allerdings hab ich ein Problem. Ich würde das sehr gerne selbst lösen, aber da ich keine Ahnung hatte, wollte ich google befragen, aber damit kann ich nicht wirklcih was anfangen.
Naja, aufjedenfall geht es um Constraints! Das sind sone Art Bedingungen, die in meinem Fall ein Körper einhalten soll.
So will ich zum Beispiel einen Angelpunkt an einen Körper legen, um welchen dieser dann rumbaumelt. Ich habe zwar bis jetzt Springs drinne, allerdings hab ich etwas Probleme mit der "Steifheit". Naja, allerdings hätte ich aber auch gerne, dass man eine Körper "anpinnen" kann, sodass dieser sich auch nicht mehr drehen kann. Also schon, nur halt mit diesem Punkt mit. Ich wollte das dann so machen, dass man auch eine Kölrper an Andere pinnen kann, um so zum Beispiel konkave Körper zu simulieren.
Ich hab allerdings keine Ahnng, wie sich zu was etwas finden lassen könnte. Bei den SPrings war das so, dass sich die Kraft einfach auf Geschwindigkeit des Körpers und den Winkelgeschwindigkeit ausgeübt hat. Bei Constraints scheints aber anders zu sein.
Wah, ich bin mir jetzt nicht sicher, ob das so verständlich war, notfalls versuchs ichs nochmal zu erklären, ist ja auch schon spöt ;D
Na, okay, ich hoffe trotzdem auf Hilfe und...öhm, bis dann! o/ |
|
Nach oben |
|
 |
ThePuppetMaster

Anmeldungsdatum: 18.02.2007 Beiträge: 1839 Wohnort: [JN58JR]
|
Verfasst am: 22.06.2009, 03:30 Titel: |
|
|
also persönlich würde ich einfach eien art prüfung durchführen, die checkt, ob mehr als 2 pins ein festkörper berühren. wenn ja, dann den abstand zu den beiden pins ermitteln (pytagoras). ist er 0, dann sind beide pins in der mitte, und damit das objekt drehbar, wenn nicht, dann steht es fest.
um 2 objekte miteinander zu "fixieren" würde ich ähnlich vorgehen, ist bekannt, an welchem punkt pin 2 steht, kann auch hier mit hilfe des pytagoras der abstand vom angelpunkt zum fixpunkt des befestigtn objekts ermittelt werden. dies dient dann dazu über die winkelfunktion die rotation zu berechnen.
MfG
TPM _________________ [ WebFBC ][ OPS ][ ToOFlo ][ Wiemann.TV ] |
|
Nach oben |
|
 |
micha
Anmeldungsdatum: 09.12.2005 Beiträge: 72
|
Verfasst am: 22.06.2009, 17:51 Titel: |
|
|
Abgesehen von den Festkörpern selbst wird alles andere über "Constraints" geregelt.
Egal ob Du ein RigidBody an die Decke pinnen möchtes oder zwei RigidBodies via Joint verbinden willst.
Im Fall der Decke Regeln die "Constraints" das die Verbindung unter dem Einfluß von Gravitation und Masse nicht unendlich lang wird und z.B. das angepinnte Objekt nach kurzer Zeit auf dem Boden schleift.
Im Falle der "Joints" regeln die "Constraints" die Anzahl und das Mini- und Maximum der möglichen Freiheitsgrade.
Im Falle eines JointMotors regeln die "Constraints" das die Antriebsachse immer in einem festem Winkel steif zum "ParentBody" bleibt.
(Ohne diese festgelegten Beziehungen würden die wirkenden Kräfte zur verschrenkung von beweglichen Verbindungen führen.)
Es gibt viele verschiedene mathematische Modelle um Constraints zu Implementieren als Einstieg würde schon ein "gutes" Spring Modell reichen.
(Joints wären dann fast unendlich steife Federn die dafür sorgen das die Festkörper den gewünschten Abstand zu einander einhalten und gehindert werden den Bereich der definierten Freiheitsgade zu verlassen.) |
|
Nach oben |
|
 |
h4tt3n
Anmeldungsdatum: 19.06.2007 Beiträge: 6
|
Verfasst am: 23.06.2009, 01:46 Titel: |
|
|
Hallo Lloyd,
Hier hast du ein par code samples womit du spielen kannst! Jetzt is es ein bisschen spät (1uhr45!), aber ich erklär dir morgen gern wie's alles funktioniert.
Cheers,
Mike
#1 zweikörper constraint
Code: |
'' define constants. Play around with these and see what happens!
Const Grav_acc = 100 '' gravitational acceleration
Const Stiff_Rod_Length = 100 '' total spring body Scalar_Dst
Const Scrn_Wid = 600 '' screen width
Const Scrn_Hgt = 600 '' screen height
Const dt = 0.01 '' timestep, delta time
'' define types
Type Vector_Type
As Double X, Y
End Type
Type Mass_Type
As Double Mass, radius
As Vector_Type Frc, Acc, Vel, Psn
End Type
'' dim arrays & variables
Dim As mass_type mass(1 to 2)
Dim As Integer Mouse_X, Mouse_Y
Dim As Vector_Type Dst, Rest_Psn, Dst_Nor, Rest_Psn_Dst, Dv
Dim As Double Scalar_Dst, Proj_Vel, Kinetic, Potential, Total
'' initiate screen
ScreenRes Scrn_Wid, Scrn_hgt, 16
Color RGB(0, 0, 0), RGB(255, 255, 255)
SetMouse Scrn_Wid\2, Scrn_hgt\2
With mass(1)
.mass = 1
.radius = 4
end with
with mass(2)
.mass = 1
.radius = 4
end with
do
'' set mass 1 position to mouse position
'' (usually means very stiff movement!)
GetMouse Mouse_X, Mouse_Y
Mass(1).Psn.X = Mouse_X
Mass(1).Psn.Y = Mouse_Y
'' particle - particle distance vector
Dst.X = Mass(2).Psn.X - Mass(1).Psn.X
Dst.Y = Mass(2).Psn.Y - Mass(1).Psn.Y
'' particle - particle distance scalar
Scalar_Dst = Sqr(Dst.X*Dst.X+Dst.Y*Dst.Y)
'' particle - particle nomalised distance vector
Dst_Nor.x = Dst.X/Scalar_Dst
Dst_Nor.y = Dst.y/Scalar_Dst
'' rest position vector
Rest_Psn.X = Mass(1).Psn.X + Dst_nor.x * Stiff_Rod_Length
Rest_Psn.Y = Mass(1).Psn.Y + Dst_nor.Y * Stiff_Rod_Length
'' rest position distance vector
Rest_Psn_Dst.x = Rest_Psn.X - Mass(2).Psn.X
Rest_Psn_Dst.y = Rest_Psn.Y - Mass(2).Psn.y
'' project particle velocity vector onto
'' particle - particle normalised distance vector
'' (get radial velocity component)
Proj_Vel = Dst_nor.X*Mass(2).Vel.x+Dst_nor.Y*Mass(2).Vel.Y
Dv.X = Dst_nor.X * Proj_Vel
Dv.Y = Dst_nor.Y * Proj_Vel
'' apply force
With Mass(2)
.Frc.X += .Mass * (Rest_Psn_Dst.x/dt - Dv.X)/dt
.Frc.y += .Mass * (Rest_Psn_Dst.y/dt - Dv.y)/dt
End With
'' integrate (symplectic Euler 1st order)
With mass(2)
.acc.x = (.frc.x/.mass)
.acc.y = (.frc.y/.mass) + grav_acc
.frc.x = 0
.frc.y = 0
.vel.x += .acc.x*dt
.vel.y += .acc.y*dt
.Psn.x += .vel.x*dt
.Psn.y += .vel.y*dt
End With
'' calculate energy
With Mass(2)
Kinetic = 0.5*.Mass*(.Vel.X*.Vel.X+.Vel.Y*.Vel.Y)
Potential = .Mass*Grav_Acc*(Scrn_Hgt-.Psn.Y)
Total = Kinetic+Potential
End With
'' draw to screen
ScreenLock
'' clear screen
Cls
'' print data
Locate 2, 2: Print Using " Kinetic energy: ######.##"; Kinetic
Locate 4, 2: Print Using "Potential energy: ######.##"; Potential
Locate 6, 2: Print Using " Total energy: ######.##"; Total
Locate 10, 2: Print Using "Distance error %: ###.##";((Scalar_Dst-Stiff_Rod_Length)/Stiff_Rod_Length)*100
'' draw stiff rod
Line(Mass(1).Psn.X, Mass(1).Psn.y)-(Mass(2).Psn.X, Mass(2).Psn.y), RGB(32, 128, 32)
'' draw particles
With mass(1)
Circle(.Psn.X, .Psn.Y), Stiff_Rod_Length, rgb(224, 224, 224),,, 1
Circle(.Psn.X, .Psn.Y), .radius, rgb(0, 0, 0),,, 1, f
Circle(.Psn.X, .Psn.Y), .radius-1, rgb(255, 32, 32),,, 1, f
End With
With mass(2)
Circle(.Psn.X, .Psn.Y), .radius, rgb(0, 0, 0),,, 1, f
Circle(.Psn.X, .Psn.Y), .radius-1, rgb(255, 32, 32),,, 1, f
End With
ScreenUnLock
'' give the computer a break
Sleep 4, 1
Loop Until Multikey(1)
End
|
#2 zwei partikeln bei ein constraint festgehallt.
Code: |
'******************************************************************************'
' simple rigid constraint between particles
' Michael "h4tt3n" Nissen, june 2009
'******************************************************************************'
'' set constants. experiment with these and see how the simulation reacts
const Pi = 4*atn(1) '' pi (better not change )
const dt = 0.01 '' timestep
const Num_Masses = 8 -1 '' number of masses in rope
const Point_Mass = 2 '' mass of each point mass
const Point_Density = 0.005 '' density of each point mass
const Rope_Length = 400 '' rope length
const Grav_Acc = 200 '' gravitational acceleration
const Rest_Length = Rope_Length/Num_Masses '' rest length of each spring
const Scrn_Wid = 800 '' screen width
const Scrn_Hgt = 600 '' screen height
'' define types
'' two dimensional vector type
type Vector_Type
as double X, Y
end type
'' mass type including force-, acceleration-, impulse-, velocity-, and position vectors
type Mass_Type
as double Mass, Density, Radius
as Vector_Type Frc, Acc, Ipl, Vel, Psn
end type
'' dimension variables
dim as Vector_Type Dst, Vel, Rest_Dst, Dst_Nor, Dv, impulse
dim as Mass_Type Mass(Num_Masses)
dim as double scalar_dst, total_length, proj_vel
dim as integer i, i2
'' set screen width, height, and bit depth
screenres Scrn_Wid, Scrn_hgt, 16
'' set foreground & background color
color rgb(0, 0, 0), rgb(192, 192, 255)
'' set startup conditions of masses
for i = 0 to Num_Masses
with Mass(i)
.Mass = Point_Mass
.Density = Point_Density
.Radius = ((.Mass/.Density)/((4/3)*pi))^(1/3)
.Psn.x = Scrn_Wid\2 + (i*Rest_Length)
.psn.y = scrn_hgt\8
end with
next
randomize
'' randomize position and velocity
'' (even if you randomise with a high
'' number all masses stabilise at once!)
for i = 0 to Num_Masses
with Mass(i)
.Psn.x += (rnd-rnd) * 0.01
.psn.y += (rnd-rnd) * 0.01
.vel.x += (rnd-rnd) * 0.01
.vel.y += (rnd-rnd) * 0.01
end with
next
'' main program loop
do
'' reset rope length
total_length = 0
for i = 0 to Num_Masses
with Mass(i)
'' accelerate masses:
'' acceleration = force / mass
.Acc.X = .Frc.X/.mass
.Acc.Y = .Frc.Y/.mass
'' reset force vector
.frc.x = 0
.frc.y = 0
'' add gravity (downwards acceleration)
.Acc.Y += Grav_Acc
'' update velocity:
'' delta velocity = acceleration * delta time
'' new velocity = old velocity + delta velocity
.Vel.X += .Acc.X*dt
.Vel.Y += .Acc.Y*dt
end with
next
'' make particle # 0 stay fixed
'' particle - particle distance vector
Dst.X = scrn_Wid\2 - Mass(0).Psn.X
Dst.Y = scrn_hgt\8 - Mass(0).Psn.Y
'' particle - particle velocity vector
Vel.X = -Mass(0).Vel.X
Vel.Y = -Mass(0).Vel.Y
'' particle - particle distance scalar
Scalar_Dst = sqr(Dst.X*Dst.X+Dst.Y*Dst.Y)
'' particle - particle normalised distance vector
Dst_Nor.x = Dst.X/Scalar_Dst
Dst_Nor.y = Dst.y/Scalar_Dst
'' rest distance vector
Rest_Dst.X = Dst.x
Rest_Dst.Y = Dst.Y
'' project velocity vector onto normalised distance vector
'' (get radial velocity component)
Proj_Vel = Dst_nor.X*Vel.x+Dst_nor.Y*Vel.Y
'' projected velocity vector
Dv.X = Dst_nor.X * Proj_Vel
Dv.Y = Dst_nor.Y * Proj_Vel
'' impulse vector
Impulse.x = (rest_dst.x/dt + dv.x)
Impulse.y = (rest_dst.y/dt + dv.y)
Mass(0).vel.x += Impulse.x
Mass(0).vel.y += Impulse.y
'' calculate the constraint forces acting upon each point mass in the rope
for i = 0 to Num_Masses-1
i2 = i+1
'' particle - particle distance vector
Dst.X = Mass(i2).Psn.X - Mass(i).Psn.X
Dst.Y = Mass(i2).Psn.Y - Mass(i).Psn.Y
'' particle - particle velocity vector
Vel.X = Mass(i2).Vel.X - Mass(i).Vel.X
Vel.Y = Mass(i2).Vel.Y - Mass(i).Vel.Y
'' particle - particle distance scalar
Scalar_Dst = sqr(Dst.X*Dst.X+Dst.Y*Dst.Y)
'' add constraint length to total rope length
total_length += scalar_dst
'' particle - particle normalised distance vector
Dst_Nor.x = Dst.X/Scalar_Dst
Dst_Nor.y = Dst.y/Scalar_Dst
'' rest distance vector
Rest_Dst.X = Dst.x - Dst_nor.x * Rest_Length
Rest_Dst.Y = Dst.Y - Dst_nor.Y * Rest_Length
'' project velocity vector onto normalised distance vector
'' (get radial velocity component)
Proj_Vel = Dst_nor.X*Vel.x+Dst_nor.Y*Vel.Y
'' projected velocity vector
Dv.X = Dst_nor.X * Proj_Vel
Dv.Y = Dst_nor.Y * Proj_Vel
'' impulse vector
Impulse.x = (rest_dst.x/dt + dv.x)
Impulse.y = (rest_dst.y/dt + dv.y)
'' apply equal opposite impulses
Mass(i).vel.x += Impulse.x / mass(i).mass
Mass(i).vel.y += Impulse.y / mass(i).mass
Mass(i2).vel.x -= Impulse.x / mass(i2).mass
Mass(i2).vel.y -= Impulse.y / mass(i2).mass
next
'' update acceleration, velocity, and position of point masses
for i = 0 to Num_Masses
with Mass(i)
'' update position:
.Psn.X += .Vel.X*dt
.Psn.Y += .Vel.Y*dt
end with
next
'' display the rope in graphics
screenlock
'' clear screen
cls
'' print data
locate 2, 2: print using " length: ###.##"; total_length
locate 4, 2: print using " error %: ###.##"; ((total_length-rope_length)/rope_length)*100
'' draw springs
for i = 0 to Num_Masses-1
i2 = i+1
line(Mass(i).Psn.X, Mass(i).Psn.y)-(Mass(i2).Psn.X, Mass(i2).Psn.y), rgb(0, 0, 0)
next i
'' draw masses
for i = 0 to Num_Masses
with Mass(i)
circle(.Psn.X, .Psn.Y), .radius, rgb(0, 0, 0),,, 1, f
circle(.Psn.X, .Psn.Y), .radius-1, rgb(255, 32, 32),,, 1, f
end with
next i
screenunlock
sleep 4, 1
loop until multikey(1)
end
|
#3 rigid rope von partikeln und constrains gemacht
Code: | '******************************************************************************'
' simple rigid constraint between particles
' Michael "h4tt3n" Nissen, june 2009
'******************************************************************************'
'' set constants. experiment with these and see how the simulation reacts
const Pi = 4*atn(1) '' pi (better not change )
const dt = 0.01 '' timestep
const Num_Masses = 8 -1 '' number of masses in rope
const Point_Mass = 2 '' mass of each point mass
const Point_Density = 0.005 '' density of each point mass
const Rope_Length = 400 '' rope length
const Grav_Acc = 200 '' gravitational acceleration
const Rest_Length = Rope_Length/Num_Masses '' rest length of each spring
const Scrn_Wid = 800 '' screen width
const Scrn_Hgt = 600 '' screen height
'' define types
'' two dimensional vector type
type Vector_Type
as double X, Y
end type
'' mass type including force-, acceleration-, impulse-, velocity-, and position vectors
type Mass_Type
as double Mass, Density, Radius
as Vector_Type Frc, Acc, Ipl, Vel, Psn
end type
'' dimension variables
dim as Vector_Type Dst, Vel, Rest_Dst, Dst_Nor, Dv, impulse
dim as Mass_Type Mass(Num_Masses)
dim as double scalar_dst, total_length, proj_vel
dim as integer i, i2
'' set screen width, height, and bit depth
screenres Scrn_Wid, Scrn_hgt, 16
'' set foreground & background color
color rgb(0, 0, 0), rgb(192, 192, 255)
'' set startup conditions of masses
for i = 0 to Num_Masses
with Mass(i)
.Mass = Point_Mass
.Density = Point_Density
.Radius = ((.Mass/.Density)/((4/3)*pi))^(1/3)
.Psn.x = Scrn_Wid\2 + (i*Rest_Length)
.psn.y = scrn_hgt\8
end with
next
randomize
'' randomize position and velocity
'' (even if you randomise with a high
'' number all masses stabilise at once!)
for i = 0 to Num_Masses
with Mass(i)
.Psn.x += (rnd-rnd) * 0.01
.psn.y += (rnd-rnd) * 0.01
.vel.x += (rnd-rnd) * 0.01
.vel.y += (rnd-rnd) * 0.01
end with
next
'' main program loop
do
'' reset rope length
total_length = 0
for i = 0 to Num_Masses
with Mass(i)
'' accelerate masses:
'' acceleration = force / mass
.Acc.X = .Frc.X/.mass
.Acc.Y = .Frc.Y/.mass
'' reset force vector
.frc.x = 0
.frc.y = 0
'' add gravity (downwards acceleration)
.Acc.Y += Grav_Acc
'' update velocity:
'' delta velocity = acceleration * delta time
'' new velocity = old velocity + delta velocity
.Vel.X += .Acc.X*dt
.Vel.Y += .Acc.Y*dt
end with
next
'' make particle # 0 stay fixed
'' particle - particle distance vector
Dst.X = scrn_Wid\2 - Mass(0).Psn.X
Dst.Y = scrn_hgt\8 - Mass(0).Psn.Y
'' particle - particle velocity vector
Vel.X = -Mass(0).Vel.X
Vel.Y = -Mass(0).Vel.Y
'' particle - particle distance scalar
Scalar_Dst = sqr(Dst.X*Dst.X+Dst.Y*Dst.Y)
'' particle - particle normalised distance vector
Dst_Nor.x = Dst.X/Scalar_Dst
Dst_Nor.y = Dst.y/Scalar_Dst
'' rest distance vector
Rest_Dst.X = Dst.x
Rest_Dst.Y = Dst.Y
'' project velocity vector onto normalised distance vector
'' (get radial velocity component)
Proj_Vel = Dst_nor.X*Vel.x+Dst_nor.Y*Vel.Y
'' projected velocity vector
Dv.X = Dst_nor.X * Proj_Vel
Dv.Y = Dst_nor.Y * Proj_Vel
'' impulse vector
Impulse.x = (rest_dst.x/dt + dv.x)
Impulse.y = (rest_dst.y/dt + dv.y)
Mass(0).vel.x += Impulse.x
Mass(0).vel.y += Impulse.y
'' calculate the constraint forces acting upon each point mass in the rope
for i = 0 to Num_Masses-1
i2 = i+1
'' particle - particle distance vector
Dst.X = Mass(i2).Psn.X - Mass(i).Psn.X
Dst.Y = Mass(i2).Psn.Y - Mass(i).Psn.Y
'' particle - particle velocity vector
Vel.X = Mass(i2).Vel.X - Mass(i).Vel.X
Vel.Y = Mass(i2).Vel.Y - Mass(i).Vel.Y
'' particle - particle distance scalar
Scalar_Dst = sqr(Dst.X*Dst.X+Dst.Y*Dst.Y)
'' add constraint length to total rope length
total_length += scalar_dst
'' particle - particle normalised distance vector
Dst_Nor.x = Dst.X/Scalar_Dst
Dst_Nor.y = Dst.y/Scalar_Dst
'' rest distance vector
Rest_Dst.X = Dst.x - Dst_nor.x * Rest_Length
Rest_Dst.Y = Dst.Y - Dst_nor.Y * Rest_Length
'' project velocity vector onto normalised distance vector
'' (get radial velocity component)
Proj_Vel = Dst_nor.X*Vel.x+Dst_nor.Y*Vel.Y
'' projected velocity vector
Dv.X = Dst_nor.X * Proj_Vel
Dv.Y = Dst_nor.Y * Proj_Vel
'' impulse vector
Impulse.x = (rest_dst.x/dt + dv.x)
Impulse.y = (rest_dst.y/dt + dv.y)
'' apply equal opposite impulses
Mass(i).vel.x += Impulse.x / mass(i).mass
Mass(i).vel.y += Impulse.y / mass(i).mass
Mass(i2).vel.x -= Impulse.x / mass(i2).mass
Mass(i2).vel.y -= Impulse.y / mass(i2).mass
next
'' update acceleration, velocity, and position of point masses
for i = 0 to Num_Masses
with Mass(i)
'' update position:
.Psn.X += .Vel.X*dt
.Psn.Y += .Vel.Y*dt
end with
next
'' display the rope in graphics
screenlock
'' clear screen
cls
'' print data
locate 2, 2: print using " length: ###.##"; total_length
locate 4, 2: print using " error %: ###.##"; ((total_length-rope_length)/rope_length)*100
'' draw springs
for i = 0 to Num_Masses-1
i2 = i+1
line(Mass(i).Psn.X, Mass(i).Psn.y)-(Mass(i2).Psn.X, Mass(i2).Psn.y), rgb(0, 0, 0)
next i
'' draw masses
for i = 0 to Num_Masses
with Mass(i)
circle(.Psn.X, .Psn.Y), .radius, rgb(0, 0, 0),,, 1, f
circle(.Psn.X, .Psn.Y), .radius-1, rgb(255, 32, 32),,, 1, f
end with
next i
screenunlock
sleep 4, 1
loop until multikey(1)
end
|
|
|
Nach oben |
|
 |
Lloyd

Anmeldungsdatum: 27.06.2008 Beiträge: 37 Wohnort: Nähe Frankfurt
|
Verfasst am: 25.06.2009, 14:07 Titel: |
|
|
Oh, wow, das ist ne Menge! Aber danke!
Was mir sofort positiv aufgefallen ist, ist, dass die Constraints mit Kräften arbeitet. Es könnte ja einfach die Position angepasst werden, nur das wäre viel schwieriger auf die Festkörper umzurechnen. Aber mit Kräften wird das wohl sehr gut Funtionieren, danke!  |
|
Nach oben |
|
 |
|
|
Du kannst keine Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum nicht antworten. Du kannst deine Beiträge in diesem Forum nicht bearbeiten. Du kannst deine Beiträge in diesem Forum nicht löschen. Du kannst an Umfragen in diesem Forum nicht mitmachen.
|
|