diff --git a/CHANGELOG.md b/CHANGELOG.md index f24e377..4c42b4f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,15 @@ +## Turtle 0.1.8: + +* Turtle Performance + * Improving `.Steps` performance (#159) + * Reducing Turtle Verbosity (#160) +* New Moves: + * Step (#161) + * Forward,Teleport, and GoTo now use Step (#161) +* New Reflection Examples (#162) + +--- + ## Turtle 0.1.7: * Morphing Turtles diff --git a/Commands/Get-Turtle.ps1 b/Commands/Get-Turtle.ps1 index 6704f1f..16e97cd 100644 --- a/Commands/Get-Turtle.ps1 +++ b/Commands/Get-Turtle.ps1 @@ -64,6 +64,9 @@ function Get-Turtle { .EXAMPLE # Let's make a triangle by multiplying steps turtle ('forward', 10, 'rotate', 120 * 3) + .EXAMPLE + # We can also write this with a polygon + turtle polygon 10 3 .EXAMPLE # Let's make a series of polygons, decreasing in size turtle polygon 10 6 polygon 10 5 polygon 10 4 @@ -87,6 +90,12 @@ function Get-Turtle { $sideCount } ) + .EXAMPLE + # We can reflect a shape by drawing it with a negative number + turtle polygon 42 3 polygon -42 3 + .EXAMPLE + # We can change the angle of reflection by rotating first + turtle rotate 60 polygon 42 3 polygon -42 3 .EXAMPLE # We can morph any N shapes with the same number of points. turtle square 42 morph @( @@ -95,14 +104,23 @@ function Get-Turtle { turtle square 42 ) .EXAMPLE - # This animates the path of the turtle. + # Reflections always have the same number of points. + # + # Morphing a shape into its reflection will zoom out, flip, and zoom back in. + turtle polygon 42 6 morph @( + turtle polygon -42 6 + turtle polygon 42 6 + turtle polygon -42 6 + ) + .EXAMPLE # If we want to morph a smaller shape into a bigger shape, - # we can duplicate more lines + # + # we can duplicate lines turtle polygon 21 6 morph @( turtle @('forward', 21,'backward', 21 * 3) turtle polygon 21 6 turtle @('forward', 21,'backward', 21 * 3) - ) + ) .EXAMPLE # We can repeat steps by multiplying arrays. # Lets repeat a hexagon three times with a rotation @@ -304,6 +322,9 @@ function Get-Turtle { .EXAMPLE # The SierpinskiTriangle is a Fractal classic turtle SierpinskiTriangle 42 4 + .EXAMPLE + # Let's draw two reflected Sierpinski Triangles + turtle rotate 60 SierpinskiTriangle 42 4 SierpinskiTriangle -42 4 .EXAMPLE # We can draw a 'Sierpinski Snowflake' with multiple Sierpinski Triangles. turtle @('rotate', 30, 'SierpinskiTriangle',42,4 * 12) diff --git a/Examples/BoxFractal.svg b/Examples/BoxFractal.svg index e745d7c..a3771ef 100644 --- a/Examples/BoxFractal.svg +++ b/Examples/BoxFractal.svg @@ -1,6 +1,6 @@ - + diff --git a/Examples/EndlessBoxFractal.svg b/Examples/EndlessBoxFractal.svg index b31525d..7134fff 100644 --- a/Examples/EndlessBoxFractal.svg +++ b/Examples/EndlessBoxFractal.svg @@ -6,7 +6,7 @@ - + diff --git a/Examples/EndlessHilbert.svg b/Examples/EndlessHilbert.svg index 996cd0e..6243f0d 100644 --- a/Examples/EndlessHilbert.svg +++ b/Examples/EndlessHilbert.svg @@ -6,7 +6,7 @@ - + diff --git a/Examples/EndlessScissorPoly.svg b/Examples/EndlessScissorPoly.svg index 74d3ba9..e2cfff0 100644 --- a/Examples/EndlessScissorPoly.svg +++ b/Examples/EndlessScissorPoly.svg @@ -6,7 +6,7 @@ - + diff --git a/Examples/EndlessSierpinskiTrianglePattern.svg b/Examples/EndlessSierpinskiTrianglePattern.svg index 01fdacc..cca5d4d 100644 --- a/Examples/EndlessSierpinskiTrianglePattern.svg +++ b/Examples/EndlessSierpinskiTrianglePattern.svg @@ -6,7 +6,7 @@ - + diff --git a/Examples/EndlessSnowflake.svg b/Examples/EndlessSnowflake.svg index 5e944d6..8d48d65 100644 --- a/Examples/EndlessSnowflake.svg +++ b/Examples/EndlessSnowflake.svg @@ -6,7 +6,7 @@ - + diff --git a/Examples/EndlessSpirolateral.svg b/Examples/EndlessSpirolateral.svg index 2552f07..491d75c 100644 --- a/Examples/EndlessSpirolateral.svg +++ b/Examples/EndlessSpirolateral.svg @@ -6,7 +6,7 @@ - + diff --git a/Examples/EndlessStepSpiral.svg b/Examples/EndlessStepSpiral.svg index 4b6330d..2a30361 100644 --- a/Examples/EndlessStepSpiral.svg +++ b/Examples/EndlessStepSpiral.svg @@ -4,7 +4,7 @@ - + diff --git a/Examples/SierpinskiTriangle.svg b/Examples/SierpinskiTriangle.svg index 8d733a4..4000b31 100644 --- a/Examples/SierpinskiTriangle.svg +++ b/Examples/SierpinskiTriangle.svg @@ -1,6 +1,6 @@ - + diff --git a/Turtle.psd1 b/Turtle.psd1 index 4698faa..21acfbf 100644 --- a/Turtle.psd1 +++ b/Turtle.psd1 @@ -1,6 +1,6 @@ @{ # Version number of this module. - ModuleVersion = '0.1.7' + ModuleVersion = '0.1.8' # Description of the module Description = "Turtles in a PowerShell" # Script module or binary module file associated with this manifest. @@ -37,15 +37,15 @@ # A URL to the license for this module. LicenseURI = 'https://github.com/PowerShellWeb/Turtle/blob/main/LICENSE' ReleaseNotes = @' -## Turtle 0.1.7: - -* Morphing Turtles - * `Turtle.Morph` morphs shapes (#154) - * `Turtle.get/set_Duration` control animation durations (#153) - * [Lots of new examples](https://psturtle.com/Commands/Get-Turtle) -* New Fractals: - * LevyCurve (#155) - * Triplexity (#156) +## Turtle 0.1.8: + +* Turtle Performance + * Improving `.Steps` performance (#159) + * Reducing Turtle Verbosity (#160) +* New Moves: + * Step (#161) + * Forward,Teleport, and GoTo now use Step (#161) +* New Reflection Examples (#162) --- diff --git a/Turtle.types.ps1xml b/Turtle.types.ps1xml index c52d98f..5126e63 100644 --- a/Turtle.types.ps1xml +++ b/Turtle.types.ps1xml @@ -530,20 +530,23 @@ return $this Forward @@ -626,15 +629,10 @@ $X, $Y ) -$deltaX = $x - $this.X -$deltaY = $y - $this.Y -if ($this.IsPenDown) { - $this.Steps += " l $deltaX $deltaY" -} else { - $this.Steps += " m $deltaX $deltaY" -} -$this.Position = $deltaX, $deltaY -return $this +return $this.Step( + $x - $this.X, + $y - $this.Y +) @@ -1867,6 +1865,38 @@ foreach ($n in 1..$Points) { + + Step + + StepSpiral @@ -2396,10 +2428,10 @@ $this.PathAttribute = [Ordered]@{'fill-rule' = $fillRule.ToLower()} Gets the current heading of the turtle. #> param() -if ($null -ne $this.'.TurtleHeading') { - return $this.'.TurtleHeading' +if ($this -and -not $this.psobject.properties['.TurtleHeading']) { + $this.psobject.properties.add([PSNoteProperty]::new('.TurtleHeading', 0.0), $false) } -return 0 +return $this.'.TurtleHeading' @@ -2422,12 +2454,6 @@ if ($this -and -not $this.psobject.properties['.TurtleHeading']) { $this.psobject.properties.add([PSNoteProperty]::new('.TurtleHeading', 0), $false) } $this.'.TurtleHeading' = $Heading - -# $this.psobject.properties.add([PSNoteProperty]::new('.TurtleHeading', $Heading), $false) -# $this | Add-Member -MemberType NoteProperty -Force -Name '.TurtleHeading' -Value $Heading -if ($VerbosePreference -ne 'SilentlyContinue') { - Write-Verbose "Heading to $Heading" -} @@ -2500,13 +2526,12 @@ return $true [bool] $IsDown ) - -$this | - Add-Member -MemberType NoteProperty -Force -Name '.IsPenDown' -Value $IsDown - -if ($VerbosePreference -ne 'SilentlyContinue') { - Write-Verbose "Turtle is now $($IsDown ? 'down' : 'up')" +if ($null -eq $this.'.IsPenDown') { + $this | Add-Member -MemberType NoteProperty -Force -Name '.IsPenDown' -Value $IsDown +} else { + $this.'.IsPenDown' = $IsDown } + @@ -3046,10 +3071,14 @@ $this.'.Stack' Steps - if ($this.'.Steps') { - return $this.'.Steps' + if (-not $this.'.Steps') { + $this.psobject.properties.add( + [psnoteproperty]::new( + '.Steps', [Collections.Generic.List[string]]::new() + ), $false + ) } -return ,@() +return ,$this.'.Steps' @@ -3066,7 +3095,14 @@ param( $Steps ) -$this | Add-Member -MemberType NoteProperty -Force -Name '.Steps' -Value @($Steps) +if (-not $this.'.Steps') { + $this | Add-Member -MemberType NoteProperty -Force -Name '.Steps' -Value @( + [Collections.Generic.List[string]]::new($Steps) + ) +} else { + $this.'.Steps' = $steps +} + diff --git a/Types/Turtle/Forward.ps1 b/Types/Turtle/Forward.ps1 index 27f1c75..6391d1f 100644 --- a/Types/Turtle/Forward.ps1 +++ b/Types/Turtle/Forward.ps1 @@ -1,14 +1,17 @@ +<# +.SYNOPSIS + Moves the turtle forward +.DESCRIPTION + Moves the turtle forward along the current heading +.EXAMPLE + turtle forward rotate 90 forward rotate 90 forward rotate 90 forward rotate 90 +#> param( +# The distance to move forward [double] $Distance = 10 ) -$x = $Distance * [math]::round([math]::cos($this.Heading * [Math]::PI / 180),15) -$y = $Distance * [math]::round([math]::sin($this.Heading * [Math]::PI / 180),15) -$this.Position = $x, $y -if ($This.IsPenDown) { - $this.Steps += " l $x $y" -} else { - $this.Steps += " m $x $y" -} -return $this \ No newline at end of file +$x = $Distance * ([math]::round([math]::cos($this.Heading * [Math]::PI / 180),15)) +$y = $Distance * ([math]::round([math]::sin($this.Heading * [Math]::PI / 180),15)) +return $this.Step($x, $y) \ No newline at end of file diff --git a/Types/Turtle/GoTo.ps1 b/Types/Turtle/GoTo.ps1 index 0b9ef67..575f12a 100644 --- a/Types/Turtle/GoTo.ps1 +++ b/Types/Turtle/GoTo.ps1 @@ -18,12 +18,7 @@ $X, $Y ) -$deltaX = $x - $this.X -$deltaY = $y - $this.Y -if ($this.IsPenDown) { - $this.Steps += " l $deltaX $deltaY" -} else { - $this.Steps += " m $deltaX $deltaY" -} -$this.Position = $deltaX, $deltaY -return $this \ No newline at end of file +return $this.Step( + $x - $this.X, + $y - $this.Y +) \ No newline at end of file diff --git a/Types/Turtle/Step.ps1 b/Types/Turtle/Step.ps1 new file mode 100644 index 0000000..3988b7f --- /dev/null +++ b/Types/Turtle/Step.ps1 @@ -0,0 +1,26 @@ +<# +.SYNOPSIS + Takes a Step +.DESCRIPTION + Makes a relative movement. +.EXAMPLE + turtle step 5 5 step 0 -5 step -5 0 save ./stepTriangle.svg +#> +param( +# The DeltaX +[double]$DeltaX = 0, +# The DeltaY +[double]$DeltaY = 0 +) + +# If both coordinates are empty, there is no step +if ($DeltaX -or $DeltaY) { + $this.Position = $DeltaX, $DeltaY + if ($This.IsPenDown) { + $this.Steps += " l $DeltaX $DeltaY" + } else { + $this.Steps += " m $DeltaX $DeltaY" + } +} + +return $this diff --git a/Types/Turtle/Teleport.ps1 b/Types/Turtle/Teleport.ps1 index 07c2fe6..4149c4d 100644 --- a/Types/Turtle/Teleport.ps1 +++ b/Types/Turtle/Teleport.ps1 @@ -18,6 +18,8 @@ $Y $deltaX = $x - $this.X $deltaY = $y - $this.Y -$this.Steps += "m $deltaX $deltaY" -$this.Position = $deltaX, $deltaY +$penState = $this.IsPenDown +$this.IsPenDown = $false +$null = $this.Step($deltaX, $deltaY) +$this.IsPenDown = $penState return $this \ No newline at end of file diff --git a/Types/Turtle/get_Heading.ps1 b/Types/Turtle/get_Heading.ps1 index d2da812..ac7f31d 100644 --- a/Types/Turtle/get_Heading.ps1 +++ b/Types/Turtle/get_Heading.ps1 @@ -5,8 +5,8 @@ Gets the current heading of the turtle. #> param() -if ($null -ne $this.'.TurtleHeading') { - return $this.'.TurtleHeading' +if ($this -and -not $this.psobject.properties['.TurtleHeading']) { + $this.psobject.properties.add([PSNoteProperty]::new('.TurtleHeading', 0.0), $false) } -return 0 +return $this.'.TurtleHeading' diff --git a/Types/Turtle/get_Steps.ps1 b/Types/Turtle/get_Steps.ps1 index ac07da6..ecac6e0 100644 --- a/Types/Turtle/get_Steps.ps1 +++ b/Types/Turtle/get_Steps.ps1 @@ -1,4 +1,8 @@ -if ($this.'.Steps') { - return $this.'.Steps' +if (-not $this.'.Steps') { + $this.psobject.properties.add( + [psnoteproperty]::new( + '.Steps', [Collections.Generic.List[string]]::new() + ), $false + ) } -return ,@() +return ,$this.'.Steps' diff --git a/Types/Turtle/set_Heading.ps1 b/Types/Turtle/set_Heading.ps1 index 48a6bd3..e5fa088 100644 --- a/Types/Turtle/set_Heading.ps1 +++ b/Types/Turtle/set_Heading.ps1 @@ -15,10 +15,4 @@ $Heading if ($this -and -not $this.psobject.properties['.TurtleHeading']) { $this.psobject.properties.add([PSNoteProperty]::new('.TurtleHeading', 0), $false) } -$this.'.TurtleHeading' = $Heading - -# $this.psobject.properties.add([PSNoteProperty]::new('.TurtleHeading', $Heading), $false) -# $this | Add-Member -MemberType NoteProperty -Force -Name '.TurtleHeading' -Value $Heading -if ($VerbosePreference -ne 'SilentlyContinue') { - Write-Verbose "Heading to $Heading" -} \ No newline at end of file +$this.'.TurtleHeading' = $Heading \ No newline at end of file diff --git a/Types/Turtle/set_IsPenDown.ps1 b/Types/Turtle/set_IsPenDown.ps1 index 6f6a3de..4ff306f 100644 --- a/Types/Turtle/set_IsPenDown.ps1 +++ b/Types/Turtle/set_IsPenDown.ps1 @@ -2,10 +2,8 @@ param( [bool] $IsDown ) - -$this | - Add-Member -MemberType NoteProperty -Force -Name '.IsPenDown' -Value $IsDown - -if ($VerbosePreference -ne 'SilentlyContinue') { - Write-Verbose "Turtle is now $($IsDown ? 'down' : 'up')" -} \ No newline at end of file +if ($null -eq $this.'.IsPenDown') { + $this | Add-Member -MemberType NoteProperty -Force -Name '.IsPenDown' -Value $IsDown +} else { + $this.'.IsPenDown' = $IsDown +} diff --git a/Types/Turtle/set_Steps.ps1 b/Types/Turtle/set_Steps.ps1 index 2e3270e..4c7529e 100644 --- a/Types/Turtle/set_Steps.ps1 +++ b/Types/Turtle/set_Steps.ps1 @@ -11,4 +11,11 @@ param( $Steps ) -$this | Add-Member -MemberType NoteProperty -Force -Name '.Steps' -Value @($Steps) +if (-not $this.'.Steps') { + $this | Add-Member -MemberType NoteProperty -Force -Name '.Steps' -Value @( + [Collections.Generic.List[string]]::new($Steps) + ) +} else { + $this.'.Steps' = $steps +} +