Page 1 sur 1

Simulation de corde à linge

Publié : mer. 22/févr./2012 10:38
par kelebrindae
Bonjour!

Je n'envisageais pas de poster ça, mais comme c'est l'anniversaire de Hertz (cf. page d'accueil de Google), je me sens un peu obligé...

C'est une adaptation rapide d'un code trouvé chez les p'tits copains de DarkBasic (à cette adresse: http://forum.thegamecreators.com/?m=for ... 194376&b=6); le titre m'avait intrigué, et je voulais voir ce que ça faisait. Bon, en l'occurrence, ça ne fait rien, mais c'est marrant à regarder... :wink:

Boutons gauche/droit de la souris pour donner une impulsion à la corde.

Code : Tout sélectionner

#SCREENWIDTH = 800
#SCREENHEIGHT = 500

Structure vector2_struct
  x.f
  y.f
EndStructure

;- Macros for vector maths
Global VEC2_tempLength.f
Macro VEC2_add(vectorA,vectorB,vectorResult)
        vectorResult\x = vectorA\x + vectorB\x
        vectorResult\y = vectorA\y + vectorB\y
EndMacro

Macro VEC2_substract(vectorA,vectorB,vectorResult)
        vectorResult\x = vectorA\x - vectorB\x
        vectorResult\y = vectorA\y - vectorB\y
EndMacro  

Macro VEC2_multiply(vectorA,magnitude,vectorResult)
        vectorResult\x = vectorA\x * magnitude
        vectorResult\y = vectorA\y * magnitude
EndMacro  

Macro VEC2_normalize(vectorA,vectorResult)
  VEC2_tempLength = VEC2_length(vectorA)
  vectorResult\x = vectorA\x / VEC2_tempLength
  vectorResult\y = vectorA\y / VEC2_tempLength
EndMacro

;- Screen initialization
InitSprite()
InitKeyboard()
InitMouse()
OpenWindow(0, 0, 0, #SCREENWIDTH, #SCREENHEIGHT, "Rope", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
OpenWindowedScreen(WindowID(0), 0, 0, #SCREENWIDTH, #SCREENHEIGHT, 0, 0, 0, #PB_Screen_SmartSynchronization)

;- Variables initalization
Global nbSegments.i = 100
Global lenSegment.i = (#SCREENWIDTH-100)/nbSegments

Global Dim ropeSegment.vector2_struct(nbSegments)
Global Dim v.vector2_struct(nbSegments)
Global Dim mass.f(nbSegments)

Global F1.vector2_struct
Global F2.vector2_struct
Global G.vector2_struct ; Gravity (?)

Global speed.f = 5000
Global friction.f = 1 - 2/speed
Global lineforce.f = 0.002

For i = 0 To nbSegments-1
  ropeSegment(i)\x = 50 + i*lenSegment
  ropeSegment(i)\y = #SCREENHEIGHT/2
  mass(i) = 2
Next i


;- Main loop
Repeat
  While WindowEvent(): Wend
  Delay(1)
  
  ;- Left or right click to create impulses on the rope
  ExamineMouse()  
  If MouseButton(#PB_MouseButton_Left)
    ropeSegment(1)\y + 100
  EndIf
  If MouseButton(#PB_MouseButton_Right)
    ropeSegment(nbSegments-2)\y + 100
  EndIf
  
  ; Compute movements
  For nbIter = 0 To 20
    For i = 1 To nbSegments-2
      VEC2_substract(ropeSegment(i-1),ropeSegment(i),F1)          
      VEC2_substract(ropeSegment(i+1),ropeSegment(i),F2)
      
      G\x = 0
      G\y = 0.01*mass(i)
      
      VEC2_add(F1,F2,F1)
      VEC2_add(F1,G,F1)
      VEC2_multiply(F1,lineforce,F1)
      VEC2_add(v(i),F1,v(i))
      VEC2_multiply(v(i),friction,v(i))
    Next i
    
    For i = 0 To nbSegments-1
      VEC2_add(ropeSegment(i),v(i),ropeSegment(i))
    Next i
    
  Next nbIter
  
  ; Draw the rope
  ClearScreen(0) ; Or box(0,0,#SCREENWIDTH,#SCREENHEIGHT,0) if "clearScreen" doesn't work
  StartDrawing(ScreenOutput())
  For i = 1 To nbSegments-1
    w = ropeSegment(i)\x - ropeSegment(i-1)\x
    If w=0
      w=1
    EndIf
    h = ropeSegment(i)\y - ropeSegment(i-1)\y
    If h=0
      h=1
    EndIf
    Line(ropeSegment(i-1)\x,ropeSegment(i-1)\y,w,h,$00FF00)
    Line(ropeSegment(i-1)\x,ropeSegment(i-1)\y - 1,w,h,$00BB00); this makes the rope a little thicker
    Line(ropeSegment(i-1)\x,ropeSegment(i-1)\y + 1,w,h,$00BB00); this makes the rope a little thicker
  
  Next i
  StopDrawing()

  FlipBuffers()
  
  ExamineKeyboard()
Until KeyboardReleased(#PB_Key_Escape)

Re: Simulation de corde à linge

Publié : mer. 22/févr./2012 13:07
par Ar-S
Sympa :) L'effet est crédible.

Re: Simulation de corde à linge

Publié : mer. 22/févr./2012 14:40
par Backup
Ar-S a écrit :Sympa :) L'effet est crédible.
je ne pense pas non ! :)

parce qu'on vois bien, dans son programme que l’impulsion de départ est deja complexe ! c'est un pic sur une petite partie de la "corde" c'est impossible ! :)
un pic de la sorte créerai une rupture de la corde ...
ça ressemble plus a une simulation d'une onde (d'une fréquence...une pierre qui entre en collision) sur de l'eau avec rebond de l'onde sur les bords d'un contenant
sa corde représentant alors l'horizon de l'eau... pour toute matiere autre, ça ne marche plus

parce que , si l'on cogne (pince) une corde (guitare, a linge etc ...) , l'impulsion est unique !

ça devrai plus ressembler a ça :

Variation de la fréquence avec la longueur
Image

Trois premiers modes de vibration d'une corde
Image

Vibration fondamentale (haut), avec une harmonique (milieu) et avec deux harmoniques (bas)
Image

et surtout pas a ça :

Image

au final , je pense que cette simulation ne représente rien de connu dans l'univers :lol:

Re: Simulation de corde à linge

Publié : ven. 24/févr./2012 0:14
par graph100
ce genre de pic existe en mathématique informatique, ça s'appelle un dirac et ça sert pour la modélisation et l'analyse harmonique.
C'est une excitation de tout les modes de l'objet observé.
Il faut bien sur pouvoir donner une impulsion à la corde, et il a du faire ça un peu vite ^^

Re: Simulation de corde à linge

Publié : ven. 24/févr./2012 8:18
par kelebrindae
Analyse aussi pertinente qu'exacte!

Re: Simulation de corde à linge

Publié : ven. 24/févr./2012 16:23
par Kwai chang caine
En tout cas c'est cool..merci kelebrindae 8)