Types/Turtle/Spirolateral.ps1
|
<# .SYNOPSIS Draws a spirolateral .DESCRIPTION Draws a spirolateral .LINK https://en.wikipedia.org/wiki/Spirolateral .EXAMPLE turtle spirolateral save ./Spirolateral.svg .EXAMPLE turtle spirolateral 50 144 8 save ./Spirolateral-144-8.svg .EXAMPLE turtle spirolateral 50 60 10 save ./Spirolateral-60-10.svg .EXAMPLE turtle spirolateral 50 120 6 @(1,3) save ./Spirolateral-120-6-1_3.svg .EXAMPLE turtle spirolateral 50 90 11 @(3,4,5) save ./Spirolateral-90-11-3_4_5.svg .EXAMPLE turtle @('spirolateral',50,60,6,@(1,3),'rotate', 60 * 6 ) save ./Spirolateral-x6.svg #> param( # The base length of each side (this will be multiplied by the step number) [double] $Side = $( (Get-Random -Min 42.0 -Maximum 84.0) * (1,-1 | Get-Random) ), # The angle of the turn [double] $Angle = $( (Get-Random -Min 10.0 -Maximum 120.0) * (1,-1 | Get-Random) ), # The step count. # This is the number of times the steps will be repeated. [int] $StepCount = 0, # The step numbers that are left turns (counter-clockwise). # This allows the creation of general spirolaterals [Parameter(ValueFromRemainingArguments)] [int[]] $LeftTurnSteps ) if ($Angle -eq 0) { return $this } # If no step count was provided if ($StepCount -eq 0) { # pick a random number of rotations $revolutions = (Get-Random -Minimum 1 -Max 16) # and figure out how many steps at our angle it takes to get there. foreach ($n in 2..$revolutions) { $revNumber = ($revolutions * 360)/$Angle $StepCount = [Math]::Ceiling($revNumber) if ([Math]::Floor($revNumber) -eq $revNumber) { break } } } $stepNumber = 1 # Figure out our total turn per loop $totalTurn = 0.0 for ($stepNumber = 1; $stepNumber -le [Math]::Abs($StepCount); $stepNumber++) { if ($LeftTurnSteps -contains $stepNumber) { $totalTurn -= $angle } else { $totalTurn += $angle } } $rotations = 0 foreach ($n in 1..32) { $rotations = ($n * 360)/$totalTurn if ([Math]::Floor($rotations) -eq $rotations) { break } } $rotations = [Math]::Ceiling($rotations) foreach ($rotation in 1..$rotations) { $null = for ($stepNumber = 1; $stepNumber -le [Math]::Abs($StepCount); $stepNumber++) { $null = $this.Forward($side * $stepNumber) if ($LeftTurnSteps) { if ($LeftTurnSteps -contains $stepNumber) { $totalTurn -= $angle $this.Left($angle) } else { $totalTurn += $angle $this.Right($angle) } } else { $totalTurn += $angle $this.Right($angle) } } } <#} until ( (-not ([Math]::Round($totalTurn, 1) % 360 )) -and $majorStepCount -le [Math]::Abs($StepCount) )#> return $this |