Pflanzenkreation durch L - Systeme

Übersicht BlitzBasic Codearchiv

Neue Antwort erstellen

Noobody

Betreff: Pflanzenkreation durch L - Systeme

BeitragMo, Apr 27, 2009 21:32
Antworten mit Zitat
Benutzer-Profile anzeigen
Da ich mich seit längerer Zeit für Fraktale, insbesondere ihre Darstellung durch L - Systeme interessiere, bin ich vor kurzem auf das Buch The algorithmic beauty of plants (PDF) gestossen.

Es behandelt die Darstellung von Pflanzen durch sogenannte Lindenmayer - Systeme.
Ein Lindenmayer - System ist eigentlich nichts anderes als ein String, dessen Buchstaben nach bestimmten Regeln durch andere ersetzt werden. Der resultierende String wird wieder nach den Regeln buchstabenweise ersetzt, dessen resultierender String wird wieder ersetzt und so weiter.

Die Buchstaben im String werden nachher als Anweisungen interpretiert, wie die Pflanzen gezeichnet werden sollen - wie genau das geschieht, sollte man auf Wikipedia nachlesen, wenn man sich dafür interessiert.

Mein Programm zeichnet vier verschiedene Pflanzen mithilfe des Lindenmayersystems.
Ich kann nur empfehlen, ein wenig mit dem Startstring und den Regeln rumzuspielen - ganz tolle Kreationen kann man ja hier posten Razz

Der Code: BlitzBasic: [AUSKLAPPEN]
Const GWIDTH = 800
Const GHEIGHT = 600

Graphics GWIDTH, GHEIGHT, 0, 2
SetBuffer BackBuffer()

Timer = CreateTimer( 60 )

Global Iterations = 5

While Not KeyHit( 1 )
Cls

ParseLSystem( 100, GHEIGHT, 2, 25.7, LSystem( Iterations, "F", "F->F[+F]F[-F]F" ) )
ParseLSystem( 250, GHEIGHT, 8, 20, LSystem( Iterations, "F", "F->F[+F]F[-F][F]" ) )
ParseLSystem( 400, GHEIGHT, 8, 22.5, LSystem( Iterations - 1, "F", "F->FF-[-F+F+F]+[+F-F-F]" ) )
ParseLSystem( 650, GHEIGHT, 8, 22.5, LSystem( Iterations, "X", "X->F-[[X]+X]+F[+FX]-X,F->FF" ) )

Iterations = Iterations + KeyHit( 200 ) - KeyHit( 208 )

Text 0, 0, "Generation " + Iterations

Flip 0
WaitTimer Timer
Wend
End

Function LSystem$( Generations, StartString$, Rules$ )
For i = 1 To Generations
Local ResultString$ = ""
For t = 1 To Len( StartString$ )
Offset = Instr( Rules$, Mid( StartString$, t, 1 ) + "->" )

If Offset Then
Offset2 = Instr( Rules$, ",", Offset )
If Not Offset2 Then Offset2 = Len( Rules$ ) + 1
ResultString$ = ResultString$ + Mid( Rules$, Offset + 3, Offset2 - Offset - 3 )
Else
ResultString$ = ResultString$ + Mid( StartString$, t, 1 )
EndIf
Next

StartString$ = ResultString$
Next

Return ResultString$
End Function

Function ParseLSystem( X#, Y#, StepSize#, Delta#, InString$ )
Local SavePointer, Rotation#[ 100 ], PositionX#[ 100 ], PositionY#[ 100 ], Angle# = 90

LockBuffer BackBuffer()
For i = 1 To Len( InString$ )
Select Mid( InString$, i, 1 )
Case "F", "X"
NewX# = X# + StepSize#*Cos( Angle )
NewY# = Y# - StepSize#*Sin( Angle )

Line X#, Y#, NewX#, NewY#

X# = NewX#
Y# = NewY#
Case "+"
Angle# = Angle# + Delta#
Case "-"
Angle# = Angle# - Delta#
Case "["
Rotation[ SavePointer ] = Angle
PositionX[ SavePointer ] = X
PositionY[ SavePointer ] = Y
SavePointer = SavePointer + 1
Case "]"
SavePointer = SavePointer - 1
Angle = Rotation[ SavePointer ]
X = PositionX[ SavePointer ]
Y = PositionY[ SavePointer ]
End Select
Next
UnlockBuffer BackBuffer()
End Function


Die Generation des L - Systems kann man mit den Pfeiltasten hoch/runter ändern. Standardmässig steht die Generation auf 5, wo die Pflanzen am besten aussehen. Höhere Werte benötigen eine extrem lange Berechnungszeit, daher nicht wirklich zu empfehlen.

Ein kleiner Screenshot:
user posted image

L - Systeme gibt es übrigens auch für 3D, wenn auch komplizierter. Ich arbeite gerade an der Umsetzung einer 3D - Pflanze. Ich bin gespannt auf das Ergebnis Razz
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
  • Zuletzt bearbeitet von Noobody am Sa, Mai 02, 2009 10:03, insgesamt einmal bearbeitet
 

FWeinb

ehemals "ich"

BeitragMo, Apr 27, 2009 21:55
Antworten mit Zitat
Benutzer-Profile anzeigen
Machst du auch noch was anderes als Coden ?
Sieht wieder super aus (habe sowas mal für einen BCC gemacht)
In 3D währe das bestimmt sehr cool.

mfg

ich
"Wenn die Menschen nur über das sprächen, was sie begreifen, dann würde es sehr still auf der Welt sein." Albert Einstein (1879-1955)
"If you live each day as if it was your last, someday you'll most certainly be right." Steve Jobs

Chrise

BeitragMo, Apr 27, 2009 22:04
Antworten mit Zitat
Benutzer-Profile anzeigen
sowas ist toll!
Das ganze in 3d wäre super! Vll auch noch mit Auto-Textur Koordinatenberechnung? xD
Machst du keine Picknickerpause mehr?^^
Llama 1 Llama 2 Llama 3
Vielen Dank an Pummelie, der mir auf seinem Server einen Platz für LlamaNet bietet.

DAK

BeitragMo, Apr 27, 2009 22:11
Antworten mit Zitat
Benutzer-Profile anzeigen
Noobody is on a coding spree!

nette sache, das ganze^^ schau nur, dass coden ned rein zu deinem leben wird Wink
Gewinner der 6. und der 68. BlitzCodeCompo

MikeDee

BeitragMo, Apr 27, 2009 22:15
Antworten mit Zitat
Benutzer-Profile anzeigen
Wenn man sich den Code so ansieht, sieht es gar nicht so kompliziert aus. Bestimmt werde ich es irgendwann, für irgendwas brauchen. Ich liebe solche sachen^^
Nicht wenige benutzen die Anonymität des Internets um berühmt zu werden.

Chrise

BeitragMo, Apr 27, 2009 22:23
Antworten mit Zitat
Benutzer-Profile anzeigen
Wenn das ganze denn in 3D umgesetzt werden würde, fällt mir gerade so auf, könnte man wunderbar Korallenriffe nachbilden. Allerdings wären Low-Polys dafür dringend notwendig. Könnte mir das aber als recht schön vorstellen, besonders für Unterwasserprojekte.
Llama 1 Llama 2 Llama 3
Vielen Dank an Pummelie, der mir auf seinem Server einen Platz für LlamaNet bietet.

MikeDee

BeitragMo, Apr 27, 2009 22:25
Antworten mit Zitat
Benutzer-Profile anzeigen
die 3D umsetzung in kombination mit Voxel währe doch auch was.
Nicht wenige benutzen die Anonymität des Internets um berühmt zu werden.
 

Ava

Gast

BeitragDi, Apr 28, 2009 3:16
Antworten mit Zitat
Voll toll !! Very Happy

kriD

BeitragDi, Apr 28, 2009 11:29
Antworten mit Zitat
Benutzer-Profile anzeigen
wenn du das echt in 3D umgesetzt bekommst, wirst du reich Wink solche tree-models kann man (wenn sie gut sind) für teuer geld verkaufen..
wird zumindest auf manchen pages angeboten, und bäume sind da meißt am teuersten...

ich muss sagen, was du hier im (fast) tagesrythmus ablieferst, ist echt mehr als impressive!
hut ab

lg kriD

EDIT: sehe ich das richtig, dass -wenn man eine "baumstufe" hochschaltet- einfach nur der teil der letzten "baumstufe" nochmal an den vorherigen teil drangesetzt wird (halt ein wenig verzweigter, aber ansonsten von der Form her identisch)?
Wenn ich du wäre, wäre ich lieber ich!

CypressArt

BeitragDi, Apr 28, 2009 16:53
Antworten mit Zitat
Benutzer-Profile anzeigen
wow! das sieht ja mega aus..und wenn das in 3D möglich wird!!

*gespanntbin*
(no comment) -> Google Search Bot!!

ComNik

BeitragDi, Apr 28, 2009 17:59
Antworten mit Zitat
Benutzer-Profile anzeigen
Montag: Physik Engine schreiben
Dienstag: Ego Shooter mit Taktikelementen
Mittwoch: Pflanzensysteme
Donnerstag: Seit 100 Jahren ungelöstes Mathematisches Problem lösen
Freitag: Entspannen (höchstens ein, zwei selbstständig lernende Ki's)
Samstag + Sonntag: Hardwareunterstüzte Gedankenkontrolle

Quizfrage: Wessen Wochenplan stelle ich dar? Wink

BTW: Super Programm!

lg
WIP: Vorx.Engine

MikeDee

BeitragDi, Apr 28, 2009 20:27
Antworten mit Zitat
Benutzer-Profile anzeigen
kurz und knapp: Noobody entwickelt Skynet Shocked
Nicht wenige benutzen die Anonymität des Internets um berühmt zu werden.

Noobody

BeitragDi, Apr 28, 2009 22:36
Antworten mit Zitat
Benutzer-Profile anzeigen
kriD hat Folgendes geschrieben:
sehe ich das richtig, dass -wenn man eine "baumstufe" hochschaltet- einfach nur der teil der letzten "baumstufe" nochmal an den vorherigen teil drangesetzt wird (halt ein wenig verzweigter, aber ansonsten von der Form her identisch)?

Ganz so einfach ist es nicht. Es wird nicht einfach der vorige Teil nochmals angesetzt, sondern es werden einzelne Seiten oder Knoten durch kleinere Bausteine ersetzt (Edge Replacing/Node replacing). Dadurch erhält man zwar sich wiederholende Strukturen, allerdings komplexer als durch neu-Ansetzen.
Wenn du dich näher dafür interessierst, kann ich den Wikipediaartikel nur empfehlen. Fraktale im Allgemeinen sind wirklich interessant.

Ich habe mich heute mal an eine kleine Version in 3D gewagt und bin schon relativ zufrieden mit dem Ergebnis:
user posted image

Der Code: BlitzBasic: [AUSKLAPPEN]
Const GWIDTH = 800
Const GHEIGHT = 600

Graphics3D GWIDTH, GHEIGHT, 0, 2
SetBuffer BackBuffer()

Type TNode
Field X#
Field Y#
Field Z#

Field Diameter#

Field Pred.TNode

Field ProjX
Field ProjY
End Type

Type TVertex
Field X#
Field Y#
Field Z#

Field Index
End Type

Local Cam = CreateCamera()
TurnEntity Cam, 30, 0, 0
MoveEntity Cam, 0, 25, -35

Local CamPivot = CreatePivot()
EntityParent Cam, CamPivot
TurnEntity CamPivot, 0, 0, 0

Local Light = CreateLight( 2 )
PositionEntity Light, 0, 40, 0
LightRange Light, 10

Global Iterations = 7, TreeMesh, LeafMesh

;Erste Berechnung
ParseLSystem( 0, 0, 0, 1, 22.5, 0.5, LSystem( Iterations, "A", "A->[&FL!A]/////'[&FL!A]///////'[&FL!A],F->S/////F,S->FL,L->['''^^{-f+f+f-|-f+f+f}]" ) )

Local Timer = CreateTimer( 60 )

While Not KeyHit( 1 )
Evolution = KeyHit( 200 ) - KeyHit( 208 )

TurnEntity CamPivot, 0, KeyDown( 205 ) - KeyDown( 203 ), 0

If Evolution Then
Iterations = Iterations + Evolution

ParseLSystem( 0, 0, 0, 1, 22.5, 0.5, LSystem( Iterations, "A", "A->[&FL!A]/////'[&FL!A]///////'[&FL!A],F->S/////F,S->FL,L->['''^^{-f+f+f-|-f+f+f}]" ) )
EndIf

WireFrame MouseDown( 1 )

RenderWorld

Text 0, 0, "Generation " + Iterations

Flip 0
WaitTimer Timer
Wend
End

Function LSystem$( Generations, StartString$, Rules$ )
For i = 1 To Generations
Local ResultString$ = ""
For t = 1 To Len( StartString$ )
Offset = Instr( Rules$, Mid( StartString$, t, 1 ) + "->" )

If Offset Then
Offset2 = Instr( Rules$, ",", Offset )
If Not Offset2 Then Offset2 = Len( Rules$ ) + 1
ResultString$ = ResultString$ + Mid( Rules$, Offset + 3, Offset2 - Offset - 3 )
Else
ResultString$ = ResultString$ + Mid( StartString$, t, 1 )
EndIf
Next

StartString$ = ResultString$
Next

Return ResultString$
End Function

Function ParseLSystem( X#, Y#, Z#, StepSize#, Delta#, CurrDiameter#, InString$ )
Local SavePointer, Pitch#[ 100 ], Yaw#[ 100 ], Roll#[ 100 ], PositionX#[ 100 ], PositionY#[ 100 ], PositionZ#[ 100 ], Pred.TNode[ 100 ], Diameter#[ 100 ], Angle# = 90

If TreeMesh Then FreeEntity TreeMesh
If LeafMesh Then FreeEntity LeafMesh

TreeMesh = CreateMesh()
EntityFX TreeMesh, 2

LeafMesh = CreateMesh()
EntityFX LeafMesh, 2 + 16

TreeSurf = CreateSurface( TreeMesh )
LeafSurf = CreateSurface( LeafMesh )

TurtlePivot = CreatePivot()
PositionEntity TurtlePivot, X#, Y#, Z#
AlignToVector TurtlePivot, 0, 1, 0, 3

Delete Each TNode

Node.TNode = New TNode
Node\X# = X#
Node\Y# = Y#
Node\Z# = Z#

For i = 1 To Len( InString$ )
Select Mid( InString$, i, 1 )
Case "F"
MoveEntity TurtlePivot, 0, 0, StepSize#

NewNode.TNode = New TNode
NewNode\X# = EntityX( TurtlePivot, True )
NewNode\Y# = EntityY( TurtlePivot, True )
NewNode\Z# = EntityZ( TurtlePivot, True )
NewNode\Pred = Node.TNode
NewNode\Diameter# = CurrDiameter#

Node = NewNode
Case "+"
TurnEntity TurtlePivot, 0, Delta#, 0
Case "-"
TurnEntity TurtlePivot, 0, -Delta#, 0
Case "\"
TurnEntity TurtlePivot, 0, 0, Delta#
Case "/"
TurnEntity TurtlePivot, 0, 0, -Delta#
Case "&"
TurnEntity TurtlePivot, Delta#, 0, 0
Case "^"
TurnEntity TurtlePivot, -Delta#, 0, 0
Case "|"
TurnEntity TurtlePivot, 0, 180, 0
Case "["
Pitch[ SavePointer ] = EntityPitch( TurtlePivot, True )
Yaw[ SavePointer ] = EntityYaw( TurtlePivot, True )
Roll[ SavePointer ] = EntityRoll( TurtlePivot, True )
PositionX[ SavePointer ] = EntityX( TurtlePivot, True )
PositionY[ SavePointer ] = EntityY( TurtlePivot, True )
PositionZ[ SavePointer ] = EntityZ( TurtlePivot, True )
Diameter[ SavePointer ] = CurrDiameter#
Pred[ SavePointer ] = Node
SavePointer = SavePointer + 1
Case "]"
SavePointer = SavePointer - 1
PositionEntity TurtlePivot, PositionX[ SavePointer ], PositionY[ SavePointer ], PositionZ[ SavePointer ], True
RotateEntity TurtlePivot, Pitch[ SavePointer ], Yaw[ SavePointer ], Roll[ SavePointer ], True
Node = Pred[ SavePointer ]
CurrDiameter# = Diameter[ SavePointer ]
Case "{"
Delete Each TVertex

Vertex.TVertex = New TVertex
Vertex\X# = EntityX( TurtlePivot, True )
Vertex\Y# = EntityY( TurtlePivot, True )
Vertex\Z# = EntityZ( TurtlePivot, True )
Case "f"
MoveEntity TurtlePivot, 0, 0, StepSize#

Vertex.TVertex = New TVertex
Vertex\X# = EntityX( TurtlePivot, True )
Vertex\Y# = EntityY( TurtlePivot, True )
Vertex\Z# = EntityZ( TurtlePivot, True )
Case "}"
For Vertex.TVertex = Each TVertex
Vertex\Index = AddVertex( LeafSurf, Vertex\X#, Vertex\Y#, Vertex\Z# )

VertexColor LeafSurf, Vertex\Index, 0, Rand( 100, 255 ), 0
Next

For Vertex.TVertex = Each TVertex
If Vertex <> First TVertex And Vertex <> After First TVertex Then
Pred1.TVertex = Before Vertex
Pred2.TVertex = First TVertex

AddTriangle LeafSurf, Vertex\Index, Pred1\Index, Pred2\Index
EndIf
Next
Case "!"
CurrDiameter# = CurrDiameter#*0.6
End Select
Next

For Node.TNode = Each TNode
If Node\Pred <> Null Then
V1 = AddVertex( TreeSurf, Node\X# - Node\Diameter#/2, Node\Y#, Node\Z# + Node\Diameter#/2 )
V2 = AddVertex( TreeSurf, Node\X# + Node\Diameter#/2, Node\Y#, Node\Z# + Node\Diameter#/2 )
V3 = AddVertex( TreeSurf, Node\X# + Node\Diameter#/2, Node\Y#, Node\Z# - Node\Diameter#/2 )
V4 = AddVertex( TreeSurf, Node\X# - Node\Diameter#/2, Node\Y#, Node\Z# - Node\Diameter#/2 )

V5 = AddVertex( TreeSurf, Node\Pred\X# - Node\Pred\Diameter#/2, Node\Pred\Y#, Node\Pred\Z# + Node\Pred\Diameter#/2 )
V6 = AddVertex( TreeSurf, Node\Pred\X# + Node\Pred\Diameter#/2, Node\Pred\Y#, Node\Pred\Z# + Node\Pred\Diameter#/2 )
V7 = AddVertex( TreeSurf, Node\Pred\X# + Node\Pred\Diameter#/2, Node\Pred\Y#, Node\Pred\Z# - Node\Pred\Diameter#/2 )
V8 = AddVertex( TreeSurf, Node\Pred\X# - Node\Pred\Diameter#/2, Node\Pred\Y#, Node\Pred\Z# - Node\Pred\Diameter#/2 )

VertexColor TreeSurf, V1, Rand( 50, 110 ), Rand( 50, 70 ), Rand( 25, 45 )
VertexColor TreeSurf, V2, Rand( 50, 110 ), Rand( 50, 70 ), Rand( 25, 45 )
VertexColor TreeSurf, V3, Rand( 50, 110 ), Rand( 50, 70 ), Rand( 25, 45 )
VertexColor TreeSurf, V4, Rand( 50, 110 ), Rand( 50, 70 ), Rand( 25, 45 )
VertexColor TreeSurf, V5, Rand( 50, 110 ), Rand( 50, 70 ), Rand( 25, 45 )
VertexColor TreeSurf, V6, Rand( 50, 110 ), Rand( 50, 70 ), Rand( 25, 45 )
VertexColor TreeSurf, V7, Rand( 50, 110 ), Rand( 50, 70 ), Rand( 25, 45 )
VertexColor TreeSurf, V8, Rand( 50, 110 ), Rand( 50, 70 ), Rand( 25, 45 )

AddTriangle TreeSurf, V4, V3, V8
AddTriangle TreeSurf, V8, V3, V7

AddTriangle TreeSurf, V3, V2, V7
AddTriangle TreeSurf, V7, V2, V6

AddTriangle TreeSurf, V2, V5, V6
AddTriangle TreeSurf, V2, V1, V5

AddTriangle TreeSurf, V1, V8, V5
AddTriangle TreeSurf, V1, V4, V8
EndIf
Next

UpdateNormals TreeMesh
UpdateNormals LeafMesh

FreeEntity TurtlePivot
End Function

Mit Pfeiltasten links/rechts dreht man die Kamera und mit hoch/runter steuert man die Generation (Achtung: Eine Generation > 7 führt zum MAV bei RenderWorld).

Der erstellte Strauch ist sowas von High-poly, das könnte so nie in einem Spiel eingesetzt werden Razz Aber das war auch nicht mein vorrangiges Ziel, sondern eher, ein möglichst gutaussehendes Resultat zu erzeugen. Dafür benötigt es aber noch sehr viel Feinschliff wie z.B. eine anständige Textur.

Als nächstes werde ich mich an Blumen und Bäumen versuchen, um auch mal komplexere Strukturen zu Gesicht zu bekommen; verschiedene Blätterformen sind ebenfalls interessant.
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
 

KaDuZa

BeitragDi, Apr 28, 2009 23:09
Antworten mit Zitat
Benutzer-Profile anzeigen
großes lob meiner seits,
ich finde es gut das sowas nicht immer nur verschärbelt wird sondern wie früher, wo noch alles frei war,
open source gestellt wird... Wink
@noobody, darf ich fragen wie lange du schon programmierst?, eventuel auch noch in anderen sprachen?

MikeDee

BeitragMi, Apr 29, 2009 9:51
Antworten mit Zitat
Benutzer-Profile anzeigen
Respekt, bei dir sehen die Codes auch immer so verständlich aus. Ich glaub, wenn ich mal programmieren kann, dann versuch ich daraus ein "Wie-wächst-ein-Baum-Simulator" zu machen. Bin eh zurzeit auf dem Simulatortrip, zurzeit geistert in meinem Hinterkopf ein Wettersimulator rum^^. Die Fertigstellung wird aber warscheinlich erst, sagen wir, 2015 sein...oder später Smile
Nicht wenige benutzen die Anonymität des Internets um berühmt zu werden.

Chrise

BeitragMi, Apr 29, 2009 17:23
Antworten mit Zitat
Benutzer-Profile anzeigen
sehr schönes Ergebnis!
Wieviele Vertices braucht jetzt ein so ein Baum auf 7. Generation?
Llama 1 Llama 2 Llama 3
Vielen Dank an Pummelie, der mir auf seinem Server einen Platz für LlamaNet bietet.

Noobody

BeitragMi, Apr 29, 2009 20:37
Antworten mit Zitat
Benutzer-Profile anzeigen
KaDuZa hat Folgendes geschrieben:
@noobody, darf ich fragen wie lange du schon programmierst?, eventuel auch noch in anderen sprachen?

In Blitz Basic so zweieinhalb Jahre, vorher habe ich noch ein wenig mit Visual Basic Kontakt gehabt, aber nicht wirklich ernsthaft. Im letzten halben Jahr habe ich dann vermehrt in C programmiert, aber Blitz Basic ist nach wie vor mein Favorit Razz

Chrise hat Folgendes geschrieben:
Wieviele Vertices braucht jetzt ein so ein Baum auf 7. Generation?

Horrend viele *kicher*
Genau weiss ich das nicht, aber damit der Strauch für ein Spiel verwendbar würde, müsste man das Mesh noch stark optimieren.
Der Strauch war aber auch nicht viel mehr als ein kleiner Test.


Heute habe ich mal eine kleine Blume gemacht. Sie wurde leider nicht ganz so schön wie beabsichtigt, aber immerhin hat es mir geholfen, L - Systeme in 3D ein wenig besser zu verstehen.
Das Mesh ist schon ein wenig optimierter als der Strauch von vorhin, allerdings noch längst nicht gut genug Razz
Für Bäume müsste ich mir dann noch was überlegen.

Bild:
user posted image

Der Code: BlitzBasic: [AUSKLAPPEN]
Const GWIDTH = 800
Const GHEIGHT = 600

Graphics3D GWIDTH, GHEIGHT, 0, 2
SetBuffer BackBuffer()

Type TNode
Field X#
Field Y#
Field Z#

Field Diameter#

Field Pred.TNode

Field V1
Field V2
Field V3
Field V4
End Type

Type TVertex
Field X#
Field Y#
Field Z#

Field Index
End Type

Local Cam = CreateCamera()
TurnEntity Cam, 30, 0, 0
MoveEntity Cam, -5, 25, -35

Local CamPivot = CreatePivot()
EntityParent Cam, CamPivot
MoveEntity CamPivot, 0, 0, -3

Local Light = CreateLight( 2 )
PositionEntity Light, 0, 40, 0
LightRange Light, 10

Global Iterations = 5, TreeMesh, LeafMesh

Local Timer = CreateTimer( 60 )

;Spross -> 1
;Internodium -> 2
;Blüte -> 3
;Blatt -> 4
;Segment -> 5
;Blütenstiel -> 6
;Pollenfäden -> 7

Rules$ = "1->2+[1+3]--//[--4]2[++4]-[13]++13,2->F5[//&&4][//^^4]F5,5->5F5,4->[*{+f-ff-f+|+f-ff-f}],3->[&&&6'/7////7////7////7////7],6->FF,7->['^!!!!!!F][{&&&&-f+f|-f+f}]"

ParseLSystem( 0, 0, 0, 0.5, 18, 0.08, LSystem( Iterations, "1", Rules$ ) )

While Not KeyHit( 1 )
Evolution = KeyHit( 200 ) - KeyHit( 208 )

TurnEntity CamPivot, 0, KeyDown( 205 ) - KeyDown( 203 ), 0

If Evolution Then
Iterations = Iterations + Evolution

ParseLSystem( 0, 0, 0, 0.5, 18, 0.08, LSystem( Iterations, "1", Rules$ ) )
EndIf

WireFrame MouseDown( 1 )

RenderWorld

Text 0, 0, "Generation " + Iterations

Flip 0
WaitTimer Timer
Wend
End

Function LSystem$( Generations, StartString$, Rules$ )
For i = 1 To Generations
Local ResultString$ = ""
For t = 1 To Len( StartString$ )
Offset = Instr( Rules$, Mid( StartString$, t, 1 ) + "->" )

If Offset Then
Offset2 = Instr( Rules$, ",", Offset )
If Not Offset2 Then Offset2 = Len( Rules$ ) + 1
ResultString$ = ResultString$ + Mid( Rules$, Offset + 3, Offset2 - Offset - 3 )
Else
ResultString$ = ResultString$ + Mid( StartString$, t, 1 )
EndIf
Next

StartString$ = ResultString$
Next

Return ResultString$
End Function

Function ParseLSystem( X#, Y#, Z#, StepSize#, Delta#, CurrDiameter#, InString$ )
Local SavePointer, Pitch#[ 100 ], Yaw#[ 100 ], Roll#[ 100 ], PositionX#[ 100 ], PositionY#[ 100 ], PositionZ#[ 100 ], Pred.TNode[ 100 ], Diameter#[ 100 ], Angle# = 90
Local R = 0, G = 255, B = 0

If TreeMesh Then FreeEntity TreeMesh
If LeafMesh Then FreeEntity LeafMesh

TreeMesh = CreateMesh()
EntityFX TreeMesh, 2

LeafMesh = CreateMesh()
EntityFX LeafMesh, 2 + 16

TreeSurf = CreateSurface( TreeMesh )
LeafSurf = CreateSurface( LeafMesh )

TurtlePivot = CreatePivot()
PositionEntity TurtlePivot, X#, Y#, Z#
AlignToVector TurtlePivot, 0, 1, 0, 3

Delete Each TNode

Node.TNode = New TNode
Node\X# = X#
Node\Y# = Y#
Node\Z# = Z#
Node\Diameter# = CurrDiameter#
Node\V1 = AddVertex( TreeSurf, Node\X# - Node\Diameter#/2, Node\Y#, Node\Z# + Node\Diameter#/2 )
Node\V2 = AddVertex( TreeSurf, Node\X# + Node\Diameter#/2, Node\Y#, Node\Z# + Node\Diameter#/2 )
Node\V3 = AddVertex( TreeSurf, Node\X# + Node\Diameter#/2, Node\Y#, Node\Z# - Node\Diameter#/2 )
Node\V4 = AddVertex( TreeSurf, Node\X# - Node\Diameter#/2, Node\Y#, Node\Z# - Node\Diameter#/2 )

For i = 1 To Len( InString$ )
Select Mid( InString$, i, 1 )
Case "F"
MoveEntity TurtlePivot, 0, 0, StepSize#

NewNode.TNode = New TNode
NewNode\X# = EntityX( TurtlePivot, True )
NewNode\Y# = EntityY( TurtlePivot, True )
NewNode\Z# = EntityZ( TurtlePivot, True )
NewNode\Pred = Node.TNode
NewNode\Diameter# = CurrDiameter#
NewNode\V1 = AddVertex( TreeSurf, NewNode\X# - NewNode\Diameter#/2, NewNode\Y#, NewNode\Z# + NewNode\Diameter#/2 )
NewNode\V2 = AddVertex( TreeSurf, NewNode\X# + NewNode\Diameter#/2, NewNode\Y#, NewNode\Z# + NewNode\Diameter#/2 )
NewNode\V3 = AddVertex( TreeSurf, NewNode\X# + NewNode\Diameter#/2, NewNode\Y#, NewNode\Z# - NewNode\Diameter#/2 )
NewNode\V4 = AddVertex( TreeSurf, NewNode\X# - NewNode\Diameter#/2, NewNode\Y#, NewNode\Z# - NewNode\Diameter#/2 )

VertexColor TreeSurf, NewNode\V1, R, G, B
VertexColor TreeSurf, NewNode\V2, R, G, B
VertexColor TreeSurf, NewNode\V3, R, G, B
VertexColor TreeSurf, NewNode\V4, R, G, B

AddTriangle TreeSurf, NewNode\V4, NewNode\V3, Node\V4
AddTriangle TreeSurf, Node\V4, NewNode\V3, Node\V3

AddTriangle TreeSurf, NewNode\V3, NewNode\V2, Node\V3
AddTriangle TreeSurf, Node\V3, NewNode\V2, Node\V2

AddTriangle TreeSurf, NewNode\V2, Node\V1, Node\V2
AddTriangle TreeSurf, NewNode\V2, NewNode\V1, Node\V1

AddTriangle TreeSurf, NewNode\V1, Node\V4, Node\V1
AddTriangle TreeSurf, NewNode\V1, NewNode\V4, Node\V4

Node = NewNode
Case "*"
R = 0
G = 255
B = 0
Case "'"
R = 255
G = 255
B = 255
Case "+"
TurnEntity TurtlePivot, 0, Delta#, 0
Case "-"
TurnEntity TurtlePivot, 0, -Delta#, 0
Case "\"
TurnEntity TurtlePivot, 0, 0, Delta#
Case "/"
TurnEntity TurtlePivot, 0, 0, -Delta#
Case "&"
TurnEntity TurtlePivot, Delta#, 0, 0
Case "^"
TurnEntity TurtlePivot, -Delta#, 0, 0
Case "|"
TurnEntity TurtlePivot, 0, 180, 0
Case "["
Pitch[ SavePointer ] = EntityPitch( TurtlePivot, True )
Yaw[ SavePointer ] = EntityYaw( TurtlePivot, True )
Roll[ SavePointer ] = EntityRoll( TurtlePivot, True )
PositionX[ SavePointer ] = EntityX( TurtlePivot, True )
PositionY[ SavePointer ] = EntityY( TurtlePivot, True )
PositionZ[ SavePointer ] = EntityZ( TurtlePivot, True )
Diameter[ SavePointer ] = CurrDiameter#
Pred[ SavePointer ] = Node
SavePointer = SavePointer + 1
Case "]"
SavePointer = SavePointer - 1
PositionEntity TurtlePivot, PositionX[ SavePointer ], PositionY[ SavePointer ], PositionZ[ SavePointer ], True
RotateEntity TurtlePivot, Pitch[ SavePointer ], Yaw[ SavePointer ], Roll[ SavePointer ], True
Node = Pred[ SavePointer ]
CurrDiameter# = Diameter[ SavePointer ]
Case "{"
Delete Each TVertex

Vertex.TVertex = New TVertex
Vertex\X# = EntityX( TurtlePivot, True )
Vertex\Y# = EntityY( TurtlePivot, True )
Vertex\Z# = EntityZ( TurtlePivot, True )
Case "f"
MoveEntity TurtlePivot, 0, 0, StepSize#

Vertex.TVertex = New TVertex
Vertex\X# = EntityX( TurtlePivot, True )
Vertex\Y# = EntityY( TurtlePivot, True )
Vertex\Z# = EntityZ( TurtlePivot, True )
Case "}"
For Vertex.TVertex = Each TVertex
Vertex\Index = AddVertex( LeafSurf, Vertex\X#, Vertex\Y#, Vertex\Z# )

VertexColor LeafSurf, Vertex\Index, RandomColor( R ), RandomColor( G ), RandomColor( B )
Next

For Vertex.TVertex = Each TVertex
If Vertex <> First TVertex And Vertex <> After First TVertex Then
Pred1.TVertex = Before Vertex
Pred2.TVertex = First TVertex

AddTriangle LeafSurf, Vertex\Index, Pred1\Index, Pred2\Index
EndIf
Next
Case "!"
CurrDiameter# = CurrDiameter#*0.6
End Select
Next

UpdateNormals TreeMesh
UpdateNormals LeafMesh

FreeEntity TurtlePivot
End Function

Function RandomColor( Char )
Char = Char + Rand( -60, 60 )

If Char < 0 Then Char = 0 ElseIf Char > 255 Then Char = 255

Return Char
End Function


Bedienung wie gehabt.
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

CypressArt

BeitragDo, Apr 30, 2009 13:10
Antworten mit Zitat
Benutzer-Profile anzeigen
sieht ja stark aus!! *kompliment*

jetzt fehlt nur noch eine Routine um die Pflanzen in B3D zu "importieren".. Wink
Oder als Add-On ?

bin gespannt wie es weiter geht..
(no comment) -> Google Search Bot!!

count-doku

BeitragDo, Apr 30, 2009 13:41
Antworten mit Zitat
Benutzer-Profile anzeigen
Sowas tolles hab ich noch nicht gesehen Exclamation

Wie wärs mit ner .DLL? Wink

Mfg,
Count-Doku

Neue Antwort erstellen


Übersicht BlitzBasic Codearchiv

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group