L-system

Oletko tehnyt jotain, mistä muut voisivat hyötyä. Postita vinkit tänne.
Post Reply
User avatar
Sami345
Advanced Member
Posts: 349
Joined: Fri Aug 31, 2007 4:52 pm
Contact:

L-system

Post by Sami345 » Thu Jan 27, 2011 10:01 pm

Koodasin tässä illalla aikani kuluksi tällaisen L-system -tulkin CoolBasicille. Tätä voidaan siis käyttää luonnollisten näköisten kasvien ja fraktaalien piirtoon. Laittamalla satunnaisuusarvoa saadaan uniikin näköisiä kuvia.

Esimerkkejä löytyy täältä: http://inkscape.org/screenshots/gallery ... nmayer.png

Kuvankaappaus esimerkkistä:
lsystem.png
lsystem.png (74.81 KiB) Viewed 2056 times
Koodi:

Code: Select all

//Esimerkki
SCREEN 800, 800

LSystem(400, 800, "++F", "F=FF-[-F+F+F]+[+F-F-F]", 3, 25.0, 16.0, 16.0, 0.05, 0.05)
LSystem(335, 250, "A++A++A", "A=A-A++A-A", 3, 8.0, 60.0, 60.0)
LSystem(400, 800, "--F", "F=FF+[+F-F-F]-[-F+F+F]", 3, 25.0, 16.0, 16.0, 0.05, 0.05)

Repeat
    DrawScreen OFF
    Wait 1000
Forever




//Kirjasto
Type LSystem_Savepoints
    Field x As Float
    Field y As Float
    Field r As Float
EndType

Type LSystem_Rules
    Field needle As String
    Field change As String
EndType

//x = aloituspaikka x-akselilla
//y = aloituspaikka y-akselilla
//rules = säännöt joiden mukaan generoidaan
//iteration = kuinka monta kertaa suoritetaan
//move = kuinka paljon yksi siirto siirtää
//turnleft = kuinka paljon käännös vasemmalle kääntää asteissa
//turnright = kuinka paljon käännös oikealle kääntää asteissa
//randmove = kuinka paljon siirtoa arvotaan, oletus 0
//randturn = kuinka paljon käännöstä arvotaan, oletus 0
//rotation = aloituskulma, oletus -90 (ylös)
Function LSystem(x, y, status$, rules$, iteration, move#, turnleft#, turnright#, randmove# = 0, randturn# = 0, rotation# = -90)
    If iteration = 0 Then
        For i = 1 To Len(status)
            char$ = Mid(status, i, 1)
            If Asc(char) >= 65 And Asc(char) <= 76 Then
                oldx# = x
                oldy# = y
                
                move2# = move + move * Rnd(-randmove, randmove)
                
                x = x + Cos(rotation) * move2
                y = y + Sin(rotation) * move2
                
                If Asc(char) <= 70 Then Line oldx, oldy, x, y
            ElseIf char = "+" Then
                turn2 = turnleft + turnleft * Rnd(-randturn, randturn)
            
                rotation + turn2
            ElseIf char = "-" Then
                turn2 = turnright + turnright * Rnd(-randturn, randturn)
            
                rotation - turn2
            ElseIf char = "|" Then
                rotation + 180
            ElseIf char = "[" Then
                savepoint.LSystem_Savepoints = New(LSystem_Savepoints)
                
                savepoint\x = x
                savepoint\y = y
                savepoint\r = rotation
            ElseIf char = "]" Then
                savepoint.LSystem_Savepoints = Last(LSystem_Savepoints)
            
                x = savepoint\x
                y = savepoint\y
                rotation = savepoint\r
                
                Delete savepoint
            EndIf

        Next i
        
        For savepoint.LSystem_Savepoints = Each LSystem_Savepoints
            Delete savepoint
        Next savepoint
        
        For rule.LSystem_Rules = Each LSystem_Rules
            Delete rule
        Next rule
    Else
        If Last(LSystem_Rules) = NULL Then
            For i = 1 To CountWords(rules, ";")
                rulestr$ = GetWord(rules, i, ";")
                
                rule.LSystem_Rules = New(LSystem_Rules)
                
                location = InStr(rulestr, "=")
                If location <= 1 Then MakeError "Invalid formated L-System rule!"
                
                rule\needle = Trim(Mid(rulestr, 1, location - 1))
                rule\change = Mid(rulestr, location + 1)
                
            Next i
        EndIf
        
        oldstatus$ = status
        status = ""
        
        For i = 1 To Len(oldstatus)
            char$ = Mid(oldstatus, i, 1)

            found = 0
            
            For rule.LSystem_Rules = Each LSystem_Rules
                If char = rule\needle Then
                    status = status + rule\change
                    found = 1
                    
                    Exit
                EndIf
            Next rule
            
            If found = 0 Then
                status = status + char
            EndIf
            
        Next i
        
        LSystem(x, y, status, rules, iteration - 1, move, turnleft, turnright, randmove, randturn, rotation)
    EndIf
EndFunction
Projektit: Fiperus - Jäädytetty pidemmäksi aikaa.
Voitot: Viikkokisa XIII, Pikapelikisa 3, Pikapelikisa 13
http://www.sami345.tk/

User avatar
esa94
Guru
Posts: 1855
Joined: Tue Sep 04, 2007 5:35 pm

Re: L-system

Post by esa94 » Thu Jan 27, 2011 11:29 pm

Sami345 wrote: <fraktaali>
Eikös tuo ole vain parsafraktaali jota on vähän tiivistetty ja lisätty satunnaisuutta?

User avatar
Koodiapina
Forum Veteran
Posts: 2396
Joined: Tue Aug 28, 2007 4:20 pm
Contact:

Re: L-system

Post by Koodiapina » Thu Jan 27, 2011 11:38 pm

Tämä tuo mieleeni hieman oman LOGOa muistuttavan kieleni, jossa oli Brainfuckin syntaksi. Silläkin tehtiin fraktaaleita/muita kuvioita.
Olen liian älykäs ollakseni väärässä. Jos olet kanssani eri mieltä, suosittelen sinua pohtimaan omaa elämänkatsomustasi ja sen perusteita.

Post Reply