Types/Turtle/get_PathData.ps1

<#
.SYNOPSIS
    Gets our Turtle's path
.DESCRIPTION
    Gets the path data of this Turtle's movements.
    
    This is the shape this turtle will draw.
.NOTES
    Turtle Path data is represented as a
    [SVG path](https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorials/SVG_from_scratch/Paths).
    
    This format can also be used as a [Path2D](https://developer.mozilla.org/en-US/docs/Web/API/Path2D/Path2D) in a Canvas element.

    It can also be used in WPF, where it is simply called [Path Markup](https://learn.microsoft.com/en-us/dotnet/desktop/wpf/graphics-multimedia/path-markup-syntax)
.LINK
    https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorials/SVG_from_scratch/Paths
.LINK
    https://developer.mozilla.org/en-US/docs/Web/API/Path2D/Path2D
.LINK
    https://learn.microsoft.com/en-us/dotnet/desktop/wpf/graphics-multimedia/path-markup-syntax?wt.mc_id=MVP_321542
.EXAMPLE
    turtle square 42 pathdata
#>

@(
    # Let's call this trick Schrödinger's rounding.
    # We want to be able to render our shapes with a custom precision
    # but we don't want to slow down in rounding or only be able to round once.
    
    # So we can round when we ask for the path data.
    # This is a much less common request than moving the turtle forward.
    $precision = $this.Precision
    filter roundToPrecision { [Math]::Round($_, $precision)}
    
    if ($null -ne $this.Start.X -and $null -ne $this.Start.Y) {
        if ($precision) {
            "m $($this.Start.x | roundToPrecision) $($this.Start.y | roundToPrecision)"
        } else {
            "m $($this.Start.x) $($this.Start.y)"
        }
        
    }
    else {
        @("m"
        # If the viewbox has been manually set
        if ($this.'.ViewBox') {
            0, 0 # do not adjust our starting position
        } else {
            # otherwise, translate by the minimum point.
            if ($this.Minimum.X -lt 0) {
                if ($precision) {
                    -1 * $this.Minimum.X | roundToPrecision
                } else {
                    -1 * $this.Minimum.X
                }                
            }
            else { 0 }

            if ($this.Minimum.Y -lt 0) {
                if ($precision) {
                    -1 * $this.Minimum.Y | roundToPrecision
                } else {
                    -1 * $this.Minimum.Y
                }
                
            }
            else { 0 }
        }) -join ' '
    }
    
    # Walk over our steps
    foreach ($step in
        $this.Steps -join ' ' -replace ',',' ' -split '(?=[\p{L}-[E]])' -ne ''
    ) {
        # If our precision is zero or nothing, don't round
        if (-not $precision) {
            $step
        } else {
            # Otherwise, pick out the letter
            $step.Substring(0,1)
            # and get each digit
            $digits = $step.Substring(1) -split '\s+' -ne '' -as [double[]]
            # and round them.
            foreach ($digit in $digits) {                
                [Math]::Round($digit, $precision)
            }            
        }
    }    
) -join ' '