module KinematicClass !! Some basic functions for Kinematics use, intrinsic :: iso_fortran_env use MathClass implicit none contains ! ############################################# !> It returns 3-D rotation matrix. function RotationMatrix3D(rotx, roty, rotz, n, angle) result(Rmat) real(real64)::Rmat(3, 3) real(real64), optional, intent(in)::rotx, roty, rotz, n(3), angle integer(int32) :: i Rmat(:, :) = 0.0d0 do i = 1, 3 Rmat(i, i) = 1.0d0 end do if (present(rotx)) then Rmat(2, 2) = cos(rotx) Rmat(2, 3) = -sin(rotx) Rmat(3, 2) = sin(rotx) Rmat(3, 3) = cos(rotx) end if if (present(rotx)) then Rmat(1, 1) = cos(rotx) Rmat(1, 3) = sin(rotx) Rmat(3, 1) = -sin(rotx) Rmat(3, 3) = cos(rotx) end if if (present(rotx)) then Rmat(2, 2) = cos(rotx) Rmat(2, 3) = -sin(rotx) Rmat(3, 2) = sin(rotx) Rmat(3, 3) = cos(rotx) end if if (present(n) .and. present(angle)) then ! Rodrigues' rotation formula Rmat(1, 1) = cos(angle) + n(1)*n(1)*(1.0d0 - cos(angle)) Rmat(1, 2) = n(1)*n(2)*(1.0d0 - cos(angle)) - n(3)*sin(angle) Rmat(1, 3) = n(1)*n(3)*(1.0d0 + cos(angle)) - n(2)*sin(angle) Rmat(2, 1) = n(2)*n(1)*(1.0d0 + cos(angle)) - n(3)*sin(angle) Rmat(2, 2) = cos(angle) + n(2)*n(2)*(1.0d0 - cos(angle)) Rmat(2, 3) = n(2)*n(3)*(1.0d0 - cos(angle)) - n(1)*sin(angle) Rmat(3, 1) = n(3)*n(1)*(1.0d0 - cos(angle)) - n(2)*sin(angle) Rmat(3, 2) = n(3)*n(2)*(1.0d0 + cos(angle)) - n(1)*sin(angle) Rmat(3, 3) = cos(angle) + n(3)*n(3)*(1.0d0 - cos(angle)) end if end function ! ############################################# ! ############################################# !> It rotates 3-D vector. function Rotation3D(vector, rotx, roty, rotz, n, angle) result(vec) real(real64)::vec(3) real(real64), intent(in)::vector(3) real(real64), optional, intent(in)::rotx, roty, rotz, n(3), angle vec(:) = matmul(RotationMatrix3D(rotx, roty, rotz, n, angle), vector) end function ! ############################################# end module