@@ -2,6 +2,7 @@ module Render
22using Makie
33using Multibody
44import Multibody: render, render!, loop_render, encode, decode, get_rot, get_trans, get_frame
5+ import Multibody. PlanarMechanics as P
56using Rotations
67using LinearAlgebra
78using ModelingToolkit
@@ -679,4 +680,103 @@ function rot_from_line(d)
679680 y = y ./ norm (y)
680681 RotMatrix {3} ([x y d])
681682end
683+
684+ # ==============================================================================
685+ # # PlanarMechanics
686+ # ==============================================================================
687+ function get_rot_fun_2d (sol, frame)
688+ phifun = get_fun (sol, frame. phi)
689+ function (t)
690+ phi = phifun (t)
691+ [cos (phi) - sin (phi); sin (phi) cos (phi)]
692+ end
693+ end
694+
695+ function get_frame_fun_2d (sol, frame)
696+ R = get_rot_fun_2d (sol, frame)
697+ tr = get_fun (sol, [frame. x, frame. y])
698+ function (t)
699+ [R (t) tr (t); 0 0 1 ]
700+ end
701+ end
702+
703+ function render! (scene, :: typeof (P. Body), sys, sol, t)
704+ sol (sol. t[1 ], idxs= sys. render)== true || return true # yes, == true
705+ color = get_color (sys, sol, :purple )
706+ r_cm = get_fun (sol, collect (sys. r))
707+ framefun = get_frame_fun_2d (sol, sys. frame)
708+ radius = sol (sol. t[1 ], idxs= sys. radius) |> Float32
709+ thing = @lift begin # Sphere
710+ # Ta = framefun($t)
711+ # coords = (Ta*[0; 0; 1])[1:2] # r_cm($t)
712+
713+ coords = r_cm ($ t)
714+ point = Point3f (coords... , 0 )
715+ Sphere (point, Float32 (radius))
716+ end
717+ mesh! (scene, thing; color, specular = Vec3f (1.5 ), shininess= 20f0 , diffuse= Vec3f (1 ))
718+ false
719+ end
720+
721+
722+ function render! (scene, :: typeof (P. FixedTranslation), sys, sol, t)
723+ r_0a = get_fun (sol, [sys. frame_a. x, sys. frame_a. y])
724+ r_0b = get_fun (sol, [sys. frame_b. x, sys. frame_b. y])
725+ color = get_color (sys, sol, :purple )
726+ thing = @lift begin
727+ r1 = Point3f (r_0a ($ t)... , 0 )
728+ r2 = Point3f (r_0b ($ t)... , 0 )
729+ origin = r1# (r1+r2) ./ 2
730+ extremity = r2# -r1 # Double pendulum is a good test for this
731+ radius = 0.1f0 # Float32(sol($t, idxs=sys.radius))
732+ Makie. GeometryBasics. Cylinder (origin, extremity, radius)
733+ end
734+ mesh! (scene, thing; color, specular = Vec3f (1.5 ), shininess= 20f0 , diffuse= Vec3f (1 ))
735+ true
736+ end
737+
738+ function render! (scene, :: typeof (P. Revolute), sys, sol, t)
739+ r_0 = get_fun (sol, [sys. frame_a. x, sys. frame_a. y])
740+ n = [0 ,0 ,1 ]
741+ color = get_color (sys, sol, :red )
742+
743+ rotfun = get_rot_fun_2d (sol, sys. frame_a)
744+ radius = try
745+ sol (sol. t[1 ], idxs= sys. radius)
746+ catch
747+ 0.05f0
748+ end |> Float32
749+ length = try
750+ sol (sol. t[1 ], idxs= sys. length)
751+ catch
752+ radius
753+ end |> Float32
754+ thing = @lift begin
755+ O = [r_0 ($ t)... , 0 ]
756+ R_w_a = cat (rotfun ($ t), 1 , dims= (1 ,2 ))
757+ n_w = R_w_a* n # Rotate to the world frame
758+ p1 = Point3f (O + length* n_w)
759+ p2 = Point3f (O - length* n_w)
760+ Makie. GeometryBasics. Cylinder (p1, p2, radius)
761+ end
762+ mesh! (scene, thing; color, specular = Vec3f (1.5 ), shininess= 20f0 , diffuse= Vec3f (1 ))
763+ true
764+ end
765+
766+ function render! (scene, :: Union{typeof(P.Spring), typeof(P.SpringDamper)} , sys, sol, t)
767+ r_0a = get_fun (sol, [sys. frame_a. x, sys. frame_a. y])
768+ r_0b = get_fun (sol, [sys. frame_b. x, sys. frame_b. y])
769+ color = get_color (sys, sol, :blue )
770+ n_wind = sol (sol. t[1 ], idxs= sys. num_windings)
771+ radius = sol (sol. t[1 ], idxs= sys. radius) |> Float32
772+ N = sol (sol. t[1 ], idxs= sys. N) |> Int
773+ thing = @lift begin
774+ r1 = Point3f (r_0a ($ t)... , 0 )
775+ r2 = Point3f (r_0b ($ t)... , 0 )
776+ spring_mesh (r1,r2; n_wind, radius, N)
777+ end
778+ plot! (scene, thing; color)
779+ true
780+ end
781+
682782end
0 commit comments