Polyspiral: Difference between revisions

59,046 bytes added ,  4 months ago
m
→‎{{header|Wren}}: Changed to Wren S/H
(→‎{{header|Java}}: adding JS solution)
m (→‎{{header|Wren}}: Changed to Wren S/H)
 
(62 intermediate revisions by 28 users not shown)
Line 34:
 
<br><br>
=={{header|Action!}}==
{{libheader|Action! Tool Kit}}
{{libheader|Action! Real Math}}
<syntaxhighlight lang="action!">INCLUDE "H6:REALMATH.ACT"
 
INT ARRAY SinTab=[
0 4 9 13 18 22 27 31 36 40 44 49 53 58 62 66 71 75 79 83
88 92 96 100 104 108 112 116 120 124 128 132 136 139 143
147 150 154 158 161 165 168 171 175 178 181 184 187 190
193 196 199 202 204 207 210 212 215 217 219 222 224 226
228 230 232 234 236 237 239 241 242 243 245 246 247 248
249 250 251 252 253 254 254 255 255 255 256 256 256 256]
 
INT FUNC Sin(INT a)
WHILE a<0 DO a==+360 OD
WHILE a>360 DO a==-360 OD
IF a<=90 THEN
RETURN (SinTab(a))
ELSEIF a<=180 THEN
RETURN (SinTab(180-a))
ELSEIF a<=270 THEN
RETURN (-SinTab(a-180))
ELSE
RETURN (-SinTab(360-a))
FI
RETURN (0)
 
INT FUNC Cos(INT a)
RETURN (Sin(a-90))
 
PROC DrawSpiral(INT x0,y0)
INT i,angle,x,y,tmp
REAL rx,ry,len,dlen,r1,r2,r3,r256
 
IntToReal(x0,rx)
IntToReal(y0,ry)
ValR("1.9",len)
ValR("1.14",dlen)
IntToReal(256,r256)
angle=0
Plot(x0,y0)
FOR i=1 TO 150
DO
tmp=Cos(angle)
IntToRealForNeg(tmp,r1)
RealDiv(r1,r256,r2)
RealMult(r2,len,r1)
RealAdd(rx,r1,r2)
RealAssign(r2,rx)
 
tmp=Sin(angle)
IntToRealForNeg(tmp,r1)
RealDiv(r1,r256,r2)
RealMult(r2,len,r1)
RealAdd(ry,r1,r2)
RealAssign(r2,ry)
 
x=RealToInt(rx)
y=RealToInt(ry)
DrawTo(x,y)
 
RealAdd(len,dlen,r1)
RealAssign(r1,len)
angle==+123
IF angle>360 THEN
angle==-360
FI
OD
RETURN
 
PROC Main()
BYTE CH=$02FC,COLOR1=$02C5,COLOR2=$02C6
 
Graphics(8+16)
Color=1
COLOR1=$0C
COLOR2=$02
 
DrawSpiral(160,96)
 
DO UNTIL CH#$FF OD
CH=$FF
RETURN</syntaxhighlight>
{{out}}
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Polyspiral.png Screenshot from Atari 8-bit computer]
 
=={{header|AutoHotkey}}==
Requires [https://www.autohotkey.com/boards/viewtopic.php?t=6517 Gdip Library]
<syntaxhighlight lang="autohotkey">If !pToken := Gdip_Startup()
{
MsgBox, 48, gdiplus error!, Gdiplus failed to start. Please ensure you have gdiplus on your system
ExitApp
}
OnExit, Exit
gdip1()
incr := 0
π := 3.141592653589793
loop
{
incr := Mod(incr + 0.05, 360)
x1 := Width/2
y1 := Height/2
length := 5
angle := incr
Gdip_FillRoundedRectangle(G, pBrush, 0, 0, Width, Height, 0)
loop 150
{
x2 := x1 + length * Cos(angle * π/180)
y2 := y1 + length * Sin(angle * π/180)
Gdip_DrawLine(G, pPen, x1, y1, x2, y2)
x1 := x2
y1 := y2
length := length + 3
angle := Mod(angle + incr, 360)
}
UpdateLayeredWindow(hwnd1, hdc, -1, -1, Width, Height)
Sleep 25
}
return
;----------------------------------------------------------------
Esc:: Pause, toggle
^Esc::ExitApp
;----------------------------------------------------------------
gdip1(){
global
Width := A_ScreenWidth+1, Height := A_ScreenHeight+1
Gui, 1: -Caption +E0x80000 +LastFound +OwnDialogs +Owner +AlwaysOnTop
Gui, 1: Show, NA
hwnd1 := WinExist()
hbm := CreateDIBSection(Width, Height)
hdc := CreateCompatibleDC()
obm := SelectObject(hdc, hbm)
G := Gdip_GraphicsFromHDC(hdc)
Gdip_SetSmoothingMode(G, 4)
pBrush := Gdip_BrushCreateSolid("0xFF000000")
pPen := Gdip_CreatePen("0xFF00FF00", 1)
}
;----------------------------------------------------------------
gdip2(){
global
Gdip_DeletePen(pPen)
Gdip_DeleteBrush(pBrush)
SelectObject(hdc, obm)
DeleteObject(hbm)
DeleteDC(hdc)
Gdip_DeleteGraphics(G)
}
;----------------------------------------------------------------
Exit:
gdip2()
Gdip_Shutdown(pToken)
ExitApp
Return
;----------------------------------------------------------------</syntaxhighlight>
 
=={{header|C}}==
Straightforward implementation of the pseudocode, incr and angle are integers and incr is incremented by 5 instead of 0.05 as the % operation in C is not defined for non-integers. Requires the [http://www.cs.colorado.edu/~main/bgi/cs1300/ WinBGIm] library.
<syntaxhighlight lang="c">
<lang C>
/*Abhishek Ghosh, 23rd September 2017*/
 
#include<graphics.h>
#include<math.h>
Line 85 ⟶ 240:
return 0;
}
</syntaxhighlight>
</lang>
 
=={{header|C sharp|C#}}==
{{trans|Java}}
<syntaxhighlight lang="csharp">using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
using System.Windows.Threading;
 
namespace Polyspiral
{
public partial class Form1 : Form
{
private double inc;
 
public Form1()
{
Width = Height = 640;
StartPosition = FormStartPosition.CenterScreen;
SetStyle(
ControlStyles.AllPaintingInWmPaint |
ControlStyles.UserPaint |
ControlStyles.DoubleBuffer,
true);
 
var timer = new DispatcherTimer();
timer.Tick += (s, e) => { inc = (inc + 0.05) % 360; Refresh(); };
timer.Interval = new TimeSpan(0, 0, 0, 0, 40);
timer.Start();
}
 
private void DrawSpiral(Graphics g, int len, double angleIncrement)
{
double x1 = Width / 2;
double y1 = Height / 2;
double angle = angleIncrement;
 
for (int i = 0; i < 150; i++)
{
double x2 = x1 + Math.Cos(angle) * len;
double y2 = y1 - Math.Sin(angle) * len;
g.DrawLine(Pens.Blue, (int)x1, (int)y1, (int)x2, (int)y2);
x1 = x2;
y1 = y2;
 
len += 3;
 
angle = (angle + angleIncrement) % (Math.PI * 2);
}
}
 
protected override void OnPaint(PaintEventArgs args)
{
var g = args.Graphics;
g.SmoothingMode = SmoothingMode.AntiAlias;
g.Clear(Color.White);
 
DrawSpiral(g, 5, ToRadians(inc));
}
 
private double ToRadians(double angle)
{
return Math.PI * angle / 180.0;
}
}
}</syntaxhighlight>
 
=={{header|C++}}==
This Windows programm has no animation, it will simply save 100 bitmaps onto your harddrive
<langsyntaxhighlight lang="cpp">
#include <windows.h>
#include <sstream>
Line 233 ⟶ 454:
return 0;
}
</syntaxhighlight>
</lang>
 
=={{header|C#Ceylon}}==
Be sure to import javafx.graphics and ceylon.numeric in your module.ceylon file.
{{trans|Java}}
<syntaxhighlight lang="ceylon">import javafx.application {
<lang csharp>using System;
Application
using System.Drawing;
}
using System.Drawing.Drawing2D;
import javafx.stage {
using System.Windows.Forms;
Stage
using System.Windows.Threading;
}
import javafx.animation {
AnimationTimer
}
import ceylon.numeric.float {
remainder,
cos,
sin,
toRadians
}
import javafx.scene.layout {
BorderPane
}
import javafx.scene.canvas {
Canvas
}
import javafx.scene {
Scene
}
import javafx.scene.paint {
Color
}
 
shared void run() {
namespace Polyspiral
Application.launch(`PolySpiralApp`);
{
}
public partial class Form1 : Form
{
private double inc;
 
shared class PolySpiralApp() extends Application() {
public Form1()
{
Width = Height = 640;
StartPosition = FormStartPosition.CenterScreen;
SetStyle(
ControlStyles.AllPaintingInWmPaint |
ControlStyles.UserPaint |
ControlStyles.DoubleBuffer,
true);
 
value width = 600.0;
var timer = new DispatcherTimer();
value height = 600.0;
timer.Tick += (s, e) => { inc = (inc + 0.05) % 360; Refresh(); };
timer.Interval = new TimeSpan(0, 0, 0, 0, 40);
timer.Start();
}
 
variable value incr = 0.0;
private void DrawSpiral(Graphics g, int len, double angleIncrement)
{
double x1 = Width / 2;
double y1 = Height / 2;
double angle = angleIncrement;
 
shared actual void start(Stage primaryStage) {
for (int i = 0; i < 150; i++)
{
double x2 = x1 + Math.Cos(angle) * len;
double y2 = y1 - Math.Sin(angle) * len;
g.DrawLine(Pens.Blue, (int)x1, (int)y1, (int)x2, (int)y2);
x1 = x2;
y1 = y2;
 
value canvas = Canvas(width, len += 3height);
value graphics = canvas.graphicsContext2D;
 
object extends AnimationTimer() {
angle = (angle + angleIncrement) % (Math.PI * 2);
}
}
 
protected override shared actual void OnPainthandle(PaintEventArgsInteger argsnow) {
{
var g = args.Graphics;
g.SmoothingMode = SmoothingMode.AntiAlias;
g.Clear(Color.White);
 
DrawSpiral incr = remainder(g,incr 5+ 0.05, ToRadians(inc)360.0);
}
 
variable value x = width / 2.0;
private double ToRadians(double angle)
variable value y = width / 2.0;
{
return Math.PI * angle /variable 180value length = 5.0;
variable value angle = incr;
}
 
graphics.fillRect(0.0, 0.0, width, height);
graphics.beginPath();
graphics.moveTo(x, y);
 
for (i in 1..150) {
value radians = toRadians(angle);
x = x + cos(radians) * length;
y = y + sin(radians) * length;
graphics.stroke = Color.hsb(angle, 1.0, 1.0);
graphics.lineTo(x, y);
length += 3;
angle = remainder(angle + incr, 360.0);
}
 
graphics.stroke();
}
}.start();
 
value root = BorderPane();
root.center = canvas;
value scene = Scene(root);
primaryStage.title = "poly-spiral";
primaryStage.setScene(scene);
primaryStage.show();
}
}</langsyntaxhighlight>
 
=={{header|Delphi}}==
{{works with|Delphi|6.0}}
{{libheader|SysUtils,StdCtrls}}
 
[[File:DelphiSpiralAnimaion.png|frame|none]]
 
 
<syntaxhighlight lang="Delphi">
 
 
procedure PolySpiral(Image: TImage);
var Step,Angle,LineLen,I: integer;
var X,Y,X1,Y1: double;
begin
AbortFlag:=False;
ClearImage(Image,clBlack);
Image.Canvas.Pen.Width:=1;
while true do
begin
Image.Canvas.Pen.Color:=clYellow;
Step:=(Step + 5) mod 360;
X:=Image.Width/2;
Y:=Image.Height/2;
 
LineLen:=5;
angle:=Step;
for I:=1 to 150 do
begin
X1:=X + LineLen*cos(DegToRad(angle));
Y1:=Y + LineLen*sin(DegToRad(angle));
Image.Canvas.MoveTo(Round(X),Round(Y));
Image.Canvas.LIneTo(Round(X1),Round(Y1));
Image.Repaint;
 
LineLen:=LineLen+2;
 
Angle:=(Angle + Step) mod 360;
X:=X1;
Y:=Y1;
end;
if Application.Terminated then exit;
if AbortFlag then break;
Sleep(1200);
Application.ProcessMessages;
WaitForButton;
ClearImage(Image,clBlack);
end;
end;
 
 
</syntaxhighlight>
{{out}}
<pre>
 
</pre>
 
=={{header|EasyLang}}==
 
[https://easylang.dev/show/#cod=bU/LCsMgELz7FXtMKwTzKvSQjxFjU8GskIQ2/n13jekDenLGmR1mTPBhhmvbCu/QPt2w3kGVjQgIGt2kVysAwHirZwYOzQw9FOmV5FTdCaYwQHNRrG8VqV2C8QO9xZFye6iYaRy9JcIZzKfwsHwYk3qjOo6tsAao9nsOrumPTBJMWHLEOQdnS2RLZMvi8L+FN3JUrI9YLrkdLFV+a7m1zLW/mhc7kGnCz/5SlOIF Run it]
 
<syntaxhighlight lang="easylang">
color 944
linewidth 0.3
on animate
clear
incr = (incr + 0.05) mod 360
x1 = 50
y1 = 50
length = 1
angle = incr
move x1 y1
for i = 1 to 150
x2 = x1 + cos angle * length
y2 = y1 + sin angle * length
line x2 y2
x1 = x2
y1 = y2
length += 1
angle = (angle + incr) mod 360
.
.
</syntaxhighlight>
 
=={{header|FreeBASIC}}==
<syntaxhighlight lang="freebasic">#include "fbgfx.bi"
#if __FB_LANG__ = "fb"
Using FB '' Scan code constants are stored in the FB namespace in lang FB
#endif
#define pi 4 * Atn(1)
#define Deg2Rad pi/180
 
Dim As Integer w = 900, h = w
Screenres w, h, 8
Windowtitle "Polyspiral"
 
Dim As Integer incr = 0, angulo, longitud, x1, y1, x2, y2, N
Do
incr += 1
x1 = w / 2
y1 = h / 2
Pset (Fix(x1), Fix(y1))
longitud = 5
angulo = incr
For N = 1 To 150
x2 = x1 + longitud * Cos(angulo * Deg2Rad)
y2 = y1 + longitud * Sin(angulo * Deg2Rad)
Line - (Fix(x2), Fix(y2)), N+16
x1 = x2
y1 = y2
longitud += 3
angulo += incr
Next N
Sleep 500
Cls
Loop Until Multikey(SC_ESCAPE)</syntaxhighlight>
 
=={{header|FutureBasic}}==
<syntaxhighlight lang="futurebasic">
local fn DoIt
NSInteger i, t
double length, incr, x1, y1, x2, y2, twopi, angle, w, h
pen 2.0, fn ColorRed, NSLineCapStyleButt, NULL, 0
incr = 0 : twopi = 2 * pi
w = 600 : h = 600
t = 150
while ( t > 0 )
incr = ( incr + 0.05 mod twopi )
x1 = w / 2
y1 = h / 2
length = 1.0
angle = incr
line to x1, y1
cls
for i = 1 to 300
x2 = x1 + cos( angle ) * length
y2 = y1 + sin( angle ) * length
line to x1, y1 to x2, y2
x1 = x2 : y1 = y2
length = length + 1.0
angle = ( angle + incr mod twopi )
next
t--
wend
end fn
 
window 1, @"Rosetta Code Polyspiral", fn CGRectMake( 0, 0, 600, 600 )
WindowSetBackgroundColor( 1, fn ColorBlack )
 
fn DoIt
 
HandleEvents
</syntaxhighlight>
{{output}}
[[File:Polyspiral FutureBasic.png]]
 
 
 
 
=={{header|Fōrmulæ}}==
 
{{FormulaeEntry|page=https://formulae.org/?script=examples/Polyspiral}}
 
'''Solution'''
 
[[File:Fōrmulæ - Polyspiral 01.png]]
 
'''Test cases'''
 
[[File:Fōrmulæ - Polyspiral 02.png]]
 
[[File:Fōrmulæ - Polyspiral 03.png]]
 
[[File:Fōrmulæ - Polyspiral 04.png]]
 
[[File:Fōrmulæ - Polyspiral 05.png]]
 
[[File:Fōrmulæ - Polyspiral 06.png]]
 
[[File:Fōrmulæ - Polyspiral 07.png]]
 
=={{header|Gnuplot}}==
Line 306 ⟶ 728:
===Plotting a polyspiral file-function for the load command===
'''plotpoly.gp''' file for the load command is the only possible imitation of the fine function in the '''gnuplot'''.
<langsyntaxhighlight lang="gnuplot">
## plotpoly.gp 1/10/17 aev
## Plotting a polyspiral and writing to the png-file.
Line 322 ⟶ 744:
plot [0:c] t*cos(d*t), t*sin(d*t) lt rgb @clr
set output
</langsyntaxhighlight>
 
===Plotting many versions of a polyspiral.===
Line 333 ⟶ 755:
[[File:PS6gp.png|right|thumb|Output PS6gp.png]]
 
<langsyntaxhighlight lang="gnuplot">
## PSpirals.gp 1/10/17 aev
## Plotting many polyspiral pictures.
Line 436 ⟶ 858:
## Continue plotting starting with a range rng=110 to 400+ step 10 to discover new figures.
## END ##
</langsyntaxhighlight>
{{Output}}
<pre>
Line 445 ⟶ 867:
===Plotting a polyspiral file-function for the load command (for animation)===
'''plotpolya.gp''' file for the load command is the only possible imitation of the fine function in the '''gnuplot'''.
<langsyntaxhighlight lang="gnuplot">
## plotpolya.gp 1/19/17 aev
## Plotting a polyspiral and writing to the png-file. Simple plot for animation.
Line 460 ⟶ 882:
plot [0:c] t*cos(d*t), t*sin(d*t) lt rgb @clr
set output
</langsyntaxhighlight>
 
===Plotting many polyspiral and other pictures for animation.===
'''Note:''' No generated pictures here on RC.
<langsyntaxhighlight lang="gnuplot">
## PSpirals4a.gp 1/19/17 aev
## Plotting many polyspiral and other pictures for animation
Line 520 ⟶ 942:
##PS14 Not a polyspiral, but has many short secondary spirals.
rng=700; d=-1; clr = '"navy"'; filename = "PS14"; load "plotpolya.gp";
</langsyntaxhighlight>
{{Output}}
<pre>
Line 532 ⟶ 954:
[[File:NiceFigsAnim.gif|right|thumb|Output NiceFigsAnim.gif]]
 
<langsyntaxhighlight lang="gnuplot">
## Animation for polyspirals PS0 - PS6
reset
Line 554 ⟶ 976:
do for [i=8:14]{plot 'PS'.i.'.png' binary filetype=png with rgbimage}
set output
</langsyntaxhighlight>
{{Output}}
<pre>
Line 562 ⟶ 984:
===Showing 2 animated gif-files.===
Create 2 the following html-files and envoke them in browser.
<langsyntaxhighlight lang="html">
<!-- PolySpirsAnim.html -->
<html><body>
Line 569 ⟶ 991:
<img src="PolySpirsAnim.gif">
</body></html>
</langsyntaxhighlight>
<langsyntaxhighlight lang="html">
<!-- NiceFigsAnim.html -->
<html><body>
Line 577 ⟶ 999:
<img src="NiceFigsAnim.gif">
</body></html>
</langsyntaxhighlight>
{{Output}}
<pre>
2 pages with animation.
</pre>
 
=={{header|Go}}==
This uses Go's 'image' packages in its standard library to create an animated GIF.
 
When played this is similar to the Java entry but much quicker. The whole animation completes in 72 seconds and repeats indefinitely.
 
Although the .gif works fine in Firefox it might not do so in EOG due to optimizations made during its creation. If so, then the following ImageMagick command should fix it:
<pre>
$ convert polyspiral.gif -coalesce polyspiral2.gif
$ eog polyspiral2.gif
</pre>
<syntaxhighlight lang="go">package main
 
import (
"image"
"image/color"
"image/gif"
"log"
"math"
"os"
)
 
func drawLine(img *image.Paletted, x1, y1, x2, y2 int, ci uint8) {
var first, last int
if x2 != x1 {
m := float64(y2-y1) / float64(x2-x1)
if x1 < x2 {
first, last = x1, x2
} else {
first, last = x2, x1
}
for x := first; x <= last; x++ {
y := int(m*float64(x-x1)+0.5) + y1
img.SetColorIndex(x, y, ci)
}
} else {
if y1 < y2 {
first, last = y1, y2
} else {
first, last = y2, y1
}
for y := first; y <= last; y++ {
img.SetColorIndex(x1, y, ci)
}
}
}
 
func setBackgroundColor(img *image.Paletted, w, h int, ci uint8) {
for x := 0; x < w; x++ {
for y := 0; y < h; y++ {
img.SetColorIndex(x, y, ci)
}
}
}
 
func hsb2rgb(hue, sat, bri float64) (r, g, b int) {
u := int(bri*255 + 0.5)
if sat == 0 {
r, g, b = u, u, u
} else {
h := (hue - math.Floor(hue)) * 6
f := h - math.Floor(h)
p := int(bri*(1-sat)*255 + 0.5)
q := int(bri*(1-sat*f)*255 + 0.5)
t := int(bri*(1-sat*(1-f))*255 + 0.5)
switch int(h) {
case 0:
r, g, b = u, t, p
case 1:
r, g, b = q, u, p
case 2:
r, g, b = p, u, t
case 3:
r, g, b = p, q, u
case 4:
r, g, b = t, p, u
case 5:
r, g, b = u, p, q
}
}
return
}
 
func main() {
const degToRad = math.Pi / 180
const nframes = 360
const delay = 20 // 200ms
width, height := 640, 640
anim := gif.GIF{LoopCount: nframes}
rect := image.Rect(0, 0, width, height)
palette := make([]color.Color, 151)
palette[0] = color.White
for i := 1; i <= 150; i++ {
r, g, b := hsb2rgb(float64(i)/150, 1, 1)
palette[i] = color.RGBA{uint8(r), uint8(g), uint8(b), 255}
}
incr := 0
for f := 1; f <= nframes; f++ {
incr = (incr + 1) % 360
x1, y1 := width/2, height/2
length := 5.0
img := image.NewPaletted(rect, palette)
setBackgroundColor(img, width, height, 0) // white background
angle := incr
for ci := uint8(1); ci <= 150; ci++ {
x2 := x1 + int(math.Cos(float64(angle)*degToRad)*length)
y2 := y1 - int(math.Sin(float64(angle)*degToRad)*length)
drawLine(img, x1, y1, x2, y2, ci)
x1, y1 = x2, y2
length += 3
angle = (angle + incr) % 360
}
anim.Delay = append(anim.Delay, delay)
anim.Image = append(anim.Image, img)
}
file, err := os.Create("polyspiral.gif")
if err != nil {
log.Fatal(err)
}
defer file.Close()
if err2 := gif.EncodeAll(file, &anim); err != nil {
log.Fatal(err2)
}
}</syntaxhighlight>
 
=={{header|Haskell}}==
{{Works with|Chrome and Firefox}}
Line 587 ⟶ 1,134:
This implementation compiles to javascript that runs in the browser using the [https://github.com/ghcjs/ghcjs ghcjs compiler ] . The [https://github.com/reflex-frp/reflex-dom reflex-dom ] library is used to help with svg rendering and animation.
 
<langsyntaxhighlight lang="haskell">{-# LANGUAGE OverloadedStrings #-}
import Reflex
import Reflex.Dom
Line 669 ⟶ 1,216:
elSvgns t m ma = do
(el, val) <- elDynAttrNS' (Just "http://www.w3.org/2000/svg") t m ma
return val</langsyntaxhighlight>
 
Link to live demo: https://dc25.github.io/rosettaCode__Polyspiral_haskell/
 
=={{header|IS-BASIC}}==
<syntaxhighlight lang="is-basic">100 PROGRAM "PolySp.bas"
110 OPTION ANGLE DEGREES
120 LET CH=2
130 SET VIDEO X 40:SET VIDEO Y 27:SET VIDEO MODE 1:SET VIDEO COLOR 0
140 OPEN #1:"video:"
150 OPEN #2:"video:"
160 WHEN EXCEPTION USE POSERROR
170 FOR ANG=40 TO 150 STEP 2
180 IF CH=2 THEN
190 LET CH=1
200 ELSE
210 LET CH=2
220 END IF
230 CLEAR #CH
240 PLOT #CH:640,468,ANGLE 180;
250 FOR D=12 TO 740 STEP 4
260 PLOT #CH:FORWARD D,RIGHT ANG;
270 NEXT
280 DISPLAY #CH:AT 1 FROM 1 TO 27
290 NEXT
300 END WHEN
310 HANDLER POSERROR
320 LET D=740
330 CONTINUE
340 END HANDLER</syntaxhighlight>
 
Link to live demo: https://dc25.github.io/rosettaCode__Polyspiral_haskell/
=={{header|J}}==
[[File:J-polyspiral.gif|200px|thumb|right]]
{{trans|java}}
 
<langsyntaxhighlight Jlang="j">require 'gl2 trig media/imagekit'
coinsert 'jgl2'
Line 725 ⟶ 1,300:
)
poly_run''</langsyntaxhighlight>
 
Note that we're using a lot of [[j:Guides/Window_Driver/Command_Reference|wd]] commands here. You'll need to be running [[j:System/Installation|jqt]] for this to work.
Line 732 ⟶ 1,307:
[[File:Polyspiral_java2.png|300px|thumb|right]]
{{works with|Java|8}}
<langsyntaxhighlight lang="java">import java.awt.*;
import java.awt.event.ActionEvent;
import javax.swing.*;
Line 793 ⟶ 1,368:
});
}
}</langsyntaxhighlight>
 
=={{header|JavaScript}}==
===Version #1 - Plain===
This Polyspiral Generator page alows user to enjoy hundreds of polyspirals in different colors.<br>
InspiredThis is inspired by a discovery made while using the gnuplot.
(See [[Talk:Polyspiral| Discussion ]] for Polyspiral task.)<br>
'''Note:'''
* Some polyspirals would be degenerated to a single branch of it or even to a single line.<br>
* An image uploading is still blocked,. But you have a browser!? So, copy/paste/save this page and double click it.
{{Works with|Chrome}} (or any other browser supporting Canvas tag)
<langsyntaxhighlight lang="html">
<!-- Polyspiral.html -->
<html>
Line 864 ⟶ 1,440:
</body>
</html>
</syntaxhighlight>
</lang>
{{Output}}
<pre>
Line 871 ⟶ 1,447:
340, 350, 400, 430, 480, 510, all 1010-2000, a few 3000+, etc.
</pre>
 
===Version #2 - Animated===
{{trans|Java}}
<syntaxhighlight lang="javascript"><!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<style>
body {
background-color: black;
}
</style>
</head>
<body>
<canvas></canvas>
<script>
var canvas = document.querySelector("canvas");
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
 
var g = canvas.getContext("2d");
 
var inc = 0;
 
function drawSpiral(len, angleIncrement) {
var x1 = canvas.width / 2;
var y1 = canvas.height / 2;
var angle = angleIncrement;
 
for (var i = 0; i < 150; i++) {
 
var x2 = x1 + Math.cos(angle) * len;
var y2 = y1 - Math.sin(angle) * len;
 
g.strokeStyle = HSVtoRGB(i / 150, 1.0, 1.0);
g.beginPath();
g.moveTo(x1, y1);
g.lineTo(x2, y2);
g.stroke();
 
x1 = x2;
y1 = y2;
 
len += 3;
 
angle = (angle + angleIncrement) % (Math.PI * 2);
}
}
 
/* copied from stackoverflow */
function HSVtoRGB(h, s, v) {
var r, g, b, i, f, p, q, t;
 
i = Math.floor(h * 6);
f = h * 6 - i;
p = v * (1 - s);
q = v * (1 - f * s);
t = v * (1 - (1 - f) * s);
switch (i % 6) {
case 0: r = v, g = t, b = p; break;
case 1: r = q, g = v, b = p; break;
case 2: r = p, g = v, b = t; break;
case 3: r = p, g = q, b = v; break;
case 4: r = t, g = p, b = v; break;
case 5: r = v, g = p, b = q; break;
}
return "rgb("
+ Math.round(r * 255) + ","
+ Math.round(g * 255) + ","
+ Math.round(b * 255) + ")";
}
 
function toRadians(degrees) {
return degrees * (Math.PI / 180);
}
 
setInterval(function () {
inc = (inc + 0.05) % 360;
g.clearRect(0, 0, canvas.width, canvas.height);
drawSpiral(5, toRadians(inc));
}, 40);
</script>
 
</body>
</html></syntaxhighlight>
 
=={{header|Julia}}==
<syntaxhighlight lang="julia">using Gtk, Graphics, Colors
 
const can = @GtkCanvas()
const win = GtkWindow(can, "Polyspiral", 360, 360)
 
const drawiters = 72
const colorseq = [colorant"blue", colorant"red", colorant"green", colorant"black", colorant"gold"]
const angleiters = [0, 0, 0]
const angles = [75, 100, 135, 160]
 
Base.length(v::Vec2) = sqrt(v.x * v.x + v.y * v.y)
 
function drawline(ctx, p1, p2, color, width=1)
move_to(ctx, p1.x, p1.y)
set_source(ctx, color)
line_to(ctx, p2.x, p2.y)
set_line_width(ctx, width)
stroke(ctx)
end
 
@guarded draw(can) do widget
δ(r, θ) = Vec2(r * cospi(θ/180), r * sinpi(θ/180))
nextpoint(p, r, θ) = (dp = δ(r, θ); Point(p.x + dp.x, p.y + dp.y))
colorindex = (angleiters[1] % 5) + 1
colr = colorseq[colorindex]
ctx = getgc(can)
h = height(can)
w = width(can)
x = 0.5 * w
y = 0.5 * h
θ = angleiters[2] * rand() * 3
δθ = angleiters[2]
r = 5
δr = 3
p1 = Point(x, y)
for i in 1:drawiters
if angleiters[3] == 0
set_source(ctx, colorant"gray90")
rectangle(ctx, 0, 0, w, h)
fill(ctx)
continue
end
p2 = nextpoint(p1, r, θ)
drawline(ctx, p1, p2, colr, 2)
θ = θ + δθ
r = r + δr
p1 = p2
end
end
 
show(can)
 
while true
angleiters[2] = angles[angleiters[1] % 3 + 1]
angleiters[1] += 1
angleiters[3] = angleiters[3] == 0 ? 1 : 0
draw(can)
yield()
sleep(0.5)
end
</syntaxhighlight>
 
=={{header|Kotlin}}==
{{trans|Java}}
<langsyntaxhighlight lang="scala">// version 1.1.0
 
import java.awt.*
Line 928 ⟶ 1,652:
f.setVisible(true)
}
}</langsyntaxhighlight>
 
=={{header|Lua}}==
{{libheader|LÖVE}}
LÖVE defaults to animating at sixty frames per second, so the patterns become very complex very quickly.
<langsyntaxhighlight Lualang="lua">function love.load ()
love.window.setTitle("Polyspiral")
incr = 0
Line 955 ⟶ 1,679:
angle = (angle + incr) % 360
end
end</langsyntaxhighlight>
[[File:love2dPolyspiral.jpg]]
 
=={{header|Mathematica}}/{{header|Wolfram Language}}==
<syntaxhighlight lang="mathematica">linedata = {};
Dynamic[Graphics[Line[linedata], PlotRange -> 1000]]
Do[
linedata = AnglePath[{#, \[Theta]} & /@ Range[5, 300, 3]];
Pause[0.1];
,
{\[Theta], Subdivide[0.1, 1, 100]}
]</syntaxhighlight>
{{out}}
Outputs an animating graphic with a spiral with changing angle.
 
=={{header|Nim}}==
{{libheader|gintro}}
As Julia, we use Gtk/Cairo to draw the polyspirals. So, the drawing part is taken, with some modifications, from Julia solution.
 
<syntaxhighlight lang="nim"># Pendulum simulation.
 
import math, random
 
import gintro/[gobject, gdk, gtk, gio, glib, cairo]
 
const
Width = 500
Height = 500
DrawIters = 72
Red = [float 1, 0, 0]
Green = [float 0, 1, 0]
Blue = [float 0, 0, 1]
Black = [float 0, 0, 0]
White = [float 255, 255, 255]
Gold = [float 255, 215, 0]
Colors = [Blue, Red, Green, White, Gold]
Angles = [75, 100, 135, 160]
 
type
 
Vec2 = tuple[x, y: float]
Point = Vec2
 
# Description of the simulation.
Simulation = ref object
area: DrawingArea
xmax, ymax: float
center: Point
itercount: int
 
#---------------------------------------------------------------------------------------------------
 
proc newSimulation(area: DrawingArea; width, height: int): Simulation {.noInit.} =
## Allocate and initialize the simulation object.
 
new(result)
result.area = area
result.xmax = float(width - 1)
result.ymax = float(height - 1)
result.center = (result.xmax * 0.5, result.ymax * 0.5)
 
#---------------------------------------------------------------------------------------------------
 
func δ(r, θ: float): Vec2 = (r * cos(degToRad(θ)), r * sin(degToRad(θ)))
 
#---------------------------------------------------------------------------------------------------
 
func nextPoint(p: Point; r, θ: float): Point =
let dp = δ(r, θ)
result = (p.x + dp.x, p.y + dp.y)
 
#---------------------------------------------------------------------------------------------------
 
proc draw(sim: Simulation; context: cairo.Context) =
## Draw the spiral.
 
context.setSource(Black)
context.rectangle(0, 0, sim.xmax, sim.ymax)
context.fill()
 
let colorIndex = sim.itercount mod Colors.len
let color = Colors[colorIndex]
 
var p1 = sim.center
let δθ = Angles[sim.itercount mod Angles.len].toFloat
var θ = δθ * rand(1.0) * 3
var r = 5.0
let δr = 3.0
 
for _ in 1..DrawIters:
let p2 = p1.nextPoint(r, θ)
context.moveTo(p1.x, p1.y)
context.setSource(color)
context.lineTo(p2.x, p2.y)
context.setLineWidth(2)
context.stroke()
θ += δθ
r += δr
p1 = p2
 
#---------------------------------------------------------------------------------------------------
 
proc update(sim: Simulation): gboolean =
## Update the simulation state.
 
result = gboolean(1)
sim.draw(sim.area.window.cairoCreate())
inc sim.itercount
 
#---------------------------------------------------------------------------------------------------
 
proc activate(app: Application) =
## Activate the application.
 
let window = app.newApplicationWindow()
window.setSizeRequest(Width, Height)
window.setTitle("Polyspiral")
 
let area = newDrawingArea()
window.add(area)
 
let sim = newSimulation(area, Width, Height)
 
timeoutAdd(500, update, sim)
 
window.showAll()
 
#———————————————————————————————————————————————————————————————————————————————————————————————————
 
let app = newApplication(Application, "Rosetta.polyspiral")
discard app.connect("activate", activate)
discard app.run()</syntaxhighlight>
 
=={{header|PARI/GP}}==
Line 966 ⟶ 1,820:
You can find a few others on [http://oeis.org/wiki/User:Anatoly_E._Voevudko/VoeLib.gp#Plotting_helper_functions OEIS Wiki] and here on RC Wiki.
 
<langsyntaxhighlight lang="parigp">
\\ Plot the line from x1,y1 to x2,y2.
plotline(x1,y1,x2,y2,w=0)={plotmove(w, x1,y1);plotrline(w,x2-x1,y2-y1);}
Line 974 ⟶ 1,828:
cartes2(r,a,rndf=0)={my(v,x,y); x=r*cos(a); y=r*sin(a);
if(rndf==0, return([x,y]), return(round([x,y])))}
</syntaxhighlight>
</lang>
 
===Version #1. Polyspiral (a spiral made of multiple line segments).===
Line 987 ⟶ 1,841:
[[File:Polyspiral4.png|100px|right|thumb|Output Polyspiral4.png]]
 
<langsyntaxhighlight lang="parigp">
\\Polyspiral (a spiral made of multiple line segments)
\\ 4/15/16 aev
Line 1,022 ⟶ 1,876:
polyspiral(100000,100000,0.03,3,2);\\Polyspiral4.png
}
</langsyntaxhighlight>
 
{{Output}}
Line 1,054 ⟶ 1,908:
[[File:Spiralz1.png|100px|right|thumb|Output Spiralz.png]]
 
<langsyntaxhighlight lang="parigp">
\\ plotpspiralz() Multi-spiral figure translated from zkl using my own ploting functions.
\\ 4/15/16 aev
Line 1,091 ⟶ 1,945:
Spiralz(640,2,3.0,3.0,128); \\Spiralz1.png
}
</langsyntaxhighlight>
 
{{Output}}
Line 1,099 ⟶ 1,953:
*** Spiralz: size=640 lim=2 ai=3.000 di=3.000 lim2=128
</pre>
 
=={{header|Perl}}==
Click Start button to run, then runs continuously.
It takes just a little over four minutes to complete a full 360 degree cycle.
<syntaxhighlight lang="perl">
#!/usr/bin/perl
 
use strict; # https://rosettacode.org/wiki/Polyspiral
use warnings;
use Tk;
use List::Util qw( min );
 
my $size = 500;
my ($width, $height, $x, $y, $dist);
my $angleinc = 0;
my $active = 0;
my $wait = 1000 / 30;
my $radian = 90 / atan2 1, 0;
 
my $mw = MainWindow->new;
$mw->title( 'Polyspiral' );
my $c = $mw->Canvas( -width => $size, -height => $size,
-relief => 'raised', -borderwidth => 2,
)->pack(-fill => 'both', -expand => 1);
$mw->bind('<Configure>' => sub { $width = $c->width; $height = $c->height;
$dist = min($width, $height) ** 2 / 4 } );
$mw->Button(-text => $_->[0], -command => $_->[1],
)->pack(-side => 'right') for
[ Exit => sub {$mw->destroy} ],
[ 'Start / Pause' => sub { $active ^= 1; step() } ];
 
MainLoop;
-M $0 < 0 and exec $0;
 
sub step
{
$active or return;
my @pts = ($x = $width >> 1, $y = $height >> 1);
my $length = 5;
my $angle = $angleinc;
$angleinc += 0.05 / $radian;
while( ($x - $width / 2)**2 + ($y - $height / 2)**2 < $dist && @pts < 300 )
{
push @pts, $x, $y;
$x += $length * cos($angle);
$y += $length * sin($angle);
$length += 3;
$angle += $angleinc;
}
$c->delete('all');
$c->createLine( @pts );
$mw->after($wait => \&step);
}</syntaxhighlight>
 
=={{header|Phix}}==
Line 1,104 ⟶ 2,011:
'M' toggles "mod360", which inverts the angle every 360/2PI or so, since sin/cos
accept arguments in radians not degrees (and mod 2*PI changes nothing), producing
non-true polyspirals, but quite interesting nevertheless.
You can run this online [http://phix.x10.mx/p2js/Polyspiral.htm here].
{{libheader|pGUI}}
{{libheader|Phix/pGUI}}
<lang Phix>--
{{libheader|Phix/online}}
-- demo\rosetta\Polyspiral.exw
<!--<syntaxhighlight lang="phix">(phixonline)-->
--
<span style="color: #000080;font-style:italic;">--
include pGUI.e
-- demo\rosetta\Polyspiral.exw
-- ===========================
--
-- Space toggles the timer, '+' increases speed (up to 100 FPS), '-' decreases speed
-- 'M' toggles "mod360", which inverts the angle every 360/2PI or so, since sin/cos
-- accept arguments in radians not degrees (and mod 2*PI changes nothing), producing
-- non-true polyspirals, but quite interesting nevertheless.
--</span>
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">TITLE</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"Polyspiral"</span>
<span style="color: #008080;">include</span> <span style="color: #000000;">pGUI</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span>
<span style="color: #004080;">Ihandle</span> <span style="color: #000000;">dlg</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">canvas</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">timer</span>
<span style="color: #004080;">cdCanvas</span> <span style="color: #000000;">cddbuffer</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">cdcanvas</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">incr</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
<span style="color: #004080;">bool</span> <span style="color: #000000;">mod360</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">false</span>
<span style="color: #008080;">procedure</span> <span style="color: #000000;">Polyspiral</span><span style="color: #0000FF;">(</span><span style="color: #004080;">atom</span> <span style="color: #000000;">x1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">y1</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">angle</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">incr</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">len</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">5</span>
<span style="color: #000000;">incr</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">0.05</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">mod360</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">incr</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">mod</span><span style="color: #0000FF;">(</span><span style="color: #000000;">incr</span><span style="color: #0000FF;">,</span><span style="color: #000000;">360</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">150</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">x2</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">x1</span> <span style="color: #0000FF;">+</span> <span style="color: #7060A8;">cos</span><span style="color: #0000FF;">(</span><span style="color: #000000;">angle</span><span style="color: #0000FF;">)*</span><span style="color: #000000;">len</span><span style="color: #0000FF;">,</span>
<span style="color: #000000;">y2</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">y1</span> <span style="color: #0000FF;">+</span> <span style="color: #7060A8;">sin</span><span style="color: #0000FF;">(</span><span style="color: #000000;">angle</span><span style="color: #0000FF;">)*</span><span style="color: #000000;">len</span>
<span style="color: #7060A8;">cdCanvasSetForeground</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cddbuffer</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">*</span><span style="color: #000000;">#200</span><span style="color: #0000FF;">+</span><span style="color: #000000;">i</span><span style="color: #0000FF;">*</span><span style="color: #000000;">#40</span><span style="color: #0000FF;">+</span><span style="color: #000000;">i</span><span style="color: #0000FF;">*</span><span style="color: #000000;">#10</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">cdCanvasLine</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cddbuffer</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">x1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">y1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">x2</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">y2</span><span style="color: #0000FF;">)</span>
<span style="color: #0000FF;">{</span><span style="color: #000000;">x1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">y1</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">x2</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">y2</span><span style="color: #0000FF;">}</span>
<span style="color: #000000;">len</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">3</span>
<span style="color: #000000;">angle</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">incr</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">mod360</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">angle</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">mod</span><span style="color: #0000FF;">(</span><span style="color: #000000;">angle</span><span style="color: #0000FF;">,</span><span style="color: #000000;">360</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">redraw_cb</span><span style="color: #0000FF;">(</span><span style="color: #004080;">Ihandle</span> <span style="color: #000080;font-style:italic;">/*ih*/</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">integer</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">w</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">h</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">IupGetIntInt</span><span style="color: #0000FF;">(</span><span style="color: #000000;">canvas</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"DRAWSIZE"</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">cdCanvasActivate</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cddbuffer</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">cdCanvasClear</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cddbuffer</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">Polyspiral</span><span style="color: #0000FF;">(</span><span style="color: #000000;">w</span><span style="color: #0000FF;">/</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">h</span><span style="color: #0000FF;">/</span><span style="color: #000000;">2</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">cdCanvasFlush</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cddbuffer</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">ms</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">IupGetInt</span><span style="color: #0000FF;">(</span><span style="color: #000000;">timer</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"TIME"</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">IupSetStrAttribute</span><span style="color: #0000FF;">(</span><span style="color: #000000;">dlg</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"TITLE"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"%s (timer=%d [%g FPS], angle %3.2f%s)"</span><span style="color: #0000FF;">,</span>
<span style="color: #0000FF;">{</span><span style="color: #000000;">TITLE</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ms</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1000</span><span style="color: #0000FF;">/</span><span style="color: #000000;">ms</span><span style="color: #0000FF;">,</span><span style="color: #000000;">incr</span><span style="color: #0000FF;">,</span><span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">mod360</span><span style="color: #0000FF;">?</span><span style="color: #008000;">" (mod360)"</span><span style="color: #0000FF;">:</span><span style="color: #008000;">""</span><span style="color: #0000FF;">)})</span>
<span style="color: #008080;">return</span> <span style="color: #004600;">IUP_DEFAULT</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">timer_cb</span><span style="color: #0000FF;">(</span><span style="color: #004080;">Ihandle</span> <span style="color: #000080;font-style:italic;">/*timer*/</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">IupUpdate</span><span style="color: #0000FF;">(</span><span style="color: #000000;">canvas</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">return</span> <span style="color: #004600;">IUP_IGNORE</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">map_cb</span><span style="color: #0000FF;">(</span><span style="color: #004080;">Ihandle</span> <span style="color: #000000;">canvas</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">cdcanvas</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">cdCreateCanvas</span><span style="color: #0000FF;">(</span><span style="color: #004600;">CD_IUP</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">canvas</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">cddbuffer</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">cdCreateCanvas</span><span style="color: #0000FF;">(</span><span style="color: #004600;">CD_DBUFFER</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">cdcanvas</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">cdCanvasSetBackground</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cddbuffer</span><span style="color: #0000FF;">,</span> <span style="color: #004600;">CD_WHITE</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">cdCanvasSetForeground</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cddbuffer</span><span style="color: #0000FF;">,</span> <span style="color: #004600;">CD_GRAY</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">return</span> <span style="color: #004600;">IUP_DEFAULT</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">key_cb</span><span style="color: #0000FF;">(</span><span style="color: #004080;">Ihandle</span> <span style="color: #000080;font-style:italic;">/*ih*/</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">atom</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">=</span><span style="color: #004600;">K_ESC</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #004600;">IUP_CLOSE</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">=</span><span style="color: #008000;">' '</span> <span style="color: #008080;">then</span>
<span style="color: #7060A8;">IupSetInt</span><span style="color: #0000FF;">(</span><span style="color: #000000;">timer</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"RUN"</span><span style="color: #0000FF;">,</span><span style="color: #008080;">not</span> <span style="color: #7060A8;">IupGetInt</span><span style="color: #0000FF;">(</span><span style="color: #000000;">timer</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"RUN"</span><span style="color: #0000FF;">))</span>
<span style="color: #008080;">elsif</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">c</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"+-"</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
<span style="color: #7060A8;">IupSetInt</span><span style="color: #0000FF;">(</span><span style="color: #000000;">timer</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"RUN"</span><span style="color: #0000FF;">,</span><span style="color: #004600;">false</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">c</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">-(</span><span style="color: #008000;">','</span><span style="color: #0000FF;">-</span><span style="color: #000000;">c</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- ('+' ==&gt; +1, '-' ==&gt; -1)</span>
<span style="color: #7060A8;">IupSetInt</span><span style="color: #0000FF;">(</span><span style="color: #000000;">timer</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"TIME"</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">max</span><span style="color: #0000FF;">(</span><span style="color: #000000;">10</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">IupGetInt</span><span style="color: #0000FF;">(</span><span style="color: #000000;">timer</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"TIME"</span><span style="color: #0000FF;">)+</span><span style="color: #000000;">c</span><span style="color: #0000FF;">*</span><span style="color: #000000;">10</span><span style="color: #0000FF;">))</span>
<span style="color: #7060A8;">IupSetInt</span><span style="color: #0000FF;">(</span><span style="color: #000000;">timer</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"RUN"</span><span style="color: #0000FF;">,</span><span style="color: #004600;">true</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">elsif</span> <span style="color: #7060A8;">upper</span><span style="color: #0000FF;">(</span><span style="color: #000000;">c</span><span style="color: #0000FF;">)=</span><span style="color: #008000;">'M'</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">mod360</span> <span style="color: #0000FF;">=</span> <span style="color: #008080;">not</span> <span style="color: #000000;">mod360</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">return</span> <span style="color: #004600;">IUP_CONTINUE</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #7060A8;">IupOpen</span><span style="color: #0000FF;">()</span>
<span style="color: #000000;">canvas</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">IupCanvas</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"RASTERSIZE=640x640"</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">IupSetCallbacks</span><span style="color: #0000FF;">(</span><span style="color: #000000;">canvas</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">{</span><span style="color: #008000;">"MAP_CB"</span><span style="color: #0000FF;">,</span> <span style="color: #7060A8;">Icallback</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"map_cb"</span><span style="color: #0000FF;">),</span>
<span style="color: #008000;">"ACTION"</span><span style="color: #0000FF;">,</span> <span style="color: #7060A8;">Icallback</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"redraw_cb"</span><span style="color: #0000FF;">)})</span>
<span style="color: #000000;">timer</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">IupTimer</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">Icallback</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"timer_cb"</span><span style="color: #0000FF;">),</span> <span style="color: #000000;">20</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">dlg</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">IupDialog</span><span style="color: #0000FF;">(</span><span style="color: #000000;">canvas</span><span style="color: #0000FF;">,</span><span style="color: #008000;">`TITLE="%s"`</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">TITLE</span><span style="color: #0000FF;">})</span>
<span style="color: #7060A8;">IupSetCallback</span><span style="color: #0000FF;">(</span><span style="color: #000000;">dlg</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"KEY_CB"</span><span style="color: #0000FF;">,</span> <span style="color: #7060A8;">Icallback</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"key_cb"</span><span style="color: #0000FF;">))</span>
<span style="color: #7060A8;">IupShow</span><span style="color: #0000FF;">(</span><span style="color: #000000;">dlg</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">IupSetAttribute</span><span style="color: #0000FF;">(</span><span style="color: #000000;">canvas</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"RASTERSIZE"</span><span style="color: #0000FF;">,</span> <span style="color: #004600;">NULL</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #7060A8;">platform</span><span style="color: #0000FF;">()!=</span><span style="color: #004600;">JS</span> <span style="color: #008080;">then</span>
<span style="color: #7060A8;">IupMainLoop</span><span style="color: #0000FF;">()</span>
<span style="color: #7060A8;">IupClose</span><span style="color: #0000FF;">()</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<!--</syntaxhighlight>-->
 
=={{header|Processing}}==
Ihandle dlg, canvas, timer
{{trans|C}}
cdCanvas cddbuffer, cdcanvas
<syntaxhighlight lang="java">
//Aamrun, 2nd July 2022
 
int incr = 0, angle, i, length;
constant TITLE = "Polyspiral"
float x,y,x1,y1;
double factor = PI/180;
 
void setup() {
atom incr = 0
size(1000, 1000);
bool mod360 = false
stroke(255);
 
}
procedure Polyspiral(atom x1, y1)
atom angle = incr
integer len = 5
incr += 0.05
if mod360 then
incr = mod(incr,360)
end if
for i=1 to 150 do
atom x2 = x1 + cos(angle)*len
atom y2 = y1 + sin(angle)*len
cdCanvasSetForeground(cddbuffer, i*#200+i*#40+i*#10)
cdCanvasLine(cddbuffer, x1, y1, x2, y2)
{x1, y1} = {x2, y2}
len += 3
angle += incr
if mod360 then
angle = mod(angle,360)
end if
end for
end procedure
 
void draw() {
function redraw_cb(Ihandle /*ih*/, integer /*posx*/, integer /*posy*/)
background(51);
integer {w, h} = IupGetIntInt(canvas, "DRAWSIZE")
incr = (incr + 5)%360;
cdCanvasActivate(cddbuffer)
cdCanvasClear(cddbuffer)
Polyspiral(w/2,x = hwidth/2);
y = height/2;
cdCanvasFlush(cddbuffer)
integer ms = IupGetInt(timer,"TIME")
length = 5;
IupSetStrAttribute(dlg, "TITLE", "%s (timer=%d [%g FPS], angle %3.2f%s)",
angle = incr;
{TITLE,ms,1000/ms,incr,iff(mod360?" (mod360)":"")})
return IUP_DEFAULT
for(i=1;i<=150;i++){
end function
x1 = x + (float)(length*Math.cos(factor*angle));
y1 = y + (float)(length*Math.sin(factor*angle));
line(x,y,x1,y1);
length += 3;
angle = (angle + incr)%360;
x = x1;
y = y1;
}
}
</syntaxhighlight>
 
=={{header|Python}}==
function timer_cb(Ihandle /*ih*/)
{{libheader|Pygame}}
IupUpdate(canvas)
<syntaxhighlight lang="python">import math
return IUP_IGNORE
end function
 
import pygame
function map_cb(Ihandle ih)
from pygame.locals import *
cdcanvas = cdCreateCanvas(CD_IUP, ih)
cddbuffer = cdCreateCanvas(CD_DBUFFER, cdcanvas)
cdCanvasSetBackground(cddbuffer, CD_WHITE)
cdCanvasSetForeground(cddbuffer, CD_GRAY)
return IUP_DEFAULT
end function
 
pygame.init()
function esc_close(Ihandle /*ih*/, atom c)
screen = pygame.display.set_mode((1024, 600))
if c=K_ESC then return IUP_CLOSE end if
if c=' ' then
IupSetInt(timer,"RUN",not IupGetInt(timer,"RUN"))
elsif find(c,"+-") then
-- ('+' increases speed, by decreasing TIME)
IupSetInt(timer,"TIME",max(10,IupGetInt(timer,"TIME")-(','-c)*10))
IupSetInt(timer,"RUN",0)
IupSetInt(timer,"RUN",1)
elsif upper(c)='M' then
mod360 = not mod360
end if
return IUP_CONTINUE
end function
 
pygame.display.set_caption("Polyspiral")
procedure main()
IupOpen()
 
incr = 0
canvas = IupCanvas(NULL)
IupSetAttribute(canvas, "RASTERSIZE", "640x640")
IupSetCallback(canvas, "MAP_CB", Icallback("map_cb"))
IupSetCallback(canvas, "ACTION", Icallback("redraw_cb"))
 
running = True
timer = IupTimer(Icallback("timer_cb"), 20)
 
while running:
dlg = IupDialog(canvas)
pygame.time.Clock().tick(60)
IupSetAttribute(dlg, "TITLE", TITLE)
for event in pygame.event.get():
IupSetCallback(dlg, "K_ANY", Icallback("esc_close"))
if event.type==QUIT:
running = False
break
 
incr = (incr + 0.05) % 360
IupShow(dlg)
x1 = pygame.display.Info().current_w / 2
IupSetAttribute(canvas, "RASTERSIZE", NULL)
y1 = pygame.display.Info().current_h / 2
IupMainLoop()
length = 5
IupClose()
angle = incr
end procedure
 
screen.fill((255,255,255))
main()</lang>
 
for i in range(1,151):
x2 = x1 + math.cos(angle) * length
y2 = y1 + math.sin(angle) * length
pygame.draw.line(screen, (255,0,0), (x1, y1), (x2, y2), 1)
# pygame.draw.aaline(screen, (255,0,0), (x1, y1), (x2, y2)) # Anti-Aliased
x1, y1 = x2, y2
length += 3
angle = (angle + incr) % 360
 
pygame.display.flip()
</syntaxhighlight>
 
=={{header|Quackery}}==
 
<syntaxhighlight lang="Quackery"> [ $ "turtleduck.qky" loadfile ] now!
 
[ 1000 * time +
[ dup time < until ]
drop ] is ms ( n --> )
 
[ turtle 0 frames
3601 times
[ clear
i^ 3600
1000 times
[ i^ 1+ 1 walk
2dup turn ]
2drop
frame
10 ms ] ] is polyspiral ( --> )</syntaxhighlight>
 
{{out}}
 
https://youtu.be/qZemJJBUekM
 
 
=={{header|Racket}}==
Uses the *universe* animation
 
<syntaxhighlight lang="racket">#lang racket
 
(require 2htdp/universe pict racket/draw)
 
(define ((polyspiral width height segment-length-increment n-segments) tick/s/28)
(define turn-angle (degrees->radians (/ tick/s/28 8)))
(pict->bitmap
(dc (λ (dc dx dy)
(define old-brush (send dc get-brush))
(define old-pen (send dc get-pen))
(define path (new dc-path%))
(define x (/ width #i2))
(define y (/ height #i2))
(send path move-to x y)
(for/fold ((x x) (y y) (l segment-length-increment) (a #i0))
((seg n-segments))
(define x′ (+ x (* l (cos a))))
(define y′ (+ y (* l (sin a))))
(send path line-to x y)
(values x′ y′ (+ l segment-length-increment) (+ a turn-angle)))
(send dc draw-path path dx dy)
(send* dc (set-brush old-brush) (set-pen old-pen)))
width height)))
 
(animate (polyspiral 400 400 2 1000))</syntaxhighlight>
 
See the output for yourself!
 
=={{header|Raku}}==
(formerly Perl 6)
{{works with|Rakudo|2018.09}}
 
===SVG "pseudo-animation"===
Sort of an ersatz animation. Write updates to a svg file, most modern viewers will update as the content changes.
 
<syntaxhighlight lang="raku" line>use SVG;
my $w = 600;
my $h = 600;
 
for 3..33 -> $a {
my $angle = $a/τ;
my $x1 = $w/2;
my $y1 = $h/2;
my @lines;
 
for 1..144 {
my $length = 3 * $_;
my ($x2, $y2) = ($x1, $y1) «+« |cis($angle * $_).reals».round(.01) »*» $length ;
@lines.push: 'line' => [:x1($x1.clone), :y1($y1.clone), :x2($x2.clone), :y2($y2.clone),
:style("stroke:rgb({hsv2rgb(($_*5 % 360)/360,1,1).join: ','})")];
($x1, $y1) = $x2, $y2;
}
 
my $fname = "./polyspiral-perl6.svg".IO.open(:w);
$fname.say( SVG.serialize(
svg => [
width => $w, height => $h, style => 'stroke:rgb(0,0,0)',
:rect[:width<100%>, :height<100%>, :fill<black>],
|@lines,
],)
);
$fname.close;
sleep .15;
}
 
sub hsv2rgb ( $h, $s, $v ){ # inputs normalized 0-1
my $c = $v * $s;
my $x = $c * (1 - abs( (($h*6) % 2) - 1 ) );
my $m = $v - $c;
my ($r, $g, $b) = do given $h {
when 0..^(1/6) { $c, $x, 0 }
when 1/6..^(1/3) { $x, $c, 0 }
when 1/3..^(1/2) { 0, $c, $x }
when 1/2..^(2/3) { 0, $x, $c }
when 2/3..^(5/6) { $x, 0, $c }
when 5/6..1 { $c, 0, $x }
}
( $r, $g, $b ).map: ((*+$m) * 255).Int
}</syntaxhighlight>
{{out}}
See [https://github.com/thundergnat/rc/blob/master/img/polyspiral-perl6.gif polyspiral-perl6.gif] (offsite animated gif image)
 
===SDL full animation===
Uses the same basic algorithm but fully animated. Use the up / down arrow keys to speed up / slow down the update speed. Use PgUp / PgDn keys to increment / decrement animation speed by large amounts. Use left / right arrow keys to reverse the "direction" of angle change. Press Space bar to toggle animation / reset to minimum speed. Left Control key to toggle stationary / rotating center. Use + / - keys to add remove line segments.
 
<syntaxhighlight lang="raku" line>use SDL2::Raw;
 
my $width = 900;
my $height = 900;
 
SDL_Init(VIDEO);
 
my $window = SDL_CreateWindow(
'Polyspiral',
SDL_WINDOWPOS_CENTERED_MASK,
SDL_WINDOWPOS_CENTERED_MASK,
$width, $height,
RESIZABLE
);
 
my $render = SDL_CreateRenderer($window, -1, ACCELERATED +| PRESENTVSYNC);
 
my $event = SDL_Event.new;
 
enum KEY_CODES (
K_UP => 82,
K_DOWN => 81,
K_LEFT => 80,
K_RIGHT => 79,
K_SPACE => 44,
K_PGUP => 75,
K_PGDN => 78,
K_LCTRL => 224,
K_PLUS => 87,
K_MINUS => 86,
K_SPLUS => 46,
K_SMINUS => 45,
);
 
my $angle = 0;
my $lines = 240;
my @rgb = palette($lines);
my ($x1, $y1);
my $dir = 1;
my $rot = 0;
my $incr = .0001/π;
my $step = $incr*70;
 
main: loop {
while SDL_PollEvent($event) {
my $casted_event = SDL_CastEvent($event);
given $casted_event {
when *.type == QUIT { last main }
when *.type == KEYDOWN {
if KEY_CODES(.scancode) -> $comm {
given $comm {
when 'K_LEFT' { $dir = $rot ?? 1 !! -1 }
when 'K_RIGHT' { $dir = $rot ?? -1 !! 1 }
when 'K_UP' { $step += $incr }
when 'K_DOWN' { $step -= $incr if $step > $incr }
when 'K_PGUP' { $step += $incr*50 }
when 'K_PGDN' { $step -= $incr*50; $step = $step < $incr ?? $incr !! $step }
when 'K_SPACE' { $step = $step ?? 0 !! $incr }
when 'K_LCTRL' { $rot = $rot ?? 0 !! -1; $dir *= -1 }
when 'K_PLUS' { $lines = ($lines + 5) min 360; @rgb = palette($lines) }
when 'K_SPLUS' { $lines = ($lines + 5) min 360; @rgb = palette($lines) }
when 'K_MINUS' { $lines = ($lines - 5) max 60; @rgb = palette($lines) }
when 'K_SMINUS' { $lines = ($lines - 5) max 60; @rgb = palette($lines) }
}
}
#say .scancode; # unknown key pressed
}
when *.type == WINDOWEVENT {
if .event == 5 {
$width = .data1;
$height = .data2;
}
}
}
}
 
$angle = ($angle + $dir * $step) % τ;
($x1, $y1) = $width div 2, $height div 2;
my $dim = $width min $height;
my $scale = (2 + .33 * abs(π - $angle)) * $dim / $lines;
$scale *= ($angle > π) ?? (1 - $angle/τ) !! $angle/τ;
$scale max= $dim/$lines/$lines;
for ^$lines {
my $length = $scale + $scale * $_;
my ($x2, $y2) = ($x1, $y1) «+« cis(($angle * $rot * $lines) + $angle * $_).reals »*» $length;
SDL_SetRenderDrawColor($render, |@rgb[$_], 255);
SDL_RenderDrawLine($render, |($x1, $y1, $x2, $y2)».round(1));
($x1, $y1) = $x2, $y2;
}
@rgb.=rotate($lines/60);
SDL_RenderPresent($render);
SDL_SetRenderDrawColor($render, 0, 0, 0, 0);
SDL_RenderClear($render);
}
 
SDL_Quit();
 
sub palette ($l) { (^$l).map: { hsv2rgb(($_ * 360/$l % 360)/360, 1, 1).list } };
 
sub hsv2rgb ( $h, $s, $v ){ # inputs normalized 0-1
my $c = $v * $s;
my $x = $c * (1 - abs( (($h*6) % 2) - 1 ) );
my $m = $v - $c;
my ($r, $g, $b) = do given $h {
when 0..^(1/6) { $c, $x, 0 }
when 1/6..^(1/3) { $x, $c, 0 }
when 1/3..^(1/2) { 0, $c, $x }
when 1/2..^(2/3) { 0, $x, $c }
when 2/3..^(5/6) { $x, 0, $c }
when 5/6..1 { $c, 0, $x }
}
( $r, $g, $b ).map: ((*+$m) * 255).Int
}</syntaxhighlight>
 
=={{header|Ring}}==
<syntaxhighlight lang="ring">
# Project : Polyspiral
 
load "guilib.ring"
 
paint = null
incr = 1
x1 = 1000
y1 = 1080
angle = 10
length = 10
 
new qapp
{
win1 = new qwidget() {
setwindowtitle("")
setgeometry(10,10,1000,1080)
label1 = new qlabel(win1) {
setgeometry(10,10,1000,1080)
settext("")
}
new qpushbutton(win1) {
setgeometry(150,30,100,30)
settext("draw")
setclickevent("draw()")
}
show()
}
exec()
}
 
func draw
p1 = new qpicture()
color = new qcolor() {
setrgb(0,0,255,255)
}
pen = new qpen() {
setcolor(color)
setwidth(1)
}
paint = new qpainter() {
begin(p1)
setpen(pen)
for i = 1 to 150
x2 = x1 + cos(angle) * length
y2 = y1 + sin(angle) * length
drawline(x1, y1, x2, y2)
x1 = x2
y1 = y2
length = length + 3
angle = (angle + incr) % 360
next
 
endpaint()
}
label1 { setpicture(p1) show() }
</syntaxhighlight>
Output:
 
https://www.dropbox.com/s/zwnpimbndekbd5k/PolySpiral.jpg?dl=0
 
=={{header|Scala}}==
===Java Swing Interoperability===
<syntaxhighlight lang="scala">import java.awt._
import java.awt.event.ActionEvent
 
import javax.swing._
 
object PolySpiral extends App {
 
SwingUtilities.invokeLater(() =>
new JFrame("PolySpiral") {
 
class PolySpiral extends JPanel {
private var inc = 0.0
 
override def paintComponent(gg: Graphics): Unit = {
val g = gg.asInstanceOf[Graphics2D]
def drawSpiral(g: Graphics2D, l: Int, angleIncrement: Double): Unit = {
var len = l
var (x1, y1) = (getWidth / 2d, getHeight / 2d)
var angle = angleIncrement
for (i <- 0 until 150) {
g.setColor(Color.getHSBColor(i / 150f, 1.0f, 1.0f))
val x2 = x1 + math.cos(angle) * len
val y2 = y1 - math.sin(angle) * len
g.drawLine(x1.toInt, y1.toInt, x2.toInt, y2.toInt)
x1 = x2
y1 = y2
len += 3
angle = (angle + angleIncrement) % (math.Pi * 2)
}
}
 
super.paintComponent(gg)
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON)
drawSpiral(g, 5, math.toRadians(inc))
}
 
setBackground(Color.white)
setPreferredSize(new Dimension(640, 640))
 
new Timer(40, (_: ActionEvent) => {
inc = (inc + 0.05) % 360
repaint()
}).start()
}
 
add(new PolySpiral, BorderLayout.CENTER)
pack()
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE)
setLocationRelativeTo(null)
setResizable(true)
setVisible(true)
}
)
 
}</syntaxhighlight>
 
=={{header|SPL}}==
<langsyntaxhighlight lang="spl">width,height = #.scrsize()
#.angle(#.degrees)
#.scroff()
Line 1,224 ⟶ 2,562:
<
#.scr()
<</langsyntaxhighlight>
 
=={{header|SVG}}==
 
Demo: [https://codepen.io/shephero/full/xxbaWXb codepen]
 
It's possible to render an animated polyspiral completely declaratively, using SVG/SMIL.
 
It requires building up layers, animated over a rotation transformation. This is verbose, so the code below has been truncated, and the [https://codepen.io/shephero/full/xxbaWXb demo] uses another language ([https://codepen.io/shephero/full/xxbaWXb Pug]) to generate the source.
 
<syntaxhighlight lang="html">
<svg viewBox="0 0 100 100" stroke="#000" stroke-width="0.3">
<g>
<line x1="50" y1="50" x2="54" y2="50"></line>
<animateTransform attributeName="transform" type="rotate" from="-120 50 50" to="240 50 50" dur="2400s" repeatCount="indefinite"></animateTransform>
<g>
<line x1="54" y1="50" x2="58.16" y2="50"></line>
<animateTransform attributeName="transform" type="rotate" from="-120 54 50" to="240 54 50" dur="2400s" repeatCount="indefinite"></animateTransform>
<g>
<line x1="58.16" y1="50" x2="62.48639" y2="50"></line>
<animateTransform attributeName="transform" type="rotate" dur="2400s" repeatCount="indefinite" to="240 58.16 50" from="-120 58.16 50"></animateTransform>
 
<!-- ad nauseam -->
 
</g>
</g>
</g>
</svg>
</syntaxhighlight>
 
=={{header|Wren}}==
{{trans|Kotlin}}
{{libheader|DOME}}
<syntaxhighlight lang="wren">import "graphics" for Canvas, Color
import "dome" for Window
import "math" for Math
 
var Radians = Fn.new { |d| d * Num.pi / 180 }
 
class Polyspiral {
construct new(width, height) {
Window.title = "Polyspiral"
Window.resize(width, height)
Canvas.resize(width, height)
_w = width
_h = height
_inc = 0
}
 
init() {
drawSpiral(5, Radians.call(_inc))
}
 
drawSpiral(length, angleIncrement) {
Canvas.cls(Color.white)
var x1 = _w / 2
var y1 = _h / 2
var len = length
var angle = angleIncrement
for (i in 0...150) {
var col = Color.hsv(i / 150 * 360, 1, 1)
var x2 = x1 + Math.cos(angle) * len
var y2 = y1 - Math.sin(angle) * len
Canvas.line(x1.truncate, y1.truncate, x2.truncate, y2.truncate, col)
x1 = x2
y1 = y2
len = len + 3
angle = (angle + angleIncrement) % (Num.pi * 2)
}
}
 
update() {
_inc = (_inc + 0.05) % 360
}
 
draw(alpha) {
drawSpiral(5, Radians.call(_inc))
}
}
 
var Game = Polyspiral.new(640, 640)</syntaxhighlight>
 
=={{header|XPL0}}==
There is no need for the MOD operator shown in the pseudo code for XPL0's
trig functions because they handle argument angles outside 0 to 360
degrees (2 Pi radians).
<syntaxhighlight lang="xpl0">
def Width=640., Height=480.;
def Deg2Rad = 3.141592654/180.;
real Incr, Angle, Length, X, Y, X1, Y1;
int N;
[SetVid($101); \VESA 640x480x8 graphics
Incr:= 0.;
repeat Incr:= Incr+1.;
X:= Width/2.; Y:= Height/2.;
Move(fix(X), fix(Y));
Length:= 5.;
Angle:= Incr;
for N:= 1 to 150 do
[X1:= X + Length*Cos(Angle*Deg2Rad);
Y1:= Y + Length*Sin(Angle*Deg2Rad);
Line(fix(X1), fix(Y1), N+16);
X:= X1; Y:= Y1;
Length:= Length+3.;
Angle:= Angle+Incr;
];
DelayUS(83_333);
Clear;
until KeyHit;
]</syntaxhighlight>
 
{{out}}
<pre>
https://www.youtube.com/watch?v=p1M2VVY3abM
The actual program looks better and runs under MS-DOS, Windows (with EXPL) and RPi.
</pre>
 
 
=={{header|Yabasic}}==
{{trans|Python}}
<syntaxhighlight lang="yabasic">w = 1024 : h = 600
open window w, h
color 255,0,0
incr = 0 : twopi = 2 * pi
while true
incr = mod(incr + 0.05, twopi)
x1 = w / 2
y1 = h / 2
length = 5
angle = incr
clear window
for i = 1 to 151
x2 = x1 + cos(angle) * length
y2 = y1 + sin(angle) * length
line x1, y1, x2, y2
x1 = x2 : y1 = y2
length = length + 3
angle = mod(angle + incr, twopi)
next
pause 1
end while</syntaxhighlight>
 
=={{header|Zig}}==
{{works with|Zig|0.11.0}} {{works with|raylib|4.6-dev}}
{{libheader|raylib}}
<syntaxhighlight lang="zig">
const std = @import("std");
const rl = @cImport({
@cInclude("raylib.h");
@cInclude("raymath.h");
});
 
const SCREEN_WIDTH = 640;
const SCREEN_HEIGHT = 480;
var incr: f32 = 0;
 
pub fn main() void {
rl.SetConfigFlags(rl.FLAG_WINDOW_RESIZABLE | rl.FLAG_VSYNC_HINT);
rl.SetTargetFPS(60);
 
rl.InitWindow(SCREEN_WIDTH, SCREEN_HEIGHT, "Polyspiral");
 
while (!rl.WindowShouldClose())
updateDrawFrame();
 
rl.CloseWindow();
}
 
fn updateDrawFrame() void {
rl.BeginDrawing();
 
rl.ClearBackground(rl.BLACK);
 
incr = @mod(incr + 0.001, 360);
 
drawSpiral(5, std.math.degreesToRadians(f32, incr));
 
rl.EndDrawing();
}
 
fn drawSpiral(_length: f32, _angle: f32) void {
const width = rl.GetScreenWidth();
const height = rl.GetScreenHeight();
var point0 = rl.Vector2{ .x = @as(f32, @floatFromInt(width)) / 2, .y = @as(f32, @floatFromInt(height)) / 2 };
var length = _length;
var angle = _angle;
for (0..150) |_| {
const line_vector = rl.Vector2Rotate(rl.Vector2{ .x = length, .y = 0 }, angle);
const point1 = rl.Vector2Add(point0, line_vector);
rl.DrawLineV(point0, point1, rl.LIME);
point0 = point1;
length += 3;
angle += incr;
angle = @mod(angle, comptime @as(f32, (2.0 * std.math.pi)));
}
}
</syntaxhighlight>
 
=={{header|zkl}}==
Line 1,231 ⟶ 2,769:
 
Uses the PPM class from http://rosettacode.org/wiki/Bitmap/Bresenham%27s_line_algorithm#zkl
<langsyntaxhighlight lang="zkl">w,h:=640,640;
bitmap:=PPM(w,h,0xFF|FF|FF); // White background
angleIncrement:=(3.0).toRad();
Line 1,249 ⟶ 2,787:
angleIncrement=(angleIncrement + 0.05);
Atomic.sleep(3);
}</langsyntaxhighlight>
9,486

edits