Types/Turtle/get_History.ps1
| 
                                <# .SYNOPSIS Gets a Turtle's history .DESCRIPTION Gets an annotated history of a turtle's movements. This is an SVG path translated into back into human readable text and coordinates. #> $currentPosition = [Numerics.Vector2]::new(0,0) $historyList = [Collections.Generic.List[PSObject]]::new() $startStack = [Collections.Stack]::new() foreach ($pathStep in $this.PathData -join ' ' -split '(?=[\p{L}-[E]])' -ne '') { $letter = $pathStep[0] $isUpper = "$letter".ToLower() -cne $letter $isLower = -not $isUpper $toBy = if ($isUpper) { 'to'} else { 'by'} $stepPoints = $pathStep -replace $letter -replace ',', ' ' -split '\s{1,}' -ne '' -as [float[]] $historyEntry = switch ($letter) { a { for ($stepIndex = 0; $stepIndex -lt $stepPoints.Length; $stepIndex+=7) { $sequence = $stepPoints[$stepIndex..($stepIndex + 6)] $comment = "arc $toBy $sequence" $delta = [Numerics.Vector2]::new.Invoke($sequence[-2,-1]) if ($isUpper) { $delta -= $currentPosition } [PSCustomObject]@{ PSTypeName='Turtle.History' Letter = "$letter" Start = $currentPosition End = $currentPosition + $delta Delta = $delta Instruction = "$Letter $sequence" Comment = $comment } $currentPosition += $delta } } c { for ($stepIndex = 0; $stepIndex -lt $stepPoints.Length; $stepIndex+=6) { $sequence = $stepPoints[$stepIndex..($stepIndex + 5)] $comment = "cubic curve $toBy $sequence" $delta = [Numerics.Vector2]::new.Invoke($sequence[-2,-1]) if ($isUpper) { $delta -= $currentPosition } [PSCustomObject]@{ PSTypeName='Turtle.History' Letter = "$letter" Start = $currentPosition End = $currentPosition + $delta Delta = $delta Instruction = "$Letter $sequence" Comment = $comment } $currentPosition += $delta } } l { # line segment for ($stepIndex = 0; $stepIndex -lt $stepPoints.Length; $stepIndex+=2) { $sequence = $stepPoints[$stepIndex..($stepIndex + 1)] $comment = "line $toBy $sequence" $delta = [Numerics.Vector2]::new.Invoke($sequence[-2,-1]) if ($isUpper) { $delta -= $currentPosition } [PSCustomObject]@{ PSTypeName='Turtle.History' Letter = "$letter" Start = $currentPosition End = $currentPosition + $delta Delta = $delta Instruction = "$Letter $sequence" Comment = $comment } $currentPosition += $delta } } m { # movement for ($stepIndex = 0; $stepIndex -lt $stepPoints.Length; $stepIndex+=2) { $sequence = $stepPoints[$stepIndex..($stepIndex + 1)] $comment = "line $toBy $sequence" $delta = [Numerics.Vector2]::new.Invoke($sequence[-2,-1]) if ($isUpper) { $delta -= $currentPosition } if ($stepIndex -gt 0) { if ($letter -eq 'm') { if ($isUpper) { $letter = 'L' } else { $letter = 'l'} } $comment = "line $toBy $sequence" } else { $comment = "move $toBy $sequence" $startStack.Push($currentPosition + $delta) } [PSCustomObject]@{ PSTypeName='Turtle.History' Letter = "$letter" Start = $currentPosition End = $currentPosition + $delta Delta = $delta Instruction = "$Letter $sequence" Comment = $comment } $currentPosition += $delta } } s { # simple bezier curve for ($stepIndex = 0; $stepIndex -lt $stepPoints.Length; $stepIndex+=4) { $sequence = $stepPoints[$stepIndex..($stepIndex + 3)] $comment = "simple bezier curve $toBy $sequence" $delta = [Numerics.Vector2]::new.Invoke($sequence[-2,-1]) if ($isUpper) { $delta -= $currentPosition } [PSCustomObject]@{ PSTypeName='Turtle.History' Letter = "$letter" Start = $currentPosition End = $currentPosition + $delta Delta = $delta Instruction = "$Letter $sequence" Comment = $comment } $currentPosition += $delta } } t { # continue simple bezier curve for ($stepIndex = 0; $stepIndex -lt $stepPoints.Length; $stepIndex+=2) { $sequence = $stepPoints[$stepIndex..($stepIndex + 1)] $comment = "continue bezier curve $toBy $sequence" $delta = [Numerics.Vector2]::new.Invoke($sequence[-2,-1]) if ($isUpper) { $delta -= $currentPosition } [PSCustomObject]@{ PSTypeName='Turtle.History' Letter = "$letter" Start = $currentPosition End = $currentPosition + $delta Delta = $delta Instruction = "$Letter $sequence" Comment = $comment } $currentPosition += $delta } } q { for ($stepIndex = 0; $stepIndex -lt $stepPoints.Length; $stepIndex+=4) { $sequence = $stepPoints[$stepIndex..($stepIndex + 3)] $comment = "quadratic bezier curve $toBy $sequence" $delta = [Numerics.Vector2]::new.Invoke($sequence[-2,-1]) if ($isUpper) { $delta -= $currentPosition } [PSCustomObject]@{ PSTypeName='Turtle.History' Letter = "$letter" Start = $currentPosition End = $currentPosition + $delta Delta = $delta Instruction = "$Letter $sequence" Comment = $comment } $currentPosition += $delta } } { $_ -in 'h', 'v' } { for ($stepIndex = 0; $stepIndex -lt $stepPoints.Length; $stepIndex++) { $sequence = $stepPoints[$stepIndex..$stepIndex] $comment = "$( if ($letter -eq 'v') { 'vertical' } else {'horizontal'} ) line $toBy $sequence" $delta = if ($letter -eq 'v') { [Numerics.Vector2]::new(0, $sequence[0]) } else { [Numerics.Vector2]::new($sequence[0], 0) } if ($isUpper) { $delta -= $currentPosition } [PSCustomObject]@{ PSTypeName='Turtle.History' Letter = "$letter" Start = $currentPosition End = $currentPosition + $delta Delta = $delta Instruction = "$Letter $sequence" Comment = $comment } $currentPosition += $delta } } z { $closePosition = $startStack.Pop() $delta = $closePosition - $currentPosition [PSCustomObject]@{ PSTypeName='Turtle.History' Letter = "$letter" Start = $currentPosition End = $currentPosition + $delta Delta = $delta Instruction = "$Letter" Comment = "close path" } $currentPosition += $delta } } $historyList.Add($historyEntry) } return $historyList  |