Solide glissant sur un rail (part I,II)

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
Avatar de l’utilisateur
Huitbit
Messages : 940
Inscription : jeu. 08/déc./2005 5:19
Localisation : Guadeloupe

Solide glissant sur un rail (part I,II)

Message par Huitbit »

Petite récréation(première partie) basée sur l'article :
http://www.myphysicslab.com/RollerSimple.html

Ce que l'on vous cache dans cet article !

Ce problème correspond à celui du solide glissant sur un plan incliné.
La difficulté, c'est que l'on considère qu'une courbe est une succession de plans inclinés microscopiques. On regarde donc ce qui se passe sur de très petites portions de la courbe.
C'est une application de la 2ème loi de Newton dans un repère particulier : le repère de Frenet.

m * |a> = |P> + |R>

Avec |P> vecteur poids, vertical vers le bas, |R> vecteur réaction, normal à la courbe.

Dans la base de Frenet, on montre, que l'accélération s'exprime de la manière suivante :

m * |a> = dv/dt * |et> + v²/r * |en>

Avec :
- |et> vecteur tangent à la trajectoire
- |en> vecteur normal à la trajectoire tourné vers la concavité de la trajectoire
- v valeur de la vitesse
- r rayon de courbure de la trajectoire

On a donc

m * (dv/dt * |et> + v²/r * |en>)= dv/dt * |et> + v²/r * |en>

Si on projette on a :

selon la tangente
m * dv/dt = mg * cos(a)

Remarque : si on veut rajouter des frottements, il suffit de rajouter "- coeff_frott * v" dans le terme de droite)

selon la normale
m * v²/r = m * g * sin(a) – R

Seule la première équation nous renseigne sur la variation de la vitesse.

La deuxième équation nous sera utile (à suivre dans le prochain message :wink: !) pour savoir si le solide reste en contact avec le sol.
En effet, si R = 0 (c'est à dire m * v²/r = m * g * sin(a) -0 ou bien v²/r = * g * sin(a)), le solide quitte le sol.
(voir http://www.myphysicslab.com/RollerFlight.html)

Voilà pour la physique ! :P

La difficulté maintenant, va être de passer de l'abscisse curviligne s (position sur la courbe) aux coordonnées cartésiennes x,y !
J'ai pris la première méthode qui allait bien, alors n'hésitez pas à trouver mieux !

Pour la courbe, j'ai travaillé avec des équations paramétriques, mais on peut très bien faire avec des « data ». L'intérêt des équations, c'est que l'on peut obtenir facilement leurs dérivées. Avec des « data » on pourra les calculer sans problème de manière approchée avec df(t)/dt ~ (f(t2)-f(t1))/(t2-t1)

Les courbes utilisées sont des gaussiennes (courbes en forme de cloche)

J'ai rajouté la rotation de l'objet en fonction de la pente de la courbe.

Pour placer l'objet sur la courbe (et non enfilé), on peut tricher et calculer à l'avance la courbe qui correspond au coin gauche du sprite.

Pour rajouter un décor, il suffit de construire son décor par rapport à la courbe !

Remarque : j'ai découvert que la fonction exponentielle (très utilisée en maths et en physique) n'existait pas dans PB 8O (alors que le logarithme existe) ! Avec pow(), je me suis débrouillé :roll:

Code : Tout sélectionner

;solide guidé soumis à la pesanteur
;auteur Huitbit
;pb v4.20
;*********************************
;-déclarations de variables
#largeur_ecran=1024
#hauteur_ecran=768
#g=9.8 ;intensité de la pesanteur
#dt=0.2 ;pas de calcul pour la méthode d'Euler
Enumeration
  #spr_piste
  #spr_carre_droite
  #spr_carre_gauche
EndEnumeration
Structure donnees
  x.f ; x(t)
  y.f ; y(t)
  dx.f
  dy.f
  s.f ; abscisse curviligne s(t)
  cosinus.f; cosinus de l'angle vecteur poids |P> et le vecteur tangent à la courbe
EndStructure

s.f ; abscisse curviligne s(t)
int_s.w; valeur entière de s(t)
vs.f ; vitesse curviligne 
angle_rotation.w
spr_carre.b

;infos sur les courbes
t.w ;paramètre pour les fonctions x(t), y(t) et s(t) sur tout le parcours
t_max.w ; dernière valeur de t
p.w ; paramètre provisoire pour chaque portion de courbes
longueur_courbe.f = 0
#y_depart=92
e.f=2.718281828 ; valeur de exp(1)
#parametre_gaussienne_1=0.00003
#parametre_gaussienne_2=0.0004
; point de la courbe pour tracer le premier segment
x_point_precedent.f=0
y_point_precedent.f=#y_depart

;-tracé de la courbe
Dim  courbe.donnees(5000)

t=0
p=0

;première demi-gaussienne
While courbe(t)\x<#largeur_ecran/2
  t=t+1
  p=p+1
  courbe(t)\x=p
  courbe(t)\y=#y_depart+#hauteur_ecran*0.7*(1-Pow(e,-#parametre_gaussienne_1*p*p))
  courbe(t)\dx=1
  courbe(t)\dy=#hauteur_ecran*0.7*2*#parametre_gaussienne_1*p*Pow(e,-#parametre_gaussienne_1*p*p)
  longueur_courbe=longueur_courbe+Sqr(courbe(t)\dx*courbe(t)\dx+courbe(t)\dy*courbe(t)\dy)
  courbe(t)\s=longueur_courbe
  courbe(t)\cosinus=courbe(t)\dy / Sqr(courbe(t)\dx*courbe(t)\dx+courbe(t)\dy*courbe(t)\dy) ;cosinus de l'angle entre la verticale(direction du poids) et la courbe
Wend
t_max=t

;ellipse n°1
For angle=0 To 360
  t=t+1
  courbe(t)\x=courbe(t_max)\x+150*Cos(#PI*(-angle+90)/180); décalage de 90° pour partir du bon endroit sur l'ellipse !
  courbe(t)\y=courbe(t_max)\y-200+200*Sin(#PI*(-angle+90)/180)
  courbe(t)\dx=150*#PI/180*Sin(#PI*(-angle+90)/180)
  courbe(t)\dy=-200*#PI/180*Cos(#PI*(-angle+90)/180)
  longueur_courbe=longueur_courbe+Sqr(courbe(t)\dx*courbe(t)\dx+courbe(t)\dy*courbe(t)\dy)
  courbe(t)\s=longueur_courbe
  courbe(t)\cosinus=courbe(t)\dy / Sqr(courbe(t)\dx*courbe(t)\dx+courbe(t)\dy*courbe(t)\dy)
Next angle
t_max=t

; portion horizontale
While courbe(t)\x<0.75*#largeur_ecran
  t=t+1
  p=p+1
  courbe(t)\x=p
  courbe(t)\y=courbe(t_max)\y
  courbe(t)\dx=1
  courbe(t)\dy=0
  longueur_courbe=longueur_courbe+Sqr(courbe(t)\dx*courbe(t)\dx+courbe(t)\dy*courbe(t)\dy)
  courbe(t)\s=longueur_courbe
  courbe(t)\cosinus=courbe(t)\dy / Sqr(courbe(t)\dx*courbe(t)\dx+courbe(t)\dy*courbe(t)\dy)
Wend
t_max=t

;ellipse n°2
For angle=0 To 360 
  t=t+1
  courbe(t)\x=courbe(t_max)\x+100*Cos(#PI*(-angle+90)/180)
  courbe(t)\y=courbe(t_max)\y-50+50*Sin(#PI*(-angle+90)/180)
  courbe(t)\dx=100*#PI/180*Sin(#PI*(-angle+90)/180)
  courbe(t)\dy=-50*#PI/180*Cos(#PI*(-angle+90)/180)
  longueur_courbe=longueur_courbe+Sqr(courbe(t)\dx*courbe(t)\dx+courbe(t)\dy*courbe(t)\dy)
  courbe(t)\s=longueur_courbe
  courbe(t)\cosinus=courbe(t)\dy / Sqr(courbe(t)\dx*courbe(t)\dx+courbe(t)\dy*courbe(t)\dy)
Next angle
t_max=t

;deuxième demi-gaussienne
While courbe(t)\x<#largeur_ecran-1
  t=t+1
  p=p+1
  courbe(t)\x=p
  courbe(t)\y=courbe(t_max)\y-#hauteur_ecran*0.8*Pow(e,-#parametre_gaussienne_2*(p -#largeur_ecran)*(p -#largeur_ecran))
  courbe(t)\dx=1
  courbe(t)\dy=#hauteur_ecran*0.8*#parametre_gaussienne_2*2*(p -#largeur_ecran)*Pow(e,-#parametre_gaussienne_2*(p -#largeur_ecran)*(p -#largeur_ecran))
  longueur_courbe=longueur_courbe+Sqr(courbe(t)\dx*courbe(t)\dx+courbe(t)\dy*courbe(t)\dy)
  courbe(t)\s=longueur_courbe
  courbe(t)\cosinus=courbe(t)\dy / Sqr(courbe(t)\dx*courbe(t)\dx+courbe(t)\dy*courbe(t)\dy)
Wend
t_max=t

;-correspondance s<===>(x,y)
s_max.w=Round(longueur_courbe,#PB_Round_Nearest)
Dim t_correspondant.l(s_max);tableau qui va permettre de faire le lien entre abscisse curviligne s et coordonnées cartésiennes x,y par le biais du paramètre t
; à chaque valeur de s on va faire correspondre une valeur t
For int_s=1 To s_max
  For i=1 To t_max
    If int_s=Round(courbe(i)\s,#PB_Round_Nearest)
      t_correspondant(int_s)=i
    EndIf
  Next i
Next int_s

For int_s=1 To s_max
  If  t_correspondant(int_s)=0
    t_correspondant(int_s)=t_correspondant(int_s-1)
  EndIf
Next int_s

;-PROGRAMME PRINCIPAL
InitSprite()
InitSprite3D()
InitKeyboard()
OpenWindow(0,0,0,#largeur_ecran,#hauteur_ecran,"Solide_guidé",#PB_Window_ScreenCentered|#PB_Window_SystemMenu  )
OpenWindowedScreen(WindowID(0),0,0,#largeur_ecran,#hauteur_ecran,0,0,0)

;-sprite piste
CreateSprite(#spr_piste,#largeur_ecran,#hauteur_ecran)
StartDrawing(SpriteOutput(#spr_piste))
For t=1 To t_max
  LineXY(x_point_precedent,y_point_precedent,courbe(t)\x,courbe(t)\y,RGB(255,255,255))
  x_point_precedent=courbe(t)\x
  y_point_precedent=courbe(t)\y
Next t
FillArea(10,750,RGB(255,255,255),RGB(0,128,0))
StopDrawing()

 ;-sprites du mobile 
CreateSprite(#spr_carre_droite,32,32,#PB_Sprite_Texture)
StartDrawing(SpriteOutput(#spr_carre_droite))
Box(0,0,32,32,RGB(255,255,0))
Box(16,13,16,6,RGB(255,0,0))
StopDrawing()
CreateSprite3D(#spr_carre_droite,#spr_carre_droite)

CreateSprite(#spr_carre_gauche,32,32,#PB_Sprite_Texture)
StartDrawing(SpriteOutput(#spr_carre_gauche))
Box(0,0,32,32,RGB(255,255,255))
Box(0,13,16,6,RGB(0,0,255))
StopDrawing()
CreateSprite3D(#spr_carre_gauche,#spr_carre_gauche)

t=1
;-BOUCLE PRINCIPALE
Repeat
  
  Repeat
    Event = WindowEvent()      
    If  Event = #PB_Event_CloseWindow
      End 
    EndIf
  Until Event = 0
  
  ;-équations du mouvement
  vs=vs+#g*courbe(t)\cosinus*#dt
  s=s+vs*#dt
  If s<1
    s=1
  EndIf
  
  ;recherche de la valeur de t
  t=t_correspondant(Int(s))
  
  ;-affichage des sprites
  DisplaySprite(#spr_piste,0,0)
  Start3D()
  
  ; calcul de l'angle de rotation du sprite en fonction de l'inclinaison de la courbe
  angle_rotation=180*ATan(courbe(t)\dy/courbe(t)\dx)/#PI 
  If courbe(t)\dx<0 
    angle_rotation=angle_rotation+180
  EndIf
  ;choix du sprite en fonction du sens de parcours
  If vs >=0 
    spr_carre=#spr_carre_droite
  Else
    spr_carre=#spr_carre_gauche
  EndIf
  RotateSprite3D(spr_carre,angle_rotation,0)
  
  DisplaySprite3D(spr_carre,courbe(t)\x-16,courbe(t)\y-16)
  Stop3D()
  ;-affichage des informations
  StartDrawing(ScreenOutput())
  DrawText(0,700,"distance= "+Str(courbe(t)\s)+ " sur "+Str(longueur_courbe)+" ( "+Str(courbe(t)\s/longueur_courbe*100)+" % )")
  DrawText(0,720,"s="+StrF(s)+" correspond à  t = "+Str(t)+ ">>>> s(t)= "+StrF(courbe(t)\s))
  DrawText(0,740,"vitesse= "+StrF(vs)+" accélération= "+StrF(#g*courbe(t)\cosinus))
  StopDrawing()
  Delay(10)
  FlipBuffers() 
ForEver
Hasta la vista !

PS : avec la partie II (gestion du contact solide-courbe), vous pourrez faire plein de Sonic :P
Dernière modification par Huitbit le mar. 29/juil./2008 5:59, modifié 1 fois.
Frenchy Pilou
Messages : 2194
Inscription : jeu. 27/janv./2005 19:07

Message par Frenchy Pilou »

Et après pour le fun des élèves
essayez Sketchyphysics2qui est un moteur "Physique" 3D
(plugin gratos du fabuleux gratos lui aussi Google Sketchup

(modeleur 3D ultra puissant avec la particularité d'avoir une courbe d'apprentissage de 15 minutes!!!
Un soft fabuleux à recommander pour les 7 à 77 ans! 8)

Et pour les plus cérebraux et conceptuels mais tout aussi fun!
Un "moteur Physique" 2D
Phun
Plus conceptuel mais terrible pour tester tout bidouillage en tout style!
Liquide, physique ou autre! Ils viennent même de réinventer le Sphirograph
puisqu'on peut mettre un "crayon" aux objets qui se balade en tout sens !
Un must à recommander pour les 10 -77 ans


PS
Evidemment ne pas oublier 3D Warehouse
qui permet de charger dans Google Sketchup n'importe quel model 3D!
Et donc de faire glisser une ferrari sur un plan incliné :wink:
Qu'est-ce qu'on ferait pas pour faire capter les rudiments de la physique :D
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Message par Backup »

Superbe Code huitbit :)

@ frenchy Merci pour les liens.. je n'avais pas vu qu'il y avait une nouvelle version de Phun :)
Frenchy Pilou
Messages : 2194
Inscription : jeu. 27/janv./2005 19:07

Message par Frenchy Pilou »

une nouvelle version de Phun
Oui le codeur n'arrête pas! 8)

Sinon par exemple dans Google Sketchup
toutes les fantaisies sont possibles!
On peut même faire rouler le bouzing aux joystick :roll: (on peut bien sûr cacher les roues "gonflées")
(evidemment on aura peut-être pas la même rapidité et fluidité que le code de Huibit :roll:
(ici rendu Podium un autre plugin gratoche en 500*500 et le plus facile du monde : 2 curseurs!!!)
Image
Image

C'est ce qui est le plus dur à appréhender pour un débutant! :D

On dessine un "joint" sur l'axe de la pièce la pièce qui va bouger
On "groupe" ce joint sur cette pièce
On "CONNECTE" ce joint sur une pièce "Parent" ! :D

Voilà, c'est tout, avec çà on peut faire n'importe quoi! :mrgreen:
Ici un , heu..., à deux axes pivotants :lol:
Evidemment les "flèches" sont sur un calque à part
et peuvent devenir invisibles d'un coup de baguette magique (fichier joint)
PS Damp çà veut dire attenuation dans le temps :wink:
Image
Dernière modification par Frenchy Pilou le sam. 19/juil./2008 0:07, modifié 5 fois.
Anonyme

Message par Anonyme »

8O
fouilloud
Messages : 34
Inscription : ven. 07/déc./2007 17:15

Message par fouilloud »

bonjour à tous

Frenchy Pilou, Google Sketchup est libre d'utilisation, mais pour 8 heures
seulement ! on ne peut pas vraiement dire qu'il est gratuit !!
Frenchy Pilou
Messages : 2194
Inscription : jeu. 27/janv./2005 19:07

Message par Frenchy Pilou »

Mais absolument pas! :roll:
C'est la version pro qui est valable 8 heures en essai!
Elle n'a en plus que des export de fichiers étendus et de la mise en page, inutiles pour les hobbystes ou utilisisateurs avisés :)
Toutes les autres fonctions sont valides dans la version gratoche et à durée illimitée! 8)
fouilloud
Messages : 34
Inscription : ven. 07/déc./2007 17:15

Message par fouilloud »

oups !

oui, mais si l'on clique sur télécharger on obtient :
"l'adresse semble incorrecte",

alors que pour la version pro tout se passe OK
comtois
Messages : 5186
Inscription : mer. 21/janv./2004 17:48
Contact :

Message par comtois »

Pour revenir au sujet initial , fantastique Huibit !
http://purebasic.developpez.com/
Je ne réponds à aucune question technique en PV, utilisez le forum, il est fait pour ça, et la réponse peut profiter à tous.
fouilloud
Messages : 34
Inscription : ven. 07/déc./2007 17:15

Message par fouilloud »

je viens de refaire un essai
toujour impossible, j'ai alors cliqué sur :

"En savoir plus sur Google SketchUp 6", puis clic sur "Télécharger Google SketchUp 6" et miracle, déroulement parfait.

comme quoi je devrais être plus réfléchis et essayer toutes les possibilités avant de me plaindre !!

merci pour l'info
Frenchy Pilou
Messages : 2194
Inscription : jeu. 27/janv./2005 19:07

Message par Frenchy Pilou »

Il y a quand même un petit truc curieux :)
C'est que les frottements devraient freiner l'engin :)
Là c'est le mouvement perpétuel, à moinsss que l'on soit dans le vide intersidéral :D


@Fouilloud: bonnes découvertes :wink:
Avatar de l’utilisateur
Huitbit
Messages : 940
Inscription : jeu. 08/déc./2005 5:19
Localisation : Guadeloupe

Message par Huitbit »

Merci,

Je m'attaque à la suite (j'en profiterai pour améliorer l'ensemble !!)

@Frenchy Pilou
Remarque : si on veut rajouter des frottements, il suffit de rajouter "- coeff_frott * v" dans le terme de droite)
C'est comme le Port Salut !

Dans équation du mouvement remplace

Code : Tout sélectionner

vs=vs+#g*courbe(t)\cosinus*#dt 
Par

Code : Tout sélectionner

vs=vs+(#g*courbe(t)\cosinus-0.004*vs)*#dt 

Hasta la vista !
beauregard
Messages : 1307
Inscription : dim. 08/juil./2007 18:32
Localisation : Toulouse

tourne manège

Message par beauregard »

Huitbit a écrit :PS : avec la partie II (gestion du contact solide-courbe), vous pourrez faire plein de Sonic :P
C'est encore une fois étonnant ! :)
Mais cela le serait tout autant, si les codeurs de sonic sur megadrive, avaient utilisé des techniques aussi évoluées, plutot que le système D...
J'espère que la récréation va continuer encore longtemps( je sauvegarde avec avidité tes petites merveilles, même si je n'ai pas le temps de les étudier pour le moment, honte à moi( chuis en pleine période de pixel art des décors de mon euj, et c'est interminable à faire...)).

un truc que je trouve curieux: il me semble que tout tes codes sont dépourvu de procédures...

Dommage que tmyke soit plus sur ce forum, il aurait surement apporté son savoir faire. :cry:
Dernière modification par beauregard le sam. 19/juil./2008 17:26, modifié 2 fois.
Frenchy Pilou
Messages : 2194
Inscription : jeu. 27/janv./2005 19:07

Message par Frenchy Pilou »

hihi
çà marche nickel le frottement :)
Avatar de l’utilisateur
Huitbit
Messages : 940
Inscription : jeu. 08/déc./2005 5:19
Localisation : Guadeloupe

Message par Huitbit »

'lut

@Beauregard
Dans Sonic, j'ai vu qu'ils utilisaient beaucoup de cercles (ou portions de cercles), ça simplifie les calculs :P !

Par exemple, il faut connaître le rayon de courbure(voir prochain sujet :wink: ) de la trajectoire pour savoir si le personnage reste en contact avec le sol(ce qui demande pas mal de calculs), pour un cercle, ce rayon de courbure est égal... au rayon :roll:. Les cercles (et donc bien sûr, les sinus et les cosinus) ont énormément de propriétés.
Autre exemple : longueur d'un arc de cercle = rayon * angle_en_radians (ce n'est pas par hasard que le périmètre d'un cercle =2*pi*r :wink: ).
Pour une courbe quelconque, il faut intégrer la relation
ds = sqr(dx²+dy²)*dt avec x et y fonctions du temps pour connaître la longueur s !

Il est fort possible que les concepteurs de Sonic aient travaillé de la même manière. Si on utilise les "bonnes" courbes, on s'en sort très bien !

Pour ce qui est des procédures (les macros c'est mieux non ?), pourquoi pas, j'en tiendrai compte pour le prochain sujet !


Hasta la vista !
Répondre