Solide guidé et subdivision
Publié : mer. 04/nov./2009 3:21
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é!
)? )
Quelques vagues (taper F1 pour changer la courbe ; et zou, un Goto dans le programme
) pour que Mitch Dobro se mette au surf avant de partir
!
Attention, pas de crême solaire
, ça bousille les récifs coraliens !
Pour changer les paramètres, c'est au début !
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)
Hasta la vista !
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é!

Quelques vagues (taper F1 pour changer la courbe ; et zou, un Goto dans le programme



Attention, pas de crême solaire

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
Ici, toujours 30°C, la mer, ça baisse un peu (28 °C)



Hasta la vista !