defmodule Robot.Utils do @moduledoc """ Provide useful robotics functions """ alias ELA.Matrix, as: Matrix alias ELA.Vector, as: Vector def matrixFromAxisAngle(axis_angle,translate) do angle = Enum.at(axis_angle, 3) x = Enum.at(axis_angle, 0) y = Enum.at(axis_angle, 1) z = Enum.at(axis_angle, 2) c = :math.cos(angle) s = :math.sin(angle) t = 1.0-c m00 = c + x*x*t m11 = c + y*y*t m22 = c + z*z*t tmp1 = x*y*t tmp2 = z*s m10 = tmp1 + tmp2 m01 = tmp1 - tmp2 tmp1 = x*z*t tmp2 = y*s m20 = tmp1 - tmp2 m02 = tmp1 + tmp2 tmp1 = y*z*t tmp2 = x*s m21 = tmp1 + tmp2 m12 = tmp1 - tmp2 matrix = [[m00, m01, m02, Enum.at(translate,0)], [m10, m11, m12, Enum.at(translate,1)], [m20, m21, m22, Enum.at(translate,2)], [0.0, 0.0, 0.0, 1.0]] end def axisAngleFromMatrix(matrix) do [[m00, m01, m02, m03], [m10, m11, m12, m13], [m20, m21, m22, m23], [m30, m31, m32, m33]] = matrix angle = :math.acos(( m00 + m11 + m22 - 1)/2.0) x_ = :math.sqrt(:math.pow(m21 - m12, 2.0)+:math.pow(m02 - m20,2.0)+:math.pow(m10 - m01,2.0)) y_ = :math.sqrt(:math.pow(m21 - m12,2.0)+:math.pow(m02 - m20,2.0)+:math.pow(m10 - m01,2.0)) z_ = :math.sqrt(:math.pow(m21 - m12,2.0)+:math.pow(m02 - m20,2.0)+:math.pow(m10 - m01,2.0)) if x_==0 || y_==0 || z_==0 do x = 1.0 y = 0.0 z = 0.0 angle = 0.0 %{rot: [x, y, z, angle], trans: [m03,m13,m23]} else x = (m21 - m12)/x_ y = (m02 - m20)/y_ z = (m10 - m01)/z_ %{rot: [x, y, z, angle], trans: [m03,m13,m23]} end end end