Code : Tout sélectionner
;Perlin&Subdivisions
;Auteur Huitbit
;Février 2011
;PureBasic 4.51 (Windows - x86)
; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
#LargeurEcran = 800
#HauteurEcran = 600
#NbreDeSubdivisions = 3
#OctaveMax = 5
#Persistance = 0.4
Octave.b
Persistance.f
#NombreInitialDePtsDeCtrl = 8
IndiceMaxTableau.l
TailleTableau.l = ((#NombreInitialDePtsDeCtrl*Pow(2,#OctaveMax - 1) - 2) * Pow(2,#NbreDeSubdivisions) + 1)
RapportSubdv.f = 0.25
FacteurNormalisation.f =(1 - Pow(#Persistance,#OctaveMax)) / (1 - #Persistance)
Bruit1DNormeA.f
Bruit1DNormeB.f
Structure InfosPoint
x.l
y.l ; y = a * x + b
a.f ; pente
b.f ; ordonnée à l'origine
EndStructure
Macro affine(a,b,uA,zA,uB,zB)
If (uB-uA)<>0
a = (zB - zA) / (uB - uA)
b = zB - a * uB
EndIf
EndMacro
; - ######################################
; - PROGRAMME PRINCIPAL
; - ######################################
InitSprite()
InitKeyboard()
OpenWindow(0,0,0,#LargeurEcran,#HauteurEcran,"Test Perlin 1D Tapez F1 pour créer une nouvelle courbe",#PB_Window_ScreenCentered|#PB_Window_SystemMenu )
OpenWindowedScreen(WindowID(0),0,0,#LargeurEcran,#HauteurEcran,0,0,0)
;- label pour le Goto, tracé d'une nouvelle courbe
NouvelleCourbe :
;- tableau des points de la courbe
Dim P.InfosPoint (TailleTableau,#OctaveMax)
Dim Bruit1D.l(1024)
For Octave = 1 To #OctaveMax
NombreDePtsDeCtrl = #NombreInitialDePtsDeCtrl *Pow(2,Octave - 1)
IndiceMaxTableau = ((NombreDePtsDeCtrl - 2) * Pow(2,#NbreDeSubdivisions) + 1) ;pour avoir le nombre de points, ajouter 1 à l'indice !
Persistance = Pow(#Persistance,Octave - 1)
;initialisation des points de contrôle
;Départ et arrivée
P(0,Octave)\x = 0
P(0,Octave)\y = 0
P(NombreDePtsDeCtrl - 1,Octave)\x = #LargeurEcran
P(NombreDePtsDeCtrl - 1,Octave)\y = P(0,Octave)\y
;Autres points
For i = 1 To NombreDePtsDeCtrl - 2
P(i,Octave)\x = i * #LargeurEcran / (NombreDePtsDeCtrl - 1)
P(i,Octave)\y = Random(255)*Persistance
Next i
;- subdivisions de la courbe
For SubdivisionEnCours = 0 To #NbreDeSubdivisions - 1
IndiceMaxProvisoire = (NombreDePtsDeCtrl - 2) * Pow(2,SubdivisionEnCours) + 1
For i = IndiceMaxProvisoire - 1 To 1 Step - 1
If i = IndiceMaxProvisoire - 1
P(2 * i + 1,Octave)\x = #LargeurEcran
P(2 * i + 1,Octave)\y = P(0,Octave)\y
P(2 * i,Octave)\x = P(i,Octave)\x + RapportSubdv * (P(i + 1,Octave)\x - P(i,Octave)\x)
P(2 * i,Octave)\y = P(i,Octave)\y + RapportSubdv * (P(i + 1,Octave)\y - P(i,Octave)\y)
Else
P(2 * i + 1,Octave)\x = P(i,Octave)\x + (1 - RapportSubdv) * (P(i + 1,Octave)\x - P(i,Octave)\x)
P(2 * i + 1,Octave)\y = P(i,Octave)\y + (1 - RapportSubdv) * (P(i + 1,Octave)\y - P(i,Octave)\y)
P(2 * i,Octave)\x = P(i,Octave)\x + RapportSubdv * (P(i + 1,Octave)\x - P(i,Octave)\x)
P(2 * i,Octave)\y = P(i,Octave)\y + RapportSubdv * (P(i + 1,Octave)\y - P(i,Octave)\y)
EndIf
Next i
P(1,Octave)\x = P(0,Octave)\x + (1 - RapportSubdv) * (P(1,Octave)\x - P(0,Octave)\x)
P(1,Octave)\y = P(0,Octave)\y + (1 - RapportSubdv) * (P(1,Octave)\y - P(0,Octave)\y)
Next SubdivisionEnCours
;-calculs des équations affines de chaque segment
For i = 0 To IndiceMaxTableau - 1
affine(P(i,Octave)\a,P(i,Octave)\b,P(i,Octave)\x,P(i,Octave)\y,P(i + 1,Octave)\x,P(i + 1,Octave)\y)
Next i
CreateSprite(Octave,#LargeurEcran,#HauteurEcran)
StartDrawing(SpriteOutput(Octave))
For i = 0 To IndiceMaxTableau - 1
LineXY(P(i,Octave)\x,#HauteurEcran - P(i,Octave)\y,P(i + 1,Octave)\x,#HauteurEcran - P(i + 1,Octave)\y ,RGB(0,50 + Octave*30,255 ))
Next i
StopDrawing()
Next Octave
;-Bruit1D, somme de toutes les octaves
For Octave = 1 To #OctaveMax
NombreDePtsDeCtrl = #NombreInitialDePtsDeCtrl *Pow(2,Octave - 1)
IndiceMaxTableau = ((NombreDePtsDeCtrl - 2) * Pow(2,#NbreDeSubdivisions) + 1) ;pour avoir le nombre de points, ajouter 1 à l'indice !
x = 0
For i = 0 To IndiceMaxTableau - 1
While x < P(i+1,Octave)\x
Bruit1D(x) = Bruit1D(x) + P(i,Octave)\a * x + P(i,Octave)\b
x = x + 1
Wend
Next i
Next Octave
Bruit1D(#LargeurEcran) = Bruit1D(0)
CreateSprite(#OctaveMax+1,#LargeurEcran,#HauteurEcran)
StartDrawing(SpriteOutput(#OctaveMax+1))
For x= 0 To #LargeurEcran - 1
Bruit1DNormeA = #HauteurEcran - Bruit1D(x) / FacteurNormalisation
Bruit1DNormeB = #HauteurEcran - Bruit1D(x + 1) / FacteurNormalisation
LineXY(x, Bruit1DNormeA, x + 1, Bruit1DNormeB,RGB(255,0,0))
Next x
StopDrawing()
;- ######################################
;- BOUCLE PRINCIPALE
;- ######################################
Repeat
;- affichage
FlipBuffers()
For Octave = 1 To #OctaveMax
DisplayTransparentSprite(Octave,0,0)
Next Octave
DisplayTransparentSprite(#OctaveMax + 1,0,0)
Delay(1)
ExamineKeyboard()
If KeyboardReleased(#PB_Key_F1)
ClearScreen(RGB(0,0,0))
Goto NouvelleCourbe
EndIf
Until WindowEvent() = #PB_Event_CloseWindow