diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 17573598..390d9ddb 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -534,6 +534,9 @@ add_executable(maketicks maketicks.cpp) add_executable(coordarrows coordarrows.cpp) target_link_libraries(coordarrows OpenGL::GL glfw Freetype::Freetype) +add_executable(frames frames.cpp) +target_link_libraries(frames OpenGL::GL glfw Freetype::Freetype) + add_executable(sph_to_cart sph_to_cart.cpp) target_link_libraries(sph_to_cart OpenGL::GL glfw Freetype::Freetype) diff --git a/examples/frames.cpp b/examples/frames.cpp new file mode 100644 index 00000000..cd8bcd28 --- /dev/null +++ b/examples/frames.cpp @@ -0,0 +1,81 @@ +/* + * Demonstrating coordinate frame transformations + */ +#include +#include +#include +#include +#include // This is the only VisualModel derived class not called SomethingVisual! + +int main() +{ + mplot::Visual v(1024, 768, "Slerping"); + v.lightingEffects (true); + + // A is the end location coordinate arrows (darker) + sm::vec offset = {}; + auto cavm = std::make_unique> (offset); + v.bindmodel (cavm); + cavm->x_axis_col = mplot::colour::maroon; + cavm->y_axis_col = mplot::colour::darkgreen; + cavm->z_axis_col = mplot::colour::midnightblue; + cavm->finalize(); + auto cA = v.addVisualModel (cavm); + + // B is the starting location coordinate arrows (lighter) + cavm = std::make_unique> (offset); + v.bindmodel (cavm); + cavm->x_axis_col = mplot::colour::firebrick1; + cavm->y_axis_col = mplot::colour::palegreen3; + cavm->z_axis_col = mplot::colour::steelblue1; + cavm->finalize(); + auto cB = v.addVisualModel (cavm); + + cavm = std::make_unique> (offset); + v.bindmodel (cavm); + cavm->finalize(); + auto cC = v.addVisualModel (cavm); + + // Define A's location as a viewmatrix. Apply a rotation (first) then a translation + sm::mat A; + A.translate (sm::vec{0.2,0.4,0}); + A.rotate (sm::vec::uy(), sm::mathconst::pi_over_4); + + // The starting location. + sm::mat B; + B.translate (sm::vec{1,1,1}); + B.rotate (sm::vec::uz(), sm::mathconst::pi_over_2); + + // From A and B find the pure translation between the two + sm::vec delta_x = A.translation() - B.translation(); + + // Compute the pre-translation rotations + sm::mat A0 = A; + A0.translate (-A.translation()); + sm::mat B0 = B; + B0.translate (-B.translation()); + sm::quaternion rA = A0.rotation(); + sm::quaternion rB = B0.rotation(); + + // Set the viewmatrix for both A and B coordinate arrows (these will stay fixed) + cA->setViewMatrix (A); + cB->setViewMatrix (B); + + int count = 0; + while (!v.readyToFinish()) { + + v.render(); + v.wait (0.018); + + float prop = static_cast(count++ % 100) / 100.0f; + + // Compute the intermediate translation and rotation, C and apply this to the cC coordinate arrows + sm::mat C; + // C is a rotation of the intermediate rotation between rA and rB, then a translation to B + + // the intermediate delta_x: + C.translate (B.translation() + prop * delta_x); + C.rotate (rB.slerp (rA, prop)); + + cC->setViewMatrix (C); + } +} diff --git a/maths b/maths index ecc1c258..cc59b2ca 160000 --- a/maths +++ b/maths @@ -1 +1 @@ -Subproject commit ecc1c2581272c51b102c9e3c6c668d3a82b671fa +Subproject commit cc59b2ca3af93618033ffdbbce07c97dd4570b4b