Fractal Flames
Übersicht

![]() |
NoobodyBetreff: Fractal Flames |
![]() Antworten mit Zitat ![]() |
---|---|---|
Kürzlich stiess ich bei einem Ausflug auf die englische Wikipedia auf einen kleinen Artikel über sogenannte Fractal Flames.
Dabei geht es nicht etwa - wie man vom Namen her schliessen könnte - um fraktale Flammen, sondern um eine Gruppe von Iterated Function Systems (kurz IFS). Was ist denn das schon wieder? In einem IFS wird anfangs ein zufälliger Punkt ausgewählt. Danach werden nacheinander verschiedene Funktionen darauf angewandt; durch jede Funktionsanwendung werden die Koordinaten des Punktes verändert und an der neuen Position wird ein Farbabdruck hinterlassen, der später beim Rendern verwendet wird. Die anzuwendenden Funktionen werden ebenfalls zufällig ausgewählt, jedoch wird nach einem bestimmten Schema vorgegangen: Jede Funktion erhält eine Gewichtung, die bestimmt, wie oft die Funktion aufgerufen wird. Je höher die Gewichtung im Vergleich zu den anderen Funktionen, desto öfter wird sie aufgerufen. Die fraktalen Flammen erweitern dieses IF - System um sogenannte Variationsfunktionen, die zusätzlich noch das Koordinatensystem verändern können - hier ins Detail zu gehen, würde jedoch den Rahmen dieses Posts sprengen. Kurz gefasst können mit fraktalen Flammen faszinierende Bilder generiert werden. Sie eignen sich perfekt als Bildschirmhintergrund oder zum Ausdrucken und Aufhängen ![]() Ich kann dabei nur empfehlen, selber ein wenig mit dem Code herumzuspielen und die schönsten Eigenkreationen hier zu posten. Die komplette Funktionsweise der einzelnen Parameter zu erklären, wäre hier wohl zuviel; allerdings bekommt man auch sehr schöne Resultate, wenn man einfach verschiedene Zahlen ausprobiert (allerdings sollten die Zahlen im Bereich von -1 bis 1 bleiben). Der Bereich im Code, wo man zu Werke gehen kann, ist durch Kommentare gekennzeichnet; was man alles beachten sollte, steht ebenfalls in den Kommentaren. Der Code: [AUSKLAPPEN] Const GWIDTH = 800
Const GHEIGHT = 600 Graphics GWIDTH, GHEIGHT, 0, 2 SetBuffer BackBuffer() Const RED = 0 Const GREEN = 1 Const BLUE = 2 Const FACTOR_A = 3 Const FACTOR_B = 4 Const FACTOR_C = 5 Const FACTOR_D = 6 Const FACTOR_E = 7 Const FACTOR_F = 8 Const WEIGHT = 9 Const BLEND_REFLECTION = 10 Const BLEND_SINUSODIAL = 11 Const BLEND_SPHERICAL = 12 Const BLEND_SWIRL = 13 Const BLEND_HORSESHOE = 14 Const BLEND_POLAR = 15 Const BLEND_HANDKERCHIEF= 16 Const VAR_REFLECTION = 0 Const VAR_SINUSODIAL = 1 Const VAR_SPHERICAL = 2 Const VAR_SWIRL = 3 Const VAR_HORSESHOE = 4 Const VAR_POLAR = 5 Const VAR_HANDKERCHIEF = 6 Dim F#( 31, 16 ) Dim Density#( GWIDTH - 1, GHEIGHT - 1 ) Dim RGB#( GWIDTH - 1, GHEIGHT - 1, 3 ) Dim MappedRGB#( GWIDTH - 1, GHEIGHT - 1, 3 ) Global FunctionCount, AccWeight#, RMin#, GMin#, BMin#, RMax#, GMax#, BMax# ;--------------------------------------------------------------- Ab hier eigene Funktionen kreieren ;Hinweise zur Funktionserstellung: ; AddFunction erstellt eine neue Funktion mit den Parametern A, B, C, D, E, F und mit einer bestimmten Gewichtung. ; SetFunctionColor legt für eine Funktion eine bestimmte Farbe fest. Der erste Parameter ist der Index der Funktion, beginnend mit 0 ; SetFunctionBlending bestimmt den Einfluss einer Variationsfunktion auf die Funktion. Der erste Parameter ist der Funktionsindex, der zweite Parameter ; die Variationsfunktion (man kann hier alle Konstanten angeben, die mit VAR_ beginnen) und der letzte Parameter bestimmt, ; wie gross der Einfluss auf die Funktion ist. ; A B C D E F Gewichtung AddFunction( 1, -0.4, 0.7, 0.3, 1, 0.7, 0.5 ) ;Funktionserstellung SetFunctionColor( 0, 0, 0, 0 ) ;Farbinitialisierung SetFunctionBlending( 0, VAR_HANDKERCHIEF, 1.2 ) ;Den Einfluss der einzelnen Variationsfunktionen festlegen SetFunctionBlending( 0, VAR_SPHERICAL, 0.9 ) SetFunctionBlending( 0, VAR_SWIRL, 0.4 ) ; A B C D E F Gewichtung AddFunction( 0.4, 0.4, 0.7, 0.8, 0.3, 0.2, 0.5 ) SetFunctionColor( 1, 255, 255, 255 ) SetFunctionBlending( 1, VAR_SWIRL, 0.7 ) SetFunctionBlending( 1, VAR_HORSESHOE, 0.5 ) ; A B C D E F Gewichtung AddFunction( 1, -0.4, 0.7, 0.3, 1, 0.7, 0.5 ) SetFunctionColor( 2, 0, 0, 255 ) SetFunctionBlending( 2, VAR_SPHERICAL, 2.7 ) ;------------------------------------------------------------------------------------------------------------ FractalFlame() End Function FractalFlame() Local X# = Rnd( -1, 1 ) Local Y# = Rnd( -1, 1 ) Local R# = Rnd( 0, 1 ) Local G# = Rnd( 0, 1 ) Local B# = Rnd( 0, 1 ) Local Iteration = 0, RenderTimer = MilliSecs() While True FunctionWeight# = Rnd( 0, AccWeight# ) For t = 0 To FunctionCount - 1 If FunctionWeight# < F( t, WEIGHT ) Then NewX# = F( t, FACTOR_A )*X# + F( t, FACTOR_B )*Y# + F( t, FACTOR_C ) NewY# = F( t, FACTOR_D )*X# + F( t, FACTOR_E )*Y# + F( t, FACTOR_F ) R# = ( R# + F( t, RED ) )/2. G# = ( G# + F( t, GREEN ) )/2. B# = ( B# + F( t, BLUE ) )/2. X# = 0 Y# = 0 RadiusSq# = NewX#*NewX# + NewY#*NewY# ;Hier werden Werte vorrausberechnet, die von den Variationen oft gebraucht werden. Radius# = Sqr( RadiusSq# ) For Variation = 0 To 6 If F( t, Variation + 10 ) <> 0 Then Select Variation Case VAR_REFLECTION X# = X# + NewX#*F( t, BLEND_REFLECTION ) Y# = Y# + NewY#*F( t, BLEND_REFLECTION ) Case VAR_SINUSODIAL X# = X# + Sin( NewX#*360 )*F( t, BLEND_SINUSODIAL ) Y# = Y# + Sin( NewY#*360 )*F( t, BLEND_SINUSODIAL ) Case VAR_SPHERICAL X# = X# + NewX#*F( t, BLEND_SPHERICAL )/RadiusSq# Y# = Y# + NewY#*F( t, BLEND_SPHERICAL )/RadiusSq# Case VAR_SWIRL X# = X# + ( NewX#*Sin( RadiusSq# ) - NewY#*Cos( RadiusSq# ) )*F( t, BLEND_SWIRL ) Y# = Y# + ( NewX#*Cos( RadiusSq# ) + NewY#*Sin( RadiusSq# ) )*F( t, BLEND_SWIRL ) Case VAR_HORSESHOE X# = X# + ( NewX# - NewY# )*( NewX# + NewY# )*F( t, BLEND_HORSESHOE )/RadiusSq# Y# = Y# + 2*NewX#*NewY#*F( t, BLEND_HORSESHOE )/RadiusSq# Case VAR_POLAR X# = X# + ATan( NewX#/NewY# )/180*F( t, BLEND_POLAR ) Y# = Y# + ( Radius# - 1 )*F( t, BLEND_POLAR ) Case VAR_HANDKERCHIEF X# = X# + Radius#*Sin( ATan( NewX#/NewY# ) + Radius#*360 )*F( t, BLEND_HANDKERCHIEF ) Y# = Y# + Radius#*Cos( ATan( NewX#/NewY# ) - Radius#*360 )*F( t, BLEND_HANDKERCHIEF ) End Select EndIf Next Exit EndIf FunctionWeight# = FunctionWeight# - F( t, WEIGHT ) Next Iteration = Iteration + 1 If Iteration > 20 Then FinalTransform( X#, Y#, Iteration/10000000., R#, G#, B# ) If MilliSecs() - RenderTimer > 3000 Then Cls ToneMap( 1.01 ) Render() Flip 0 RenderTimer = MilliSecs() EndIf If KeyHit( 1 ) Then End Wend End Function Function FinalTransform( FX#, FY#, FDensity#, R#, G#, B# ) X = FX#*GWIDTH/10 + GWIDTH/2 Y = FY#*GHEIGHT/10 + GHEIGHT/2 If X >= 0 And X < GWIDTH And Y >= 0 And Y < GHEIGHT Then RGB( X, Y, RED ) = ( RGB( X, Y, RED )*Density( X, Y ) + R#*FDensity# )/( Density( X, Y ) + FDensity# ) RGB( X, Y, GREEN ) = ( RGB( X, Y, GREEN )*Density( X, Y ) + G#*FDensity# )/( Density( X, Y ) + FDensity# ) RGB( X, Y, BLUE ) = ( RGB( X, Y, BLUE )*Density( X, Y ) + B#*FDensity# )/( Density( X, Y ) + FDensity# ) Density( X, Y ) = Density( X, Y ) + FDensity# EndIf End Function Function Render() LockBuffer For X = 0 To GWIDTH - 1 For Y = 0 To GHEIGHT - 1 R# = ( MappedRGB( X, Y, RED ) - RMin# )/( RMax# - RMin# ) G# = ( MappedRGB( X, Y, GREEN ) - GMin# )/( GMax# - GMin# ) B# = ( MappedRGB( X, Y, BLUE ) - BMin# )/( BMax# - BMin# ) WritePixelFast X, Y, Floor( 255*R# ) Shl 16 + Floor( 255*G# ) Shl 8 + Floor( 255*B# ) Next Next UnlockBuffer End Function Function ToneMap( B# ) RMin# = 10000 GMin# = 10000 BMin# = 10000 RMax# = -10000 GMax# = -10000 BMax# = -10000 For X = 0 To GWIDTH - 1 For Y = 0 To GHEIGHT - 1 MappedRGB( X, Y, RED ) = B#*RGB( X, Y, RED )/( ( B# - 1 )*RGB( X, Y, RED ) + 1 ) MappedRGB( X, Y, GREEN ) = B#*RGB( X, Y, GREEN )/( ( B# - 1 )*RGB( X, Y, GREEN ) + 1 ) MappedRGB( X, Y, BLUE ) = B#*RGB( X, Y, BLUE )/( ( B# - 1 )*RGB( X, Y, BLUE ) + 1 ) If MappedRGB( X, Y, RED ) > RMax# Then RMax# = MappedRGB( X, Y, RED ) ElseIf MappedRGB( X, Y, RED ) < RMin# Then RMin# = MappedRGB( X, Y, RED ) If MappedRGB( X, Y, GREEN ) > GMax# Then GMax# = MappedRGB( X, Y, GREEN ) ElseIf MappedRGB( X, Y, GREEN ) < GMin# Then GMin# = MappedRGB( X, Y, GREEN ) If MappedRGB( X, Y, BLUE ) > BMax# Then BMax# = MappedRGB( X, Y, BLUE ) ElseIf MappedRGB( X, Y, BLUE ) < BMin# Then BMin# = MappedRGB( X, Y, BLUE ) Next Next End Function Function AddFunction( FA#, FB#, FC#, FD#, FE#, FF#, FWeight# ) F( FunctionCount, RED ) = Rnd( 0, 1 ) F( FunctionCount, GREEN ) = Rnd( 0, 1 ) F( FunctionCount, BLUE ) = Rnd( 0, 1 ) F( FunctionCount, FACTOR_A ) = FA# F( FunctionCount, FACTOR_B ) = FB# F( FunctionCount, FACTOR_C ) = FC# F( FunctionCount, FACTOR_D ) = FD# F( FunctionCount, FACTOR_E ) = FE# F( FunctionCount, FACTOR_F ) = FF# F( FunctionCount, WEIGHT ) = FWeight# FunctionCount = FunctionCount + 1 AccWeight# = AccWeight# + FWeight# End Function Function SetFunctionColor( FunctionIndex, R, G, B ) F( FunctionIndex, RED ) = R/255. F( FunctionIndex, GREEN ) = G/255. F( FunctionIndex, BLUE ) = B/255. End Function Function SetFunctionBlending( FunctionIndex, Variation, BlendFactor# ) F( FunctionIndex, Variation + 10 ) = BlendFactor# End Function Da die Funktionen alle zufällig angewandt werden, hat man nicht plötzlich ein fertig gerendertes Bild, sondern nur einen Punktehaufen, der sich mit der Zeit immer weiter verfeinert. Je nach Funktionszusammenstellung ergeben sich verschiedene Berechnungszeiten, bis ein zufriedenstellendes Bild erstellt wurde. Alle 3 Sekunden wird ein neues Bild gezeichnet, um den aktuellen Fortschritt anzuzeigen - für die folgenden Bilder habe ich je 1-3 Minuten gewartet, bis ich den Screenshot gemacht habe. Hier einige Beispiele von erstellten Bildern: ![]() ![]() ![]() |
||
- Zuletzt bearbeitet von Noobody am Mi, Mai 06, 2009 7:41, insgesamt einmal bearbeitet
![]() |
Nova |
![]() Antworten mit Zitat ![]() |
---|---|---|
Faszinierend!
Hast du vielleicht einen deutschen Link der erklärt, wie das funktioniert? Oder könntest du das hier nochmal etwas näher erläutern? Ich würde das zu gerne nachcoden! ![]() |
||
AMD Athlon II 4x3,1GHz, 8GB Ram DDR3, ATI Radeon HD 6870, Win 7 64bit |
![]() |
MikeDee |
![]() Antworten mit Zitat ![]() |
---|---|---|
Ich verstehe zwar kein Wort, ist ja auch schon spät, aber man, das sieht echt gut gemacht. Seltsamerweiße ist bei jedem Bild bei mir die Grundfarbe blau. | ||
Nicht wenige benutzen die Anonymität des Internets um berühmt zu werden. |
![]() |
Valnar |
![]() Antworten mit Zitat ![]() |
---|---|---|
Kannst du evtl. den Trennstrich im Code kleiner machen? Der sprengt bei mir das ganze Design, da er nicht umgebrochen wird!
DANKE! @Topic: währe ein Cooler Bildschirmschoner, eventuell Bastel ich mir selber mal einen, es gibt dazu ja ne Howto hier. |
||
AvaGast |
![]() Antworten mit Zitat |
|
---|---|---|
Besonders das dritte Bild find ich total schön! Das würd ich mir glatt in meinem Zimmer aufhängen ![]() ![]() ![]() |
||
![]() |
ozzi789 |
![]() Antworten mit Zitat ![]() |
---|---|---|
Noobody du bist ein Genie Oo
Werd gleich ein wenig dran rumschrauben, obwohl ich nicht viel davon versteh << mfg ozzi |
||
0x2B || ! 0x2B
C# | C++13 | Java 7 | PHP 5 |
![]() |
Noobody |
![]() Antworten mit Zitat ![]() |
---|---|---|
Nova hat Folgendes geschrieben: Hast du vielleicht einen deutschen Link der erklärt, wie das funktioniert? Oder könntest du das hier nochmal etwas näher erläutern? Ich würde das zu gerne nachcoden!
Auf deutsch leider überhaupt nicht, auf englisch gibt es hier (PDF) eine Dokumentation der Mathematik dahinter, geschrieben vom Erfinder der Fractal Flames. Mit der Doku hatte ich so meine Probleme, weil sie einige Dinge mehrdeutig erklärt, daher weiss ich auch nicht, ob meine Implementation 'richtig' ist ![]() Wenn das auch nicht hilft, werde ich mir heute Abend mal Zeit nehmen und versuchen, das zu erklären. MikeDee hat Folgendes geschrieben: Seltsamerweiße ist bei jedem Bild bei mir die Grundfarbe blau.
Die dritte Funktion im Beispiel hat auch eine blaue Farbe, im Code steht ja Code: [AUSKLAPPEN] SetFunctionColor( 2, 0, 0, 255 )
Entweder, du färbst die Funktion anders ein oder löscht sie ganz, das sollte den Blaustich beheben ![]() Valnar hat Folgendes geschrieben: Kannst du evtl. den Trennstrich im Code kleiner machen? Der sprengt bei mir das ganze Design, da er nicht umgebrochen wird!
Done. |
||
Man is the best computer we can put aboard a spacecraft ... and the only one that can be mass produced with unskilled labor. -- Wernher von Braun |
![]() |
Chrise |
![]() Antworten mit Zitat ![]() |
---|---|---|
Ach wie geil ist das denn oO
Wofür mit Bildbearbeitungsprogrammen aufwendig irgendwelche Bilder herstellen, wenns auch einfach mit einem Code geht, den Noobody bestimmt mal wieder einfach so nebenbei geschrieben hat?^^ Programmier doch gleich ein Bildbearbeitungsprogramm, vielleicht findest du mal Sonntags Nachmittag - so ganz nebenbei ![]() Also dir kommt allmählich keiner mehr in Sachen Speed und Codeneuheiten mehr nach. Weiter so, deine Arbeiten sind Spitze und schön anzusehen! |
||
Llama 1 Llama 2 Llama 3
Vielen Dank an Pummelie, der mir auf seinem Server einen Platz für LlamaNet bietet. |
![]() |
hecticSieger des IS Talentwettbewerb 2006 |
![]() Antworten mit Zitat ![]() |
---|---|---|
Genau genommen ist es eine in die dritte Dimension verdrehte zweidimensionale Fläche. Oder sehe ich das falsch?
Wenn man nun die zweidimensionale Fläche in nur einer Dimension zeichnet und die zweite Dimension in die Zeit streckt, bekommt man eine schöne Animation raus. Allerdings sieht das Einzelbild natürlich nicht so gut aus. Code: [AUSKLAPPEN] Graphics 400,400,0,2
SetBuffer BackBuffer() qq#=0 za#=0 x1#=0 y1#=0 x2#=0 y2#=0 While Not KeyHit(1) za=za+1 LockBuffer BackBuffer() For qq=0 To 9999 x1=Sin(qq/3)/8 y1=Cos(qq/2)/8 x2=Sin(qq*x1+za)*(qq+x1)/60 y2=Cos(qq*y1)*(qq+y1)/60 WritePixelFast 200+x2,200+y2,14737632 Next UnlockBuffer BackBuffer() Flip Cls Wend End Dieser Code stammt noch aus meiner Power-Basic 2.0 -Zeit. |
||
Download der Draw3D2 V.1.1 für schnelle Echtzeiteffekte über Blitz3D |
![]() |
SpionAtom |
![]() Antworten mit Zitat ![]() |
---|---|---|
Schöne Sachen das!
Und Schöne Sache hectic. Bei diesen Bildern kann man nie sagen, ob sie links oder rechtsdrehend sind. (Ich kann es halbwegs steuern in welche Richtung ich es haben will, ist ne tolle Konzentrationsübung^^) |
||
os: Windows 10 Home cpu: Intel Core i7 6700K 4.00Ghz gpu: NVIDIA GeForce GTX 1080 |
![]() |
NightPhoenix |
![]() Antworten mit Zitat ![]() |
---|---|---|
*zustimm* fällt einem doch recht schwer, wenn sich das Hirn erstmal eine Richtung ausgesucht hat ![]() ![]() |
||
aletes |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
gut gemacht
hier mal mein ergebnis: ![]() |
||
![]() |
Noobody |
![]() Antworten mit Zitat ![]() |
---|---|---|
hectic hat Folgendes geschrieben: Genau genommen ist es eine in die dritte Dimension verdrehte zweidimensionale Fläche. Oder sehe ich das falsch?
Ganz so einfach ist es nicht ![]() Im Programm selbst wird keine dritte Dimension eingeführt, es wird einfach das zweidimensionale Koordinatensystem durch bestimmte Funktionen verzerrt. Der Grundstamm an Funktionen wird durch AddFunction gestellt. Diese Funktionen bestimmen die Koordinatenachsen des Koordinatensystems; auf den Punkt wird eine sogenannte affine Transformation durchgeführt. Zusätzlich werden noch Variationsfunktionen auf das Koordinatensystem ausgeführt. Diese Variationen sind nicht-linear und verzerren daher das System so, dass es ähnlich wie 3D aussieht (die Variation VAR_HANDKERCHIEF beispielsweise 'zerknüllt' das Koordinatensystem ähnlich wie ein Taschentuch, wodurch die Bereiche in der Mitte aussehen, als wären sie nach vorne gewölbt). Dieser 3D - Effekt wird zusätzlich noch dadurch verstärkt, dass gewisse Teile des Fraktals vor anderen gezeichnet werden, was durch die Dichteverteilung erreicht wird, die die Farbgebung eines bestimmten Pixels bestimmt. Das anschliessend angewandte Tonemapping tut auch noch seinen Teil (wobei ich hier auf den eher simpleren Schlick-Operator zurückgegriffen habe, wodurch leider die Farbqualität verringert wird; andere Verfahren wären wohl zu rechenintensiv). Es ist also keine in 3D gewölbte Fläche, sondern ein verzerrtes Koordinatensystem - der 3D Effekt ist aber durchaus erwünscht, weswegen die Variationsfunktionen überhaupt ausgeführt werden. |
||
Man is the best computer we can put aboard a spacecraft ... and the only one that can be mass produced with unskilled labor. -- Wernher von Braun |
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group