Scripts/lsystem-plant.ps1
# Unique Concept: L-system fractal tree with branching rules and angle variations. # Uses string rewriting to generate plant-like structures with recursive growth patterns. $ErrorActionPreference = 'Stop' $esc = [char]27 $reset = "$esc[0m" function Convert-HsvToRgb { param([double]$Hue, [double]$Saturation, [double]$Value) $h = ($Hue % 1) * 6 $sector = [math]::Floor($h) $fraction = $h - $sector $p = $Value * (1 - $Saturation) $q = $Value * (1 - $fraction * $Saturation) $t = $Value * (1 - (1 - $fraction) * $Saturation) switch ($sector) { 0 { $r = $Value; $g = $t; $b = $p } 1 { $r = $q; $g = $Value; $b = $p } 2 { $r = $p; $g = $Value; $b = $t } 3 { $r = $p; $g = $q; $b = $Value } 4 { $r = $t; $g = $p; $b = $Value } default { $r = $Value; $g = $p; $b = $q } } return @([int][math]::Round($r * 255), [int][math]::Round($g * 255), [int][math]::Round($b * 255)) } # L-system: Axiom: F, Rules: F -> FF+[+F-F-F]-[-F+F+F] $axiom = "F" $rules = @{ 'F' = 'FF+[+F-F]-[-F+F]' } # Apply L-system rules $current = $axiom for ($i = 0; $i -lt 4; $i++) { $next = "" foreach ($char in $current.ToCharArray()) { if ($rules.ContainsKey([string]$char)) { $next += $rules[[string]$char] } else { $next += $char } } $current = $next } # Interpret L-system to draw $width = 100 $height = 26 $grid = @{} $x = 50.0 $y = 25.0 $angle = -90.0 # Start pointing up $angleIncrement = 25.0 $stepSize = 0.8 $stack = New-Object 'System.Collections.Generic.Stack[object]' $depth = 0 foreach ($char in $current.ToCharArray()) { switch ($char) { 'F' { # Draw forward $rad = $angle * [math]::PI / 180.0 $newX = $x + $stepSize * [math]::Cos($rad) $newY = $y + $stepSize * [math]::Sin($rad) # Interpolate line $steps = 3 for ($s = 0; $s -le $steps; $s++) { $t = $s / [double]$steps $px = [int]($x + ($newX - $x) * $t) $py = [int]($y + ($newY - $y) * $t) if ($px -ge 0 -and $px -lt $width -and $py -ge 0 -and $py -lt $height) { $key = "$px,$py" if (-not $grid.ContainsKey($key) -or $grid[$key].Depth -lt $depth) { $grid[$key] = @{ Depth = $depth; Order = $grid.Count } } } } $x = $newX $y = $newY } '+' { $angle += $angleIncrement } '-' { $angle -= $angleIncrement } '[' { $stack.Push(@{ X = $x; Y = $y; Angle = $angle; Depth = $depth }) $depth++ } ']' { if ($stack.Count -gt 0) { $state = $stack.Pop() $x = $state.X $y = $state.Y $angle = $state.Angle $depth = $state.Depth } } } } # Render $maxDepth = ($grid.Values | Measure-Object -Property Depth -Maximum).Maximum if ($null -eq $maxDepth) { $maxDepth = 1 } for ($row = $height - 1; $row -ge 0; $row--) { $sb = [System.Text.StringBuilder]::new() for ($col = 0; $col -lt $width; $col++) { $key = "$col,$row" if ($grid.ContainsKey($key)) { $cell = $grid[$key] $depthRatio = $cell.Depth / [double]$maxDepth $hue = (0.25 + $depthRatio * 0.35) % 1 $saturation = 0.7 - 0.3 * $depthRatio $value = 0.9 - 0.4 * $depthRatio $rgb = Convert-HsvToRgb -Hue $hue -Saturation $saturation -Value $value $symbol = if ($depthRatio -lt 0.3) { '█' } elseif ($depthRatio -lt 0.6) { '▓' } else { '░' } $null = $sb.Append("$esc[38;2;$($rgb[0]);$($rgb[1]);$($rgb[2])m$symbol") } else { $null = $sb.Append("$esc[38;2;8;8;12m ") } } Write-Host ($sb.ToString() + $reset) } Write-Host $reset |