持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第15天,点击查看活动详情
已知向量 、 和旋转轴 ,求 到 的旋转角度
-
单位化
单位化:Normalize()
单位化:Normalize()
-
求点积
if (::fabs(::fabs(dDot) - 1) < Config<T>::GetAbs())
{
return dDot > 0 ? 0 : Config<T>::GetPI();
//分别对应0度多一点点和180度的旋转角,画cos即可
}
| 参数(x) | 返回值 | |
|---|---|---|
| acos | [-1,1] | [0,] |
| (x, y) | atan2(y,x) | atan(y/x) |
|---|---|---|
| (+, +) | (0, ) | (0, ) |
| (+, -) | (, ) | (, 0 ) |
| (-, -) | (, ) | (0, ) |
| (-, +) | (, 0 ) | (, 0 ) |
所以到底是(0,)还是 (,)的数值还需要判断一下
这里使用叉乘 这个结果对应于旋转角度在(0,)之间
| 二者同向 | 二者反向 | |
|---|---|---|
| 旋转轴 与真实旋转轴 做点乘 | ,点乘的值为正 > 0 | ,点乘的值为负 < 0 |
| 旋转角度 |
T GetRotateAngle(const Vec3 &cToVec, const Vec3 &cAxis) const
{
Vec3 cVec1 = Vec3::Normalize(*this);
Vec3 cVec2 = Vec3::Normalize(cToVec);
T dDot = cVec1 % cVec2;
if (::fabs(::fabs(dDot) - 1) < Config<T>::GetAbs())
{
return dDot > 0 ? 0 : Config<T>::GetPI();
}
T dCurAngle = ::acos(dDot);
Vec3 cVec3 = cVec1 * cVec2;
return cVec3 % cAxis > 0 ? dCurAngle : (2 * Config<T>::GetPI() - dCurAngle);
}
会使用到的图形库
glm::dot(cVec1.m_cVec, cVec2.m_cVec);
glm::cross(cVec1.m_cVec, cVec2.m_cVec);
三维变换矩阵
-
求平移量,GetTranslationVec
Vec3<T> GetTranslationVec() const { return std::move(Vec3<T>(m_cMat[3][0], m_cMat[3][1], m_cMat[3][2])); } -
求缩放量,GetScalingVec
Vec3<T> GetScalingVec() const { return std::move(Vec3<T>(glm::length(m_cMat[0]), glm::length(m_cMat[1]), glm::length(m_cMat[2]))); } -
求旋转矩阵
Mat3<T> GetRotateMat3() const { Vec3<T> cScaleVec = GetScalingVec(); Vec3<T> cVec = (T)1.0 / GetScalingVec(); Mat3<T> cMat3; cMat3[0][0] = m_cMat[0][0] * cVec.x; cMat3[0][1] = m_cMat[0][1] * cVec.x; cMat3[0][2] = m_cMat[0][2] * cVec.x; cMat3[1][0] = m_cMat[1][0] * cVec.y; cMat3[1][1] = m_cMat[1][1] * cVec.y; cMat3[1][2] = m_cMat[1][2] * cVec.y; cMat3[2][0] = m_cMat[2][0] * cVec.z; cMat3[2][1] = m_cMat[2][1] * cVec.z; cMat3[2][2] = m_cMat[2][2] * cVec.z; return std::move(cMat3); } -
求是否是对称的
bool IsReflect() const { double dNormalLen = (1.0 - m_cMat[0][0]) * 0.5 + (1.0 - m_cMat[1][1]) * 0.5 + (1.0 - m_cMat[2][2]) * 0.5; if (::fabs(dNormalLen - 1.0) > Config<T>::GetAbs()) { return false; } const T *pData = GetData(); if (::fabs(pData[4] - pData[1]) > Config<T>::GetAbs()) { return false; } if (::fabs(pData[8] - pData[2]) > Config<T>::GetAbs()) { return false; } if (::fabs(pData[9] - pData[6]) > Config<T>::GetAbs()) { return false; } return true; }