Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
## Turtle 0.1.5:

* New Shapes:
* Scissor draws a pair of lines at an angle (#128)
* ScissorPoly draws a polygon out of scissors (#129)
* Fixes:
* OffsetPath is now quoted (#130)
* ArcLeft/Right distance fix (#131)

---

## Turtle 0.1.4

* `Turtle` Upgrades
Expand Down
14 changes: 14 additions & 0 deletions Examples/EndlessScissorPoly.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
20 changes: 20 additions & 0 deletions Examples/EndlessScissorPoly.turtle.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
Push-Location $PSScriptRoot
$turtle = turtle ScissorPoly 230 64 64 |
Set-Turtle -Property PatternTransform -Value @{scale=0.33} |
set-turtle -property Stroke -value '#224488' |
set-turtle -property Fill -value '#4488ff' |
Set-Turtle -Property FillRule -Value 'evenodd' |
Set-Turtle -Property PatternAnimation -Value ([Ordered]@{
type = 'scale' ; values = 1.33,0.66, 1.33 ; repeatCount = 'indefinite' ;dur = "23s"; additive = 'sum'
}, [Ordered]@{
type = 'rotate' ; values = 0, 360 ;repeatCount = 'indefinite'; dur = "41s"; additive = 'sum'
}, [Ordered]@{
type = 'skewX' ; values = -30,30,-30;repeatCount = 'indefinite';dur = "83s";additive = 'sum'
}, [Ordered]@{
type = 'skewY' ; values = 30,-30, 30;repeatCount = 'indefinite';additive = 'sum';dur = "103s"
}, [Ordered]@{
type = 'translate';values = "0 0","42 42", "0 0";repeatCount = 'indefinite';additive = 'sum';dur = "117s"
})

$turtle | save-turtle -Path ./EndlessScissorPoly.svg -Property Pattern
Pop-Location
24 changes: 7 additions & 17 deletions Turtle.psd1
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
@{
# Version number of this module.
ModuleVersion = '0.1.4'
ModuleVersion = '0.1.5'
# Description of the module
Description = "Turtles in a PowerShell"
# Script module or binary module file associated with this manifest.
Expand Down Expand Up @@ -37,24 +37,14 @@
# A URL to the license for this module.
LicenseURI = 'https://github.com/PowerShellWeb/Turtle/blob/main/LICENSE'
ReleaseNotes = @'
## Turtle 0.1.4
## Turtle 0.1.5:

* `Turtle` Upgrades
* `turtle` will return an empty turtle (#112)
* `turtle` now splats to script methods, enabling more complex input binding (#121)
* `LSystem` is faster and more flexible (#116)
* New Properties:
* `get/set_Opacity` (#115)
* `get/set_PathAnimation` (#117)
* `get/set_Width/Height` (#125)
* New Methods:
* `HorizontalLine/VerticalLine` (#126)
* `Petal` (#119)
* `FlowerPetal` (#124)
* `Spirolateral` (#120)
* `StepSpiral` (#122)
* New Shapes:
* Scissor draws a pair of lines at an angle (#128)
* ScissorPoly draws a polygon out of scissors (#129)
* Fixes:
* `Turtle.Towards()` returns a relative angle (#123)
* OffsetPath is now quoted (#130)
* ArcLeft/Right distance fix (#131)

---

Expand Down
20 changes: 20 additions & 0 deletions Turtle.tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,26 @@ describe Turtle {
$png[1..3] -as 'char[]' -as 'string[]' -join '' | Should -Be PNG
}

it 'Can draw an arc' {
$Radius = 1
$t = turtle ArcRight $Radius 360
$Heading = 180.0
[Math]::Round($t.Width,1) | Should -Be ($Radius * 2)
[Math]::Round($t.Heading,1) | Should -Be 360.0

$Radius = 1
$Heading = 180.0
$t = turtle ArcRight $Radius 180
[Math]::Round($t.Width,1) | Should -Be ($Radius * 2)
[Math]::Round($t.Heading,1) | Should -Be $Heading

$Radius = 1
$Heading = 90.0
$t = turtle ArcRight $Radius $Heading
[Math]::Round($t.Width,1) | Should -Be ($Radius * 4)
[Math]::Round($t.Heading,1) | Should -Be $Heading
}


context 'Turtle Directions' {
it 'Can tell you the way towards a point' {
Expand Down
146 changes: 137 additions & 9 deletions Turtle.types.ps1xml
Original file line number Diff line number Diff line change
Expand Up @@ -151,19 +151,33 @@ $Radius = 10,
$Angle = 60
)


# Determine the absolute angle, for this
# Determine the absolute angle, for this operation
$absAngle = [Math]::Abs($angle)
$circumferenceStep = ([Math]::PI * 2 * $Radius) / $absAngle

$iteration = $angle / [Math]::Floor($absAngle)
$angleDelta = 0
$null = while ([Math]::Abs($angleDelta) -lt $absAngle) {
$this.Forward($circumferenceStep)
$this.Rotate($iteration)
if ($absAngle -eq 0) { return $this }

# Determine the circumference of a circle of this radius
$Circumference = ((2 * $Radius) * [Math]::PI)

# Clamp the angle, as arcs beyond 360 just continue to circle
$ClampedAngle =
if ($absAngle -gt 360) { 360 }
elseif ($absAngle -lt -360) { -360}
else { $absAngle }
# The circumference step is the circumference divided by our clamped angle
$CircumferenceStep = $Circumference / [Math]::Floor($ClampedAngle)
# The iteration is as close to one or negative one as possible
$iteration = $angle / [Math]::Floor($absAngle)
# Start off at iteration 1
$angleDelta = $iteration
# while we have not reached the angle
while ([Math]::Abs($angleDelta) -le $absAngle) {
# Rotate and move forward
$null = $this.Rotate($iteration).Forward($CircumferenceStep)
$angleDelta+=$iteration
}

# Return this so we can keep the chain.
return $this
</Script>
</ScriptMethod>
Expand Down Expand Up @@ -1188,6 +1202,111 @@ return $this | Save-Turtle @saveSplat

</Script>
</ScriptMethod>
<ScriptMethod>
<Name>Scissor</Name>
<Script>
&lt;#
.SYNOPSIS
Draws a Scissor
.DESCRIPTION
Draws a Scissor in turtle.

A Scissor is a pair of intersecting lines, drawn at an angle.
.EXAMPLE
Turtle Scissor Save ./Scissor.svg
#&gt;
param(
# The distance to travel
[double]
$Distance = 10,

# The interior angle of the scissors
[double]
$Angle = 60
)


$this.
Rotate($angle). # Rotate
Forward($distance). # Move Forward
Rotate($angle * -2). # Rotate Back
Forward($Distance). # Move Forward
Rotate($Angle) # Rotate

</Script>
</ScriptMethod>
<ScriptMethod>
<Name>ScissorPoly</Name>
<Script>
&lt;#
.SYNOPSIS
Draws a polygon made of Scissors
.DESCRIPTION
Draws a polygon made up of a series of Scissor shapes, followed by a rotation.

This countiues until the total angle is approximately 360.
.EXAMPLE
# When the angles are even divisors of 360, we get stars
Turtle ScissorPoly 84 60 72 save ./ScissorPolyStar.svg
.EXAMPLE
Turtle ScissorPoly 23 60 72 save ./ScissorPolyStar2.svg
.EXAMPLE
Turtle ScissorPoly 23 60 40 save ./ScissorPolyStar3.svg
.EXAMPLE
# When both angles exceed 180, the star starts to overlap
Turtle ScissorPoly 23 90 120 save ./ScissorPoly.svg
.EXAMPLE
# When the angle is _not_ an even multiple of 360, there is much more overlap
Turtle ScissorPoly 16 42 42 save ./ScissorPoly.svg
.EXAMPLE
# This can get very chaotic, if it takes a while to reach a multiple of 360
# Build N scissor polygons
foreach ($n in 60..72) {
Turtle ScissorPoly 16 $n $n save ./ScissorPoly-$n.svg
}
.EXAMPLE
Turtle ScissorPoly 16 69 69 save ./ScissorPoly-69.svg
.EXAMPLE
Turtle ScissorPoly 15 72 90 save ./ScissorPoly.svg
.EXAMPLE
# And angle of exactly 90 will produce a series of spokes
Turtle ScissorPoly 23 45 90 save ./Compass.svg
.EXAMPLE
# These spokes become pointy stars as we iterate past 90
foreach ($n in 91..99) {
Turtle ScissorPoly 23 45 $n save "./Scissor-45-$n.svg"
}
.EXAMPLE
Turtle ScissorPoly 23 45 98 save ./ScissorPoly-45-98.svg
.EXAMPLE
Turtle ScissorPoly 23 45 99 save ./ScissorPoly-45-99.svg
#&gt;
param(
# The distance of each side of the scissor
[double]
$Distance,

# The angle between each scissor
[double]
$Angle,

# The angle of each scissor, or the degree out of phase a regular N-gon would be.
[double]
$Phase
)

$totalTurn = 0

do {
$this = $this.Scissor($Distance, $Phase).Left($angle)
$totalTurn -= $angle
}
until (
(-not ([Math]::Round($totalTurn, 5) % 360 ))
)

</Script>
</ScriptMethod>
<ScriptMethod>
<Name>SierpinskiArrowheadCurve</Name>
<Script>
Expand Down Expand Up @@ -2088,7 +2207,16 @@ return ([pscustomobject]@{ X = 0; Y = 0 })
<ScriptProperty>
<Name>OffsetPath</Name>
<GetScriptBlock>
"offset-path: $($this.PathData);"
&lt;#
.SYNOPSIS
Gets the Turtle as an OffsetPath
.DESCRIPTION
Gets the Turtle as an offset path.
.LINK
https://developer.mozilla.org/en-US/docs/Web/CSS/offset-path
#&gt;
param()
"offset-path: path('$($this.PathData)');"
</GetScriptBlock>
</ScriptProperty>
<ScriptProperty>
Expand Down
30 changes: 22 additions & 8 deletions Types/Turtle/ArcRight.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,31 @@ $Radius = 10,
$Angle = 60
)


# Determine the absolute angle, for this
# Determine the absolute angle, for this operation
$absAngle = [Math]::Abs($angle)
$circumferenceStep = ([Math]::PI * 2 * $Radius) / $absAngle

$iteration = $angle / [Math]::Floor($absAngle)
$angleDelta = 0
$null = while ([Math]::Abs($angleDelta) -lt $absAngle) {
$this.Forward($circumferenceStep)
$this.Rotate($iteration)
if ($absAngle -eq 0) { return $this }

# Determine the circumference of a circle of this radius
$Circumference = ((2 * $Radius) * [Math]::PI)

# Clamp the angle, as arcs beyond 360 just continue to circle
$ClampedAngle =
if ($absAngle -gt 360) { 360 }
elseif ($absAngle -lt -360) { -360}
else { $absAngle }
# The circumference step is the circumference divided by our clamped angle
$CircumferenceStep = $Circumference / [Math]::Floor($ClampedAngle)
# The iteration is as close to one or negative one as possible
$iteration = $angle / [Math]::Floor($absAngle)
# Start off at iteration 1
$angleDelta = $iteration
# while we have not reached the angle
while ([Math]::Abs($angleDelta) -le $absAngle) {
# Rotate and move forward
$null = $this.Rotate($iteration).Forward($CircumferenceStep)
$angleDelta+=$iteration
}

# Return this so we can keep the chain.
return $this
27 changes: 27 additions & 0 deletions Types/Turtle/Scissor.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<#
.SYNOPSIS
Draws a Scissor
.DESCRIPTION
Draws a Scissor in turtle.

A Scissor is a pair of intersecting lines, drawn at an angle.
.EXAMPLE
Turtle Scissor Save ./Scissor.svg
#>
param(
# The distance to travel
[double]
$Distance = 10,

# The interior angle of the scissors
[double]
$Angle = 60
)


$this.
Rotate($angle). # Rotate
Forward($distance). # Move Forward
Rotate($angle * -2). # Rotate Back
Forward($Distance). # Move Forward
Rotate($Angle) # Rotate
Loading
Loading