Three.js中绕任意关节轴旋转运动链连杆且保留原有姿态问题
解决Three.js中圆柱关节绕任意点轴旋转的正向运动链问题
问题背景
我正在Three.js中模拟正向运动链,包含圆柱关节和关节间的静态连杆。连杆为静态部件,仅需按运动学规则执行旋转和平移。已获取包含旋转信息和位置向量的关节位移矩阵M,该矩阵决定后续关节的旋转与位置,但需补充圆柱关节的旋转和平移操作,才能让关节处于正确位置。
现有代码与逻辑
更新连杆的函数代码
function updateLink(link, jointAxis, trans, rot_3, rotOffset, transOffset){ pre_link = new Object3D() pre_link = link.clone() // 使用零位姿的旧连杆 pre_link.matrix.setFromMatrix3(rot_3) // 根据运动链的运动修改位置和旋转 pre_link.matrix.setPosition(trans) pre_link.matrixAutoUpdate = false;
平移操作逻辑
平移仅为沿归一化关节轴的平移偏移:
trans = anchor + transOffSet * jointAxis
当前遇到的问题
目前连杆位于关节底部,需要绕关节轴旋转至正确位置,但不能改变位移矩阵赋予它的旋转与平移状态。之前尝试将连杆添加到圆柱对象后旋转父对象:
cylinder.add(link) cylinder.rotateOnAxis(jointAxis, rotOffset)
但这段代码会让连杆绕穿过原点的轴旋转,而我需要绕不经过原点的通用轴(即坐标系中某点处的归一化圆柱向上轴)旋转。
解决思路与实现方案
要实现绕任意点的轴旋转,核心是平移-旋转-平移回的三步变换逻辑,以下提供两种可行实现方式:
方法一:直接操作矩阵
在设置完pre_link.matrix后,构建绕指定锚点旋转的矩阵并与原矩阵组合:
// 1. 创建绕目标轴旋转的矩阵 const rotationMatrix = new THREE.Matrix4(); rotationMatrix.makeRotationAxis(jointAxis, rotOffset); // 2. 构建平移矩阵:先将原点移到关节锚点,旋转后再移回 const translateToAnchor = new THREE.Matrix4().makeTranslation(-anchor.x, -anchor.y, -anchor.z); const translateBack = new THREE.Matrix4().makeTranslation(anchor.x, anchor.y, anchor.z); // 3. 组合变换矩阵(注意矩阵相乘顺序:从右到左执行变换) pre_link.matrix.multiply(translateToAnchor) .multiply(rotationMatrix) .multiply(translateBack); pre_link.matrixAutoUpdate = false;
方法二:利用父对象层级嵌套
通过空对象作为旋转枢轴,先将枢轴移动到关节锚点,旋转枢轴后挂载连杆,实现绕锚点轴的旋转:
// 创建空的旋转枢轴对象 const pivot = new THREE.Object3D(); // 将枢轴定位到关节锚点位置 pivot.position.copy(anchor); // 绕关节轴旋转枢轴 pivot.rotateOnAxis(jointAxis, rotOffset); // 将已设置好位移矩阵的连杆添加到枢轴 pivot.add(pre_link); // 将枢轴添加到场景或父节点 scene.add(pivot);
注意事项
- 确保
jointAxis是归一化后的向量,否则旋转会附带缩放效果 - 使用矩阵操作时,需注意Three.js的矩阵右乘规则,变换顺序为从右到左
- 若采用层级嵌套方案,需确保连杆的
matrixAutoUpdate保持关闭,避免手动设置的矩阵被自动覆盖
内容的提问来源于stack exchange,提问作者Raaquu
相关产品推荐
相关产品推荐

