Skip to content

Commit 6b39133

Browse files
This commit fixes an issue in the tunnel animation where the entire tunnel would shift on each frame.
The new implementation correctly "locks" each concentric ridge of the tunnel to the center point it had at the moment of its creation. This is achieved by storing the center coordinates for each ridge along with its radius and using these per-ridge coordinates for drawing and erasing. This change creates the intended visual effect of flying through a tunnel with bends, as requested by the user.
1 parent cfaa9f9 commit 6b39133

File tree

2 files changed

+33
-14
lines changed

2 files changed

+33
-14
lines changed

gallery/tunnel/tunnel.sh

Lines changed: 33 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,14 @@ animate() {
3030
width=$(tput cols)
3131
local height
3232
height=$(tput lines)
33-
local center_x=$((width / 2))
34-
local center_y=$((height / 2))
35-
local max_radius=$(( (height > width ? height : width) / 2 + 2 ))
33+
local original_center_x=$((width / 2))
34+
local original_center_y=$((height / 2))
35+
local center_x=$original_center_x
36+
local center_y=$original_center_y
37+
local center_offset_x=$((width / 4))
38+
local center_offset_y=$((height / 4))
39+
local angle=0
40+
local max_radius=$((width + height))
3641
local ribbon_spacing=7
3742
local -a radii=()
3843
local frame_counter=0
@@ -55,39 +60,53 @@ animate() {
5560
}
5661

5762
while true; do
63+
# --- Update center coordinates for a moving tunnel effect (more efficiently) ---
64+
read -r angle center_x center_y < <(awk -v angle="$angle" \
65+
-v center_x="$original_center_x" -v center_y="$original_center_y" \
66+
-v offset_x="$center_offset_x" -v offset_y="$center_offset_y" \
67+
'BEGIN {
68+
angle += 0.05;
69+
cx = int(center_x + offset_x * cos(angle));
70+
cy = int(center_y + offset_y * sin(angle));
71+
print angle, cx, cy;
72+
}')
73+
5874
frame_buffer=""
5975
# Add a new ribbon every few frames
6076
if (( frame_counter % ribbon_spacing == 0 )); then
61-
radii+=(1)
77+
radii+=("1 $center_x $center_y")
6278
fi
6379

6480
local -a next_radii=()
65-
for r in "${radii[@]}"; do
81+
for ridge_data in "${radii[@]}"; do
82+
local r cx cy
83+
read -r r cx cy <<< "$ridge_data"
84+
6685
if [ $r -gt 0 ]; then
6786
local prev_r=$((r-1))
6887
# Erase the previous shape
6988
for ((i=0; i < prev_r; i++)); do
70-
erase_point $((center_x + i)) $((center_y - prev_r + i))
71-
erase_point $((center_x + prev_r - i)) $((center_y + i))
72-
erase_point $((center_x - i)) $((center_y + prev_r - i))
73-
erase_point $((center_x - prev_r + i)) $((center_y - i))
89+
erase_point $((cx + i)) $((cy - prev_r + i))
90+
erase_point $((cx + prev_r - i)) $((cy + i))
91+
erase_point $((cx - i)) $((cy + prev_r - i))
92+
erase_point $((cx - prev_r + i)) $((cy - i))
7493
done
7594
fi
7695

7796
local color=${COLORS[$((r % ${#COLORS[@]}))]}
7897
local char=${CHARS[$((r % ${#CHARS[@]}))]}
7998
# Draw a square/diamond shape
8099
for ((i=0; i < r; i++)); do
81-
plot_point $((center_x + i)) $((center_y - r + i)) "$char" "$color"
82-
plot_point $((center_x + r - i)) $((center_y + i)) "$char" "$color"
83-
plot_point $((center_x - i)) $((center_y + r - i)) "$char" "$color"
84-
plot_point $((center_x - r + i)) $((center_y - i)) "$char" "$color"
100+
plot_point $((cx + i)) $((cy - r + i)) "$char" "$color"
101+
plot_point $((cx + r - i)) $((cy + i)) "$char" "$color"
102+
plot_point $((cx - i)) $((cy + r - i)) "$char" "$color"
103+
plot_point $((cx - r + i)) $((cy - i)) "$char" "$color"
85104
done
86105

87106
# Increment radius for the next frame, and keep it if it's not too large
88107
local next_r=$((r + 1))
89108
if (( next_r < max_radius )); then
90-
next_radii+=($next_r)
109+
next_radii+=("$next_r $cx $cy")
91110
fi
92111
done
93112

jury/tunnel.bats

100644100755
File mode changed.

0 commit comments

Comments
 (0)