Na tomto obrázku vidieť ako funguje pre PRIEMERNÉ VÝŠKY VĹN cca ABSko automobilu. Hoci je zeleno modrá vlna primerovaná, všimnite si maximálneho hnedého kmitania systému podobného videu https://x.com/yan_qing35527/status/2105477079638913346/video/1
Môj nápad však bol zobraziť ABS automobilu ako animáciu: 
https://hrubos.tech/blogy/content/images/20261001111314-abs_vozidla_hrubos.gif
Čo sa dá spätne použiť na výpočtoch odpruženia mrakodrapov pre zemetrasenia ^^^
using Plots
gr()
# ============================================================
# NASTAVENIA
# ============================================================
const DT = 0.004
const TOTAL_TIME = 30.0
const TIMES = 0:DT:TOTAL_TIME
const FRAME_STEP = 5
const FPS = 30
const N = 80
# Dĺžky troch tyčiniek
const LENGTHS = [2.5, 3.5, 4.5]
# Základné polohy tyčiniek v osi Y
const Y_POSITIONS = [-2.2, 0.0, 2.2]
# Počet sínusových vĺn pre jednotlivé tyčinky
const WAVE_COUNT = [1, 2, 3]
# Sila kmitania tyčiniek
const AMPLITUDE = 1.35
# Rýchlosť hlavnej vlny
const WAVE_SPEED = 1.5
# Trvanie impulzu
const IMPULSE_DURATION = 25.0
# Rýchlosť postupovania kmitania po tyčinke
const ROD_WAVE_SPEED = 3.0
# ------------------------------------------------------------
# SPODNÁ VLNA – ŠÍRENIE V SMERE X
# ------------------------------------------------------------
const BOTTOM_AMPLITUDE = 0.75
const BOTTOM_WAVE_LENGTH = 5.0
const BOTTOM_WAVE_SPEED = 2.0
const X_MIN = -5.0
const X_MAX = 5.0
const BOTTOM_Z = 0.0
# ============================================================
# POMOCNÉ FUNKCIE
# ============================================================
function impulse_envelope(t)
if t < 0.0
return 0.0
elseif t <= IMPULSE_DURATION
return sin(π * t / IMPULSE_DURATION)
else
return 0.0
end
end
# ============================================================
# PUTUJÚCA VLNA
# ============================================================
function travelling_wave(x, t, wave_count)
wavelength =
(X_MAX - X_MIN) / wave_count
k =
2π / wavelength
omega =
k * WAVE_SPEED
envelope =
impulse_envelope(t)
return AMPLITUDE *
envelope *
sin.(k .* x .- omega * t)
end
# ============================================================
# OHYB TYČINKY
# ============================================================
function bent_rod(
base_y,
rod_length,
wave_count,
t
)
z =
collect(
range(
0.0,
rod_length,
length = N
)
)
# oneskorenie podľa výšky
delay =
z ./ ROD_WAVE_SPEED
local_time =
t .- delay
normalized_time =
clamp.(
local_time ./ IMPULSE_DURATION,
0.0,
1.0
)
envelope =
ifelse.(
local_time .>= 0.0,
sin.(π .* normalized_time),
0.0
)
wavelength =
rod_length / wave_count
k =
2π / wavelength
omega =
k * ROD_WAVE_SPEED
phase =
omega .* local_time
displacement =
AMPLITUDE .*
envelope .*
sin.(phase)
# päta sa nehýbe,
# špička sa hýbe najviac
bending_factor =
(z ./ rod_length) .^ 1.5
y =
base_y .+
displacement .* bending_factor
return y, z
end
# ============================================================
# SPODNÁ VLNA
# ============================================================
function bottom_wave(t)
x =
collect(
range(
X_MIN,
X_MAX,
length = 180
)
)
k =
2π / BOTTOM_WAVE_LENGTH
omega =
k * BOTTOM_WAVE_SPEED
y =
BOTTOM_AMPLITUDE .*
sin.(
k .* x .-
omega * t
)
z =
fill(
BOTTOM_Z,
length(x)
)
return x, y, z
end
# ============================================================
# LIMITY
# ============================================================
Z_MAX =
maximum(LENGTHS) + 0.5
Y_LIMIT =
maximum(abs.(Y_POSITIONS)) +
AMPLITUDE +
1.0
# ============================================================
# HISTÓRIA ŠPIČIEK
# ============================================================
tip_times = Float64[]
tip_y_1 = Float64[]
tip_y_2 = Float64[]
tip_y_3 = Float64[]
# ============================================================
# ANIMÁCIA
# ============================================================
anim = Animation()
# ============================================================
# HLAVNÁ SLUČKA
# ============================================================
for (frame_no, t) in enumerate(TIMES)
if frame_no % FRAME_STEP != 1
continue
end
# ========================================================
# TYČINKA 1
# ========================================================
y1, z1 =
bent_rod(
Y_POSITIONS[1],
LENGTHS[1],
WAVE_COUNT[1],
t
)
x1 =
fill(
0.0,
length(z1)
)
# ========================================================
# TYČINKA 2
# ========================================================
y2, z2 =
bent_rod(
Y_POSITIONS[2],
LENGTHS[2],
WAVE_COUNT[2],
t
)
x2 =
fill(
0.0,
length(z2)
)
# ========================================================
# TYČINKA 3
# ========================================================
y3, z3 =
bent_rod(
Y_POSITIONS[3],
LENGTHS[3],
WAVE_COUNT[3],
t
)
x3 =
fill(
0.0,
length(z3)
)
# ========================================================
# ŠPIČKY
# ========================================================
tip1_y =
y1[end]
tip2_y =
y2[end]
tip3_y =
y3[end]
push!(
tip_times,
t
)
push!(
tip_y_1,
tip1_y
)
push!(
tip_y_2,
tip2_y
)
push!(
tip_y_3,
tip3_y
)
# ========================================================
# VÝSLEDNÉ VYCHÝLENIE 3 TYČINIEK
# ========================================================
d1 =
tip1_y -
Y_POSITIONS[1]
d2 =
tip2_y -
Y_POSITIONS[2]
d3 =
tip3_y -
Y_POSITIONS[3]
resultant =
(d1 + d2 + d3) / 3.0
# ========================================================
# HISTÓRIA – VÝSLEDNÁ VLNA
# ========================================================
resultant_history =
(
(collect(tip_y_1) .-
Y_POSITIONS[1]) .+
(collect(tip_y_2) .-
Y_POSITIONS[2]) .+
(collect(tip_y_3) .-
Y_POSITIONS[3])
) ./ 3.0
# ========================================================
# SPODNÁ VLNA
# ========================================================
bx, by, bz =
bottom_wave(t)
# ========================================================
# ZÁKLADNÝ 3D GRAF
# ========================================================
plt =
plot(
xlim = (
X_MIN,
X_MAX
),
ylim = (
-Y_LIMIT,
Y_LIMIT
),
zlim = (
BOTTOM_Z - 0.4,
Z_MAX + 0.8
),
xlabel =
"X – smer šírenia vlny",
ylabel =
"Y – vychýlenie",
zlabel =
"Z – výška",
title =
"ABS vozidla – prerušované brzdenie, simuloval: Mgr. Ján Hruboš",
legend =
:outertopright,
camera =
(45, 28),
size =
(1100, 850),
aspect_ratio =
:auto
)
# ========================================================
# SPODNÁ VLNA
# ========================================================
plot!(
plt,
bx,
by,
bz,
lw = 4,
label =
"spodná vlna → X"
)
# ========================================================
# TYČINKA 1
# ========================================================
plot!(
plt,
x1,
y1,
z1,
lw = 5,
label =
"tyčinka 1"
)
# ========================================================
# TYČINKA 2
# ========================================================
plot!(
plt,
x2,
y2,
z2,
lw = 5,
label =
"tyčinka 2"
)
# ========================================================
# TYČINKA 3
# ========================================================
plot!(
plt,
x3,
y3,
z3,
lw = 5,
label =
"tyčinka 3"
)
# ========================================================
# ŠPIČKY
# ========================================================
scatter!(
plt,
[0.0, 0.0, 0.0],
[
tip1_y,
tip2_y,
tip3_y
],
[
z1[end],
z2[end],
z3[end]
],
markersize = 8,
label =
"špičky"
)
# ========================================================
# STRECHA XY
# ========================================================
roof_z =
Z_MAX
# čas prevedieme na vodorovnú os X
history_x =
collect(tip_times) .*
(X_MAX - X_MIN) /
TOTAL_TIME .+
X_MIN
roof_z_values =
fill(
roof_z,
length(history_x)
)
plot!(
plt,
history_x,
resultant_history,
roof_z_values,
lw = 4,
label =
"výsledná vlna – strecha XY"
)
# ========================================================
# AKTUÁLNY BOD NA STRECHE
# ========================================================
current_x =
X_MIN +
t / TOTAL_TIME *
(X_MAX - X_MIN)
scatter!(
plt,
[current_x],
[resultant],
[roof_z],
markersize = 9,
label =
"aktuálna poloha"
)
# ========================================================
# BOČNÁ STENA XZ
# ========================================================
wall_y =
Y_LIMIT
wall_z_center =
Z_MAX / 2
GRAPH_SCALE =
1.0
wall_z_values =
wall_z_center .+
GRAPH_SCALE .*
resultant_history
wall_y_values =
fill(
wall_y,
length(history_x)
)
plot!(
plt,
history_x,
wall_y_values,
wall_z_values,
lw = 4,
label =
"tieň – stena XZ"
)
# ========================================================
# AKTUÁLNY BOD NA STENE
# ========================================================
current_wall_z =
wall_z_center +
GRAPH_SCALE *
resultant
scatter!(
plt,
[current_x],
[wall_y],
[current_wall_z],
markersize = 9,
label =
"aktuálny tieň"
)
# ========================================================
# ČIARY OD ŠPIČIEK NA STRECHU
# ========================================================
for (
tip_y,
tip_z
) in (
(tip1_y, z1[end]),
(tip2_y, z2[end]),
(tip3_y, z3[end])
)
plot!(
plt,
[0.0, current_x],
[tip_y, resultant],
[tip_z, roof_z],
lw = 1,
linestyle = :dash,
label = ""
)
end
# ========================================================
# ČAS
# ========================================================
annotate!(
plt,
X_MIN + 0.3,
-Y_LIMIT + 0.3,
BOTTOM_Z + 0.1,
text(
"t = $(round(t, digits=2)) s",
10
)
)
# ========================================================
# ULOŽENIE FRAME
# ========================================================
frame(
anim,
plt
)
end
# ============================================================
# ULOŽENIE GIF
# ============================================================
gif(
anim,
"abs_vozidla_hrubos.gif",
fps = FPS
)
println()
println("Hotovo.")
println("Výstup: abs_vozidla_hrubos.gif")
