Solide guidé et subdivision

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 guidé et subdivision

Message par Huitbit »

Aloah la communauté !

Oldskull III a pris beaucoup de retard :?

Voilà en avant-première un bout de code.

(Vous vous souvenez de http://www.purebasic.fr/french/viewtopi ... ubdivision et de http://www.purebasic.fr/french/viewtopi ... hilit=rail (pour le solide guidé, j'ai fait plus simple, à "l'époque", je m'étais un peu emballé! :lol: )? )

Quelques vagues (taper F1 pour changer la courbe ; et zou, un Goto dans le programme :mrgreen: ) pour que Mitch Dobro se mette au surf avant de partir :lol: :lol: !
Attention, pas de crême solaire :mrgreen: , ça bousille les récifs coraliens !

Code : Tout sélectionner

;Solide guidé et subdivision 
;Auteur Huitbit
;PureBasic 4.31 (Windows - x86)
;*********************************
#largeur_ecran=1024
#hauteur_ecran=768
#spr_decor=0
#spr=1
#indice_max_des_pts_de_controle=7
#nbre_de_subdivisions=3
indice_max_des_pts.l=(#indice_max_des_pts_de_controle-1)*Pow(2,#nbre_de_subdivisions)+1 ;pour avoir le nombre de points, ajouter 1 à l'indice !
rapport.f=0.25
Structure infos_point
  x.l
  y.l ; y = a * x +b
  s.l
  a.f
  b.f
 
EndStructure

Structure infos_s
  x.f
  y.f
  sinus.f
  cosinus.f
  angle_par_rapport_horizontale.f
EndStructure

Macro affine(a,b,xA,yA,xB,yB)
a=(yB-yA)/(xB-xA)
b=(yA*xB-yB*xA)/(xB-xA)
EndMacro


;-######################################
;-PROGRAMME PRINCIPAL
;-######################################

InitSprite()
InitSprite3D()
InitKeyboard()
OpenWindow(0,0,0,#largeur_ecran,#hauteur_ecran,"Solide guidé et subdivision  !!! F1 pour changer de courbe !!!",#PB_Window_ScreenCentered|#PB_Window_SystemMenu  )
OpenWindowedScreen(WindowID(0),0,0,#largeur_ecran,#hauteur_ecran,0,0,0)

;-label pour le Goto, tracé d'une nouvelle courbe
nouvelle_courbe :
;-tableau des points de la courbe
Dim P.infos_point (indice_max_des_pts)
;initialisation des points de contrôle
P(0)\x=10
P(0)\y=#hauteur_ecran*0.1
P(1)\x=10+#largeur_ecran/#indice_max_des_pts_de_controle
P(1)\y=#hauteur_ecran*0.5

For i=2 To #indice_max_des_pts_de_controle-2
  P(i)\x=P(i-1)\x+#largeur_ecran/#indice_max_des_pts_de_controle
  P(i)\y=#hauteur_ecran*0.5+#hauteur_ecran*0.25-Random(#hauteur_ecran*0.5)
Next i
P(#indice_max_des_pts_de_controle-1)\x=#largeur_ecran-#largeur_ecran/#indice_max_des_pts_de_controle
P(#indice_max_des_pts_de_controle-1)\y=P(0)\y

P(#indice_max_des_pts_de_controle)\x=#largeur_ecran
P(#indice_max_des_pts_de_controle)\y=P(0)\y

;-subdivisions de la courbe
For subdivision_en_cours=0 To #nbre_de_subdivisions-1
  indice_max_provisoire=(#indice_max_des_pts_de_controle-1)*Pow(2,subdivision_en_cours)+1
  For i=indice_max_provisoire-1 To 0 Step -1
    P(2*i+1)\x=P(i)\x+(1-rapport)*(P(i+1)\x-P(i)\x)
    P(2*i+1)\y=P(i)\y+(1-rapport)*(P(i+1)\y-P(i)\y)
    P(2*i)\x=P(i)\x+rapport*(P(i+1)\x-P(i)\x)
    P(2*i)\y=P(i)\y+rapport*(P(i+1)\y-P(i)\y)
  Next i
Next subdivision_en_cours
P(0)\x=0
P(0)\y=#hauteur_ecran*0.1
P(indice_max_des_pts)\x=#largeur_ecran
P(indice_max_des_pts)\y=P(0)\y

;-coordonnées de départ du sprite
x_sprite.f=P(0)\x
y_sprite.f=P(0)\y

;-calculs des équations affines de chaque segment
For i=0 To indice_max_des_pts-1
  affine(P(i)\a,P(i)\b,P(i)\x,P(i)\y,P(i+1)\x,P(i+1)\y)
Next i

;-calcul de l'abscisse curviligne  de chaque point P(i)  en calculant la longueur de chaque segment [P(i)P(i+1)]
; formule P(i+1)\s=P(i)\s+Sqr(1+Pow(P(i)\a,2))*dx
; dx distance parcourue selon l'axe des x entre deux points
;dx remis à zéro à chaque changement de points
P(0)\s=0
x.f=0;abscisse de référence
i=0;indice des points
While i<>indice_max_des_pts
  x.f=x+1
  dx.f=dx+1
  If x>P(i+1)\x
    P(i+1)\s=P(i)\s+Sqr(1+Pow(P(i)\a,2))*dx
    i=i+1
    dx=0
  EndIf 
Wend

;-correspondance abscisse curviligne s avec  coordonnées (x,y)
Dim s.infos_s(P(indice_max_des_pts)\s)
p=0
x=0
For i=0 To indice_max_des_pts-1
  dx=(P(i+1)\x-P(i)\x)/(P(i+1)\s-P(i)\s) ; dx dépend de la longueur de la courbe,
  dy.f=(P(i+1)\y-P(i)\y)/(P(i+1)\s-P(i)\s); idem dy 
  ; grâce au calcul de dx, on se déplace sur la courbe de 1 en 1  pour s l'abscisse curviligne 
  While x<P(i+1)\x
    s(p)\x=x
    s(p)\y=P(i)\a*x+P(i)\b
    s(p)\sinus=dy
    s(p)\cosinus=dx
    s(p)\angle_par_rapport_horizontale=ATan(dy/dx)*180/#PI ;pas de précautions avec l'arctangente dx est toujours différent de 0
    x=x+dx
    p=p+1
  Wend
Next i

CreateSprite(#spr_decor,#largeur_ecran,#hauteur_ecran)
StartDrawing(SpriteOutput(#spr_decor))
For couche=0 To 50
  For i=0 To indice_max_des_pts-1
    LineXY(P(i)\x,P(i)\y+couche,P(i+1)\x,P(i+1)\y+couche,RGB(0,0,255-couche*5))
  Next i
Next couche
StopDrawing()

CreateSprite(#spr,48,48,#PB_Sprite_Texture)
StartDrawing(SpriteOutput(#spr))
DrawingMode(#PB_2DDrawing_Outlined  )
Box(0,0,48,48,RGB(255,255,255))
Line(24,24,24,0,RGB(255,255,255))
StopDrawing()
CreateSprite3D(#spr,#spr)

p=0

;-######################################
;-BOUCLE PRINCIPALE
;-######################################
Repeat
  ;-affichage
  FlipBuffers() 
  
  DisplaySprite(#spr_decor,0,0)
  
  Start3D()
  RotateSprite3D(#spr,angle,0)
  DisplaySprite3D(#spr,x_sprite,y_sprite)
  Stop3D()
  
  ;-équation du mouvement 
  dp.f=dp+s(p)\sinus*0.2 ; s(p)\sinus=cos(angle formé par le vecteur poids et la tangente à la courbe)
  p=p+dp
  
  ;-gestion  de la sortie d'écran
  If p> P(indice_max_des_pts)\s
    p=0
    dp=0
  EndIf 
  If p<0
    p=0
    dp=0
  EndIf 
  
  angle = s(p)\angle_par_rapport_horizontale
    ; 24(24 pixels : moitié du sprite) pour le  centrage du sprite3D sur la courbe et sinus, cosinus pour le décalage par rapport à la courbe(pour que le sprite soit bien sur la courbe et non à cheval)
  x_sprite=s(p)\x-24*(1-s(p)\sinus)
  y_sprite=s(p)\y-24*(1+s(p)\cosinus)
  
  
  Delay(1)
  
  ExamineKeyboard()
  If KeyboardReleased(#PB_Key_F1)
    Goto nouvelle_courbe
  EndIf
  
Until WindowEvent() = #PB_Event_CloseWindow 


Pour changer les paramètres, c'est au début !

Code : Tout sélectionner

#indice_max_des_pts_de_controle=7
#nbre_de_subdivisions=3 ;plus c'est élévé plus la courbe est lissée et vice versa
rapport.f=0.25
C'est encore expérimental (le décollage, la chute libre, la réception(je compte faire mieux pour l'atterrissage cette fois-ci !)...etc vont suivre), je commenterai ça plus tard.

Ici, toujours 30°C, la mer, ça baisse un peu (28 °C) :lol: :lol: :lol:

Hasta la vista !
Elevé au MSX !
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Re: Solide guidé et subdivision

Message par djes »

Excellent, comme d'hab! Tu veux quelques icebergs pour refroidir un peu la mer?
Avatar de l’utilisateur
flaith
Messages : 1487
Inscription : jeu. 07/avr./2005 1:06
Localisation : Rennes
Contact :

Re: Solide guidé et subdivision

Message par flaith »

Huitbit a écrit :...je commenterai ça plus tard...
:| Oui vite s'il te plait, que je commence à comprendre vos codes un peu mieux :wink:
Avatar de l’utilisateur
Huitbit
Messages : 940
Inscription : jeu. 08/déc./2005 5:19
Localisation : Guadeloupe

Re: Solide guidé et subdivision

Message par Huitbit »

Merci !
Je continue de creuser,... travailler avec des courbes subdivisées amène des simplifications intéressantes !
Je posterai quand j'aurai fini le décollage :wink:

Ca avance :roll:
Image
Les points verts correspondent aux points après subdivision.
En rouge les parties de la courbe où les rayons de courbure sont négatifs.

Hasta la vista !
Elevé au MSX !
Répondre