Skip to content

Commit 119c4e9

Browse files
committed
improve spring animations
1 parent 8e3f8c1 commit 119c4e9

File tree

4 files changed

+26
-15
lines changed

4 files changed

+26
-15
lines changed

docs/src/examples/three_springs.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@ systems = @named begin
2424
bar1 = FixedTranslation(r = [0.3, 0, 0])
2525
bar2 = FixedTranslation(r = [0, 0, 0.3])
2626
spring1 = Multibody.Spring(c = 20, m = 0, s_unstretched = 0.1, fixed_rotation_at_frame_b=true,
27-
r_rel_0 = [-0.2, -0.2, 0.2], radius=0.05, num_windings=10)
28-
spring2 = Multibody.Spring(c = 40, m = 0, s_unstretched = 0.1, color=[0,0,0.3,1])
29-
spring3 = Multibody.Spring(c = 20, m = 0, s_unstretched = 0.1, radius=0.05, num_windings=10)
27+
r_rel_0 = [-0.2, -0.2, 0.2], radius=0.05, num_windings=10, end_ratio=0.1)
28+
spring2 = Multibody.Spring(c = 40, m = 0, s_unstretched = 0.1, color=[0,0,0.3,1], end_ratio=0.1)
29+
spring3 = Multibody.Spring(c = 20, m = 0, s_unstretched = 0.1, radius=0.05, num_windings=10, end_ratio=0.1)
3030
end
3131
eqs = [connect(world.frame_b, bar1.frame_a)
3232
connect(world.frame_b, bar2.frame_a)

ext/Render.jl

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -661,7 +661,7 @@ function render!(scene, ::typeof(BodyShape), sys, sol, t)
661661
Makie.transform!(m, translation=r1, rotation=Q)
662662
end
663663
else
664-
error("Shape $shape not supported")
664+
error("""Shape $shape not supported, currently only supports "cylinder" and "box".""")
665665
end
666666
else
667667
T = get_frame_fun(sol, sys.frame_a)
@@ -834,12 +834,13 @@ function render!(scene, ::Union{typeof(Spring), typeof(SpringDamperParallel)}, s
834834
n_wind = sol(sol.t[1], idxs=sys.num_windings)
835835
radius = sol(sol.t[1], idxs=sys.radius) |> Float32
836836
N = round(Int, sol(sol.t[1], idxs=sys.N))
837+
end_ratio = sol(sol.t[1], idxs=sys.end_ratio) |> Float32
837838
thing = @lift begin
838839
r1 = Point3f(r_0a($t))
839840
r2 = Point3f(r_0b($t))
840-
spring_mesh(r1,r2; n_wind, radius, N)
841+
spring_mesh(r1,r2; n_wind, radius, N, end_ratio)
841842
end
842-
plot!(scene, thing; color)
843+
plot!(scene, thing; color, transparency=true)
843844
true
844845
end
845846

@@ -894,16 +895,18 @@ function render!(scene, ::Function, sys, sol, t, args...) # Fallback for systems
894895
false
895896
end
896897

897-
function spring_mesh(p1, p2; n_wind=6, radius=0.1f0, N=200)
898+
function spring_mesh(p1, p2; n_wind=6, radius=0.1f0, N=200, end_ratio = 0.1)
898899
phis = range(0, n_wind*2π, length=N)
899900
d = p2 - p1
900901
z = range(0, norm(d), length=N) # Correct length
901902
dn = d ./ norm(d)
902903
R = rot_from_line(dn)
903904

904905
points = map(enumerate(phis)) do (i,phi)
905-
x = radius*cos(phi)
906-
y = radius*sin(phi)
906+
n_ramp = N * end_ratio
907+
ri = i <= n_ramp ? i/n_ramp : i > N-n_ramp ? (N-i)/n_ramp : 1
908+
x = ri*radius*cos(phi)
909+
y = ri*radius*sin(phi)
907910
pᵢ = Point3f(x, y, z[i])
908911

909912
R * pᵢ + p1
@@ -1041,12 +1044,13 @@ function render!(scene, ::Union{typeof(P.Spring), typeof(P.SpringDamper)}, sys,
10411044
n_wind = sol(sol.t[1], idxs=sys.num_windings)
10421045
radius = sol(sol.t[1], idxs=sys.radius) |> Float32
10431046
N = sol(sol.t[1], idxs=sys.N) |> Int
1047+
end_ratio = sol(sol.t[1], idxs=sys.end_ratio) |> Float32
10441048
thing = @lift begin
10451049
r1 = Point3f(r_0a($t)..., 0)
10461050
r2 = Point3f(r_0b($t)..., 0)
1047-
spring_mesh(r1,r2; n_wind, radius, N)
1051+
spring_mesh(r1,r2; n_wind, radius, N, end_ratio, end_ratio)
10481052
end
1049-
plot!(scene, thing; color)
1053+
plot!(scene, thing; color, transparency=true)
10501054
true
10511055
end
10521056

@@ -1108,8 +1112,8 @@ function render!(scene, ::typeof(Multibody.BoxVisualizer), sys, sol, t)
11081112
height = Float32(sol(sol.t[1], idxs=sys.height))
11091113
length = Float32(sol(sol.t[1], idxs=sys.length))
11101114

1111-
length_dir = sol(sol.t[1], idxs=collect(sys.render_length_dir))
1112-
width_dir = sol(sol.t[1], idxs=collect(sys.render_width_dir))
1115+
length_dir = sol(sol.t[1], idxs=collect(sys.length_direction))
1116+
width_dir = sol(sol.t[1], idxs=collect(sys.width_direction))
11131117
height_dir = normalize(cross(normalize(length_dir), normalize(width_dir)))
11141118
width_dir = normalize(cross(height_dir, length_dir))
11151119

src/PlanarMechanics/components.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,7 @@ Linear 2D translational spring
215215
- `render = true` Render the spring in animations
216216
- `radius = 0.1` Radius of spring when rendered
217217
- `N = 200` Number of points in mesh when rendered
218+
- `end_ratio = 0.0`: Ratio of the length of the spring [0, 0.5] that is rendered with decreasing radius at the ends. Set this to 0 to have uniform radius along the entire spring.
218219
219220
# Connectors:
220221
- `frame_a` [Frame](@ref) Coordinate system fixed to the component with one cut-force and cut-torque
@@ -239,6 +240,7 @@ Linear 2D translational spring
239240
render = true, [description = "Render the spring in animations"]
240241
radius = 0.1, [description = "Radius of spring when rendered"]
241242
N = 200, [description = "Number of points in mesh when rendered"]
243+
end_ratio = 0.0
242244
end
243245

244246
@variables begin
@@ -352,6 +354,7 @@ Linear 2D translational spring damper model
352354
- `render = true` Render the spring in animations
353355
- `radius = 0.1` Radius of spring when rendered
354356
- `N = 200` Number of points in mesh when rendered
357+
- `end_ratio = 0.0`: Ratio of the length of the spring that is rendered with decreasing radius at the ends.
355358
356359
# Connectors:
357360
- `frame_a` [Frame](@ref) Coordinate system fixed to the component with one cut-force and cut-torque
@@ -379,6 +382,7 @@ Linear 2D translational spring damper model
379382
render = true, [description = "Render the spring in animations"]
380383
radius = 0.1, [description = "Radius of spring when rendered"]
381384
N = 200, [description = "Number of points in mesh when rendered"]
385+
end_ratio = 0.0
382386
end
383387

384388
@variables begin

src/forces.jl

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -388,10 +388,11 @@ additional equations to handle the mass are removed.
388388
- `color = [0,0,1,1]`: Color of the spring when rendered
389389
- `radius = 0.1`: Radius of spring when rendered
390390
- `N = 200`: Number of points in mesh when rendered. Rendering time can be reduced somewhat by reducing this number.
391+
- `end_ratio = 0.0`: Ratio of the length of the spring [0, 0.5] that is rendered with decreasing radius at the ends. Set this to 0 to have uniform radius along the entire spring.
391392
392393
See also [`SpringDamperParallel`](@ref)
393394
"""
394-
@component function Spring(; c, name, m = 0, lengthfraction = 0.5, s_unstretched = 0, num_windings=6, color=[0,0,1,1], radius=0.1, N=200, kwargs...)
395+
@component function Spring(; c, name, m = 0, lengthfraction = 0.5, s_unstretched = 0, num_windings=6, color=[0,0,1,1], radius=0.1, N=200, end_ratio = 0.0, kwargs...)
395396
@named ptf = PartialTwoFrames()
396397
@unpack frame_a, frame_b = ptf
397398
pars = @parameters begin
@@ -401,6 +402,7 @@ See also [`SpringDamperParallel`](@ref)
401402
bounds = (0, Inf),
402403
]
403404
num_windings = num_windings, [description = "Number of windings of the coil when rendered"]
405+
end_ratio = 0.0
404406
color[1:4] = color
405407
radius = radius, [description = "Radius of spring when rendered"]
406408
N = N, [description = "Number of points in mesh when rendered"]
@@ -501,7 +503,7 @@ f = c (s - s_{unstretched}) + d \\cdot D(s)
501503
where `c`, `s_unstretched` and `d` are parameters, `s` is the distance between the origin of `frame_a` and the origin of `frame_b` and `D(s)` is the time derivative of `s`.
502504
"""
503505
@component function SpringDamperParallel(; name, c, d, s_unstretched=0,
504-
color = [0, 0, 1, 1], radius = 0.1, N = 200, num_windings = 6, kwargs...)
506+
color = [0, 0, 1, 1], radius = 0.1, N = 200, num_windings = 6, end_ratio = 0.0, kwargs...)
505507
@named plf = PartialLineForce(; kwargs...)
506508
@unpack s, f = plf
507509

@@ -516,6 +518,7 @@ where `c`, `s_unstretched` and `d` are parameters, `s` is the distance between t
516518
radius = radius, [description = "Radius of spring when rendered"]
517519
N = N, [description = "Number of points in mesh when rendered"]
518520
num_windings = num_windings, [description = "Number of windings of the coil when rendered"]
521+
end_ratio = end_ratio
519522
end
520523
# pars = collect_all(pars)
521524

0 commit comments

Comments
 (0)