Loading web-font TeX/Main/Regular

Rounded Pentagram: Pseudo Fourier Series Animation Using Gnuplot

Monday, July 19, 2021

Curve gnuplot YouTube

t f B! P L

YouTube

 

Equations of the curve

\begin{cases} x(t)=2\sin 2t - \cos 3t\\ y(t)=\sin 3t - 2 \cos 2t \end{cases}

Simulation [gnuplot]

Source code (PLT file)

reset
set angle degrees
#=================== Parameter ====================
# Parameters in drawing
psPoint = 2 # ps = point size
lwTrajectory = 2 # lw = line width
lcPoint = 6 # lc = line color
numPNG = 0
LOOP = 3
DEG_DIV = 1.0 # Resolution of degree, increase by 1/DEG_DIV
roundNum = 2
# Select terminal type
qtMode = 1 # ==1: qt (simulator) / !=1: png (output images for making video)
print sprintf("[MODE] %s", (qtMode==1 ? 'Simulate in Qt window' :'Output PNG images'))
#=================== Function ====================
# Parametric equations of a curve
x(t) = 2*sin(2*t)-cos(3*t)
y(t) = sin(3*t)-2*cos(2*t)
# Show the value of the parameter t
showT(t) = sprintf("{/:Italic t} = %3.1f deg", t)
#=================== Setting ====================
if(qtMode==1){
set term qt size 720, 720 font 'Times'
} else {
set term pngcairo size 720, 720 font 'Times'
folderName = 'png'
system sprintf('mkdir %s', folderName)
}
unset key
set grid
set size ratio -1
set xlabel '{/:Italic x}' font ', 20'
set ylabel '{/:Italic y}' font ', 20'
set tics font ', 18'
# Round off to the i decimal place.
round(x, i) = 1 / (10.**(i+1)) * floor(x * (10.**(i+1)) + 0.5)
#=================== Calculation ====================
# Output: "draw_trajectory.txt" is need for plotting the curve.
dataTrajectory = 'draw_trajectory.txt'
print sprintf('Start outputting %s ...', dataTrajectory)
set print dataTrajectory
# Write items and parameters in outputfile
print sprintf("# %s", dataTrajectory)
print sprintf('# DEG_DIV=%d', DEG_DIV)
print '# t / x / y'
# Calculate and output the trajectory of the curve
do for[i=0:360*DEG_DIV:1]{
t = i/DEG_DIV
print round(t, roundNum), round(x(t), roundNum), round(y(t), roundNum)
}
unset print
print sprintf('Finish!')
#=================== Plot ====================
if(qtMode == 1) {
print "Start simulation"
} else {
print sprintf('Start outputting %d images ...', LOOP*(1+360*DEG_DIV))
}
plotRange = 4
end(loop, i) = (loop>0) ? 360*DEG_DIV : i
do for [n=0:LOOP-1:1]{
do for [i=0:360*DEG_DIV:1]{
if(qtMode != 1) {
set output sprintf("%s/img_%04d.png", folderName, numPNG)
numPNG = numPNG + 1
}
# Get the value of time from dataTrajectory
set yrange [*:*] # This command enables to remove restrictions on the range of the stats command.
stats dataTrajectory using 1 every ::i::i nooutput
theta = STATS_max
set title showT(theta) left offset screen -0.07, -0.01 font ', 20'
plot[-plotRange:plotRange][-plotRange:plotRange] \
dataTrajectory using 2:3 every ::i::i with p ps psPoint pt 7 lc lcPoint, \
dataTrajectory using 2:3 every ::0::end(n, i) with line lw lwTrajectory lc lcPoint
if(qtMode == 1) {
if((n==0 && i==0) || n==LOOP-1 && i==360*DEG_DIV) {
pause 2 # Wait a few seconds
}
pause 0.001 # Adjust the drawing speed
} else {
set out # terminal pngcairo
}
}
}
# Output the curve
set term pngcairo size 720, 720 font 'Times'
set output "trajectory_plot.png"
plot[-plotRange:plotRange][-plotRange:plotRange] \
dataTrajectory using 2:3 every ::0::360*DEG_DIV with line lw lwTrajectory lc lcPoint
set out
print sprintf('Finish this program')

Output (PNG file → GIF file)

Extra: Pseud-Fourier series animation

Source code (PLT file)

reset
set angle degrees
#=================== Parameter ====================
# Parameters in drawing
psPoint = 2 # ps = point size
lwCircle = 2 # lw = line width
lwCursor = 2
lwTrajectory = 2
lcCursor = -1 # lc = line color
lcPoint = 6
lcCircle1 = 2
lcCircle2 = 4
numPNG = 0
LOOP = 3
DEG_DIV = 1.0 # Resolution of degree, increase by 1/DEG_DIV
roundNum = 2
plotRange = 10 # Set the range of x/y axis [-plotRange:plotRange]
offsetXtCircle = -6.5 # Offset of the center of circles plotting a curve
offsetYtCircle = -6.5
# Select terminal type
qtMode = 0 # ==1: qt (simulator) / !=1: png (output images for making video)
print sprintf("[MODE] %s", (qtMode==1 ? 'Simulate in Qt window' :'Output PNG images'))
#=================== Function ====================
# Parametric equations of a curve
x(t) = 2*sin(2*t)-cos(3*t)
y(t) = sin(3*t)-2*cos(2*t)
# Show the value of the parameter t
showT(t) = sprintf("{/:Italic t} = %3.1f deg", t)
#=================== Setting ====================
if(qtMode==1){
set term qt size 720, 720 font 'Times'
} else {
set term pngcairo size 720, 720 font 'Times'
folderName = 'png_with_circles'
system sprintf('mkdir %s', folderName)
}
unset key
set grid
set size ratio -1
set xlabel '{/:Italic x}' font ', 20'
set ylabel '{/:Italic y}' font ', 20'
set tics font ', 18'
# Round off to the i decimal place.
round(x, i) = 1 / (10.**(i+1)) * floor(x * (10.**(i+1)) + 0.5)
#=================== Calculation ====================
# Output: "draw_trajectory.txt" is need for plotting the curve.
dataTrajectory = 'draw_trajectory.txt'
print sprintf('Start outputting %s ...', dataTrajectory)
set print dataTrajectory
# Write items and parameters in outputfile
print sprintf("# %s", dataTrajectory)
print sprintf('# DEG_DIV=%d', DEG_DIV)
print '# t / x / y'
# Calculate and output the trajectory of the curve
do for[i=0:360*DEG_DIV:1]{
t = i/DEG_DIV
print round(t, roundNum), round(x(t), roundNum), round(y(t), roundNum)
}
unset print
print sprintf('Finish!')
#=================== Plot ====================
if(qtMode == 1) {
print "Start simulation"
} else {
print sprintf('Start outputting %d images ...', LOOP*(1+360*DEG_DIV))
}
end(loop, i) = (loop>0) ? 360*DEG_DIV : i
do for [n=0:LOOP-1:1]{
do for [i=0:360*DEG_DIV:1]{
if(qtMode != 1) {
set output sprintf("%s/img_%04d.png", folderName, numPNG)
numPNG = numPNG + 1
}
# Get the value of time from either of txt files
set yrange [*:*] # This command enables to remove restrictions on the range of the stats command.
stats dataTrajectory using 1 every ::i::i nooutput
theta = STATS_max
set title showT(theta) left offset screen -0.07, -0.01 font ', 20'
# Circles drawing x(t) and locating on the y-axis
# x(t) = 2*sin(2*t)-cos(3*t)
cx1_x = 0 + 2*sin(2*theta)
cx1_y = offsetXtCircle + 2*cos(2*theta)
cx2_x = cx1_x - cos(3*theta)
cx2_y = cx1_y - sin(3*theta)
set object 1 circle at 0, offsetXtCircle size 2 fs empty border lt lcCircle1 lw lwCircle
set object 2 circle at cx1_x, cx1_y size 1 fs empty border lt lcCircle2 lw lwCircle
set arrow 1 nohead from 0, offsetXtCircle to cx1_x, cx1_y lt lcCircle1 lw lwCircle
set arrow 2 nohead from cx1_x, cx1_y to cx2_x, cx2_y lt lcCircle2 lw lwCircle
set object 3 circle at cx1_x, cx1_y size 0.1 fs solid fc lt lcCircle1 lw lwCircle front
set object 4 circle at cx2_x, cx2_y size 0.1 fs solid fc lt lcCircle2 lw lwCircle front
set arrow 3 nohead from cx2_x, cx2_y to cx2_x, plotRange lt lcCursor lw lwCursor
# set arrow 3 nohead from cx2_x, cx2_y to x(theta), y(theta) lt lcCursor lw lwCursor
# Circles drawing y(t) and locating on the x-axis
# y(t) = sin(3*t)-2*cos(2*t)
cy1_x = offsetYtCircle + cos(3*theta)
cy1_y = 0 + sin(3*theta)
cy2_x = cy1_x - 2*sin(2*theta)
cy2_y = cy1_y - 2*cos(2*theta)
set object 5 circle at offsetYtCircle, 0 size 1 fs empty border lt lcCircle1 lw lwCircle
set object 6 circle at cy1_x, cy1_y size 2 fs empty border lt lcCircle2 lw lwCircle
set arrow 4 nohead from offsetYtCircle, 0 to cy1_x, cy1_y lt lcCircle1 lw lwCircle
set arrow 5 nohead from cy1_x, cy1_y to cy2_x, cy2_y lt lcCircle2 lw lwCircle
set object 7 circle at cy1_x, cy1_y size 0.1 fs solid fc lt lcCircle1 lw lwCircle front
set object 8 circle at cy2_x, cy2_y size 0.1 fs solid fc lt lcCircle2 lw lwCircle front
set arrow 6 nohead from cy2_x, cy2_y to plotRange, cy2_y lt lcCursor lw lwCursor
# set arrow 6 nohead from cy2_x, cy2_y to x(theta), y(theta) lt lcCursor lw lwCursor
plot[-plotRange:plotRange][-plotRange:plotRange] \
dataTrajectory using 2:3 every ::i::i with p ps psPoint pt 7 lc lcPoint, \
dataTrajectory using 2:3 every ::0::end(n, i) with line lw lwTrajectory lc lcPoint
if(qtMode == 1) {
if((n==0 && i==0) || n==LOOP-1 && i==360*DEG_DIV) {
pause 2 # Wait a few seconds
}
pause 0.001 # Adjust the drawing speed
} else {
set out # terminal pngcairo
}
}
}
# Output the curve
set term pngcairo size 720, 720 font 'Times'
set output "trajectory_plot_with_circles.png"
plot[-plotRange:plotRange][-plotRange:plotRange] \
dataTrajectory using 2:3 every ::360*DEG_DIV::360*DEG_DIV with p ps psPoint pt 7 lc lcPoint, \
dataTrajectory using 2:3 every ::0::360*DEG_DIV with line lw lwTrajectory lc lcPoint
set out
print sprintf('Finish this program')

Output (PNG file → GIF file)

Referece

The link mechanism in the video is based on the following tweet by 千葉大数学科18.
▶︎ https://twitter.com/chibamath18/status/1406756501004251136?s=20

Search This Blog

Translate

QooQ