@@ -151,19 +151,33 @@ $Radius = 10,
151151$Angle = 60
152152)
153153
154-
155- # Determine the absolute angle, for this
154+ # Determine the absolute angle, for this operation
156155$absAngle = [Math]::Abs($angle)
157- $circumferenceStep = ([Math]::PI * 2 * $Radius) / $absAngle
158156
159- $iteration = $angle / [Math]::Floor($absAngle)
160- $angleDelta = 0
161- $null = while ([Math]::Abs($angleDelta) -lt $absAngle) {
162- $this.Forward($circumferenceStep)
163- $this.Rotate($iteration)
157+ if ($absAngle -eq 0) { return $this }
158+
159+ # Determine the circumference of a circle of this radius
160+ $Circumference = ((2 * $Radius) * [Math]::PI)
161+
162+ # Clamp the angle, as arcs beyond 360 just continue to circle
163+ $ClampedAngle =
164+ if ($absAngle -gt 360) { 360 }
165+ elseif ($absAngle -lt -360) { -360}
166+ else { $absAngle }
167+ # The circumference step is the circumference divided by our clamped angle
168+ $CircumferenceStep = $Circumference / [Math]::Floor($ClampedAngle)
169+ # The iteration is as close to one or negative one as possible
170+ $iteration = $angle / [Math]::Floor($absAngle)
171+ # Start off at iteration 1
172+ $angleDelta = $iteration
173+ # while we have not reached the angle
174+ while ([Math]::Abs($angleDelta) -le $absAngle) {
175+ # Rotate and move forward
176+ $null = $this.Rotate($iteration).Forward($CircumferenceStep)
164177 $angleDelta+=$iteration
165178}
166179
180+ # Return this so we can keep the chain.
167181return $this
168182 </Script >
169183 </ScriptMethod >
@@ -1188,6 +1202,111 @@ return $this | Save-Turtle @saveSplat
11881202
11891203 </Script >
11901204 </ScriptMethod >
1205+ <ScriptMethod >
1206+ <Name >Scissor</Name >
1207+ <Script >
1208+ < #
1209+ .SYNOPSIS
1210+ Draws a Scissor
1211+ .DESCRIPTION
1212+ Draws a Scissor in turtle.
1213+
1214+ A Scissor is a pair of intersecting lines, drawn at an angle.
1215+ .EXAMPLE
1216+ Turtle Scissor Save ./Scissor.svg
1217+ #>
1218+ param(
1219+ # The distance to travel
1220+ [double]
1221+ $Distance = 10,
1222+
1223+ # The interior angle of the scissors
1224+ [double]
1225+ $Angle = 60
1226+ )
1227+
1228+
1229+ $this.
1230+ Rotate($angle). # Rotate
1231+ Forward($distance). # Move Forward
1232+ Rotate($angle * -2). # Rotate Back
1233+ Forward($Distance). # Move Forward
1234+ Rotate($Angle) # Rotate
1235+
1236+ </Script >
1237+ </ScriptMethod >
1238+ <ScriptMethod >
1239+ <Name >ScissorPoly</Name >
1240+ <Script >
1241+ < #
1242+ .SYNOPSIS
1243+ Draws a polygon made of Scissors
1244+ .DESCRIPTION
1245+ Draws a polygon made up of a series of Scissor shapes, followed by a rotation.
1246+
1247+ This countiues until the total angle is approximately 360.
1248+ .EXAMPLE
1249+ # When the angles are even divisors of 360, we get stars
1250+ Turtle ScissorPoly 84 60 72 save ./ScissorPolyStar.svg
1251+ .EXAMPLE
1252+ Turtle ScissorPoly 23 60 72 save ./ScissorPolyStar2.svg
1253+ .EXAMPLE
1254+ Turtle ScissorPoly 23 60 40 save ./ScissorPolyStar3.svg
1255+ .EXAMPLE
1256+ # When both angles exceed 180, the star starts to overlap
1257+ Turtle ScissorPoly 23 90 120 save ./ScissorPoly.svg
1258+ .EXAMPLE
1259+ # When the angle is _not_ an even multiple of 360, there is much more overlap
1260+ Turtle ScissorPoly 16 42 42 save ./ScissorPoly.svg
1261+ .EXAMPLE
1262+ # This can get very chaotic, if it takes a while to reach a multiple of 360
1263+ # Build N scissor polygons
1264+ foreach ($n in 60..72) {
1265+ Turtle ScissorPoly 16 $n $n save ./ScissorPoly-$n.svg
1266+ }
1267+ .EXAMPLE
1268+ Turtle ScissorPoly 16 69 69 save ./ScissorPoly-69.svg
1269+ .EXAMPLE
1270+ Turtle ScissorPoly 15 72 90 save ./ScissorPoly.svg
1271+ .EXAMPLE
1272+ # And angle of exactly 90 will produce a series of spokes
1273+ Turtle ScissorPoly 23 45 90 save ./Compass.svg
1274+ .EXAMPLE
1275+ # These spokes become pointy stars as we iterate past 90
1276+ foreach ($n in 91..99) {
1277+ Turtle ScissorPoly 23 45 $n save "./Scissor-45-$n.svg"
1278+ }
1279+ .EXAMPLE
1280+ Turtle ScissorPoly 23 45 98 save ./ScissorPoly-45-98.svg
1281+ .EXAMPLE
1282+ Turtle ScissorPoly 23 45 99 save ./ScissorPoly-45-99.svg
1283+ #>
1284+ param(
1285+ # The distance of each side of the scissor
1286+ [double]
1287+ $Distance,
1288+
1289+ # The angle between each scissor
1290+ [double]
1291+ $Angle,
1292+
1293+ # The angle of each scissor, or the degree out of phase a regular N-gon would be.
1294+ [double]
1295+ $Phase
1296+ )
1297+
1298+ $totalTurn = 0
1299+
1300+ do {
1301+ $this = $this.Scissor($Distance, $Phase).Left($angle)
1302+ $totalTurn -= $angle
1303+ }
1304+ until (
1305+ (-not ([Math]::Round($totalTurn, 5) % 360 ))
1306+ )
1307+
1308+ </Script >
1309+ </ScriptMethod >
11911310 <ScriptMethod >
11921311 <Name >SierpinskiArrowheadCurve</Name >
11931312 <Script >
@@ -2088,7 +2207,16 @@ return ([pscustomobject]@{ X = 0; Y = 0 })
20882207 <ScriptProperty >
20892208 <Name >OffsetPath</Name >
20902209 <GetScriptBlock >
2091- "offset-path: $($this.PathData);"
2210+ < #
2211+ .SYNOPSIS
2212+ Gets the Turtle as an OffsetPath
2213+ .DESCRIPTION
2214+ Gets the Turtle as an offset path.
2215+ .LINK
2216+ https://developer.mozilla.org/en-US/docs/Web/CSS/offset-path
2217+ #>
2218+ param()
2219+ "offset-path: path('$($this.PathData)');"
20922220 </GetScriptBlock >
20932221 </ScriptProperty >
20942222 <ScriptProperty >
0 commit comments