- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在构建一个 VR 交互系统,并添加一个 throw 组件。
它的设置是为了让我有一个不断更新的持有对象的位置数组,当我释放持有的对象时,它会计算最后 5 个位置之间每个时间步长的增量位置,并将它们取平均值。这给我留下了一个平滑的冲击力 throw 矢量,而不会因释放时无意的手腕轻弹而引入任何抖动。该系统已实现并且运行良好。
我现在正尝试对旋转做同样的事情,并在释放时添加扭力。 但是,在我当前的实现中,它似乎只是选择一个随机轴在释放时旋转。
我更新四元数数组的实现方式与位置相同,没问题,问题出在我的四元数平均代码或增量旋转计算代码中:
以下是我计算增量旋转的方法。请注意,rotations
是从最后一帧开始的 n
旋转数组,最近的在 0
,最旧的在 n
Quaternion[] deltaRotations = new Quaternion[rotations.Length - 1];
for (int i = 0; i < deltaRotations.Length; i++)
{
deltaRotations[i] = Quaternion.Inverse(rotations[i]) * rotations[i+1];
}
以下是我对增量旋转进行平均的方法。
Quaternion avgRot = Quaternion.identity;
int quatCount = 0;
foreach (Quaternion quat in deltaRotations)
{
quatCount ++;
avgRot = Quaternion.Slerp(avgRot, quat, 1 / quatCount);
}
来自 Rigidbody.addTorque(avgRot, ForceMode.Impulse)
的合力将其设置为看似随机的方向旋转。
你们有什么明显错误的地方吗?
编辑
根据 Ruzihim 的回答,我已将代码转换为使用旋转的角度/轴表示并对它们进行平均。这在物体释放时确定了正确的旋转轴,但似乎每次都给我相同的旋转强度。下面新的计算旋转力方法的代码,不是我将 deltaRotations 数组传递给这个函数,而不是传递原始旋转数组并在事后计算增量旋转:
Vector3 averageRotationsAngleAxis(Quaternion[] rotations) // returns an angle / axis representation of averaged rotations[]
{
Vector3[] deltaAxes = new Vector3[rotations.Length];
for (int i = 0; i < rotations.Length; i++)
{
float angle;
Vector3 axis;
rotations[i].ToAngleAxis(out angle, out axis);
deltaAxes[i] = angle * axis;
}
Vector3 returnVec = averageVector3(deltaAxes);
return returnVec;
}
将 Ruzihim 的答案标记为正确,当我使用他的方法 Debug.Log
抛出旋转的结果时,它们看起来是正确的,问题一定在那个和脉冲扭矩之间的某个地方
最佳答案
使用 slerp 来平均四元数可能会导致一些意外行为。例如,如果您有 2 个增量旋转,一个绕 y 轴旋转 180 度,一个绕 y 轴旋转 -180 度,从一个旋转到另一个旋转永远不会产生恒等旋转(旋转 0 度绕 y 轴轴)。它实际上总是在某个方向上旋转 180 度。自己试试:
Quaternion a = Quaternion.AngleAxis(180f, Vector3.up);
Quaternion b = Quaternion.AngleAxis(-180f, Vector3.up);
Quaternion c = Quaternion.Slerp(a, b, 0.5f)
float angle;
Vector3 axis;
c.ToAngleAxis(out angle, out axis);
Debug.Log(angle);
Debug.Log(axis);
因此,相反,我建议平均旋转轴和角度,特别是使用全局旋转轴。要获得全局轴中的增量旋转,请从 global axis delta rotation * start rotation = next rotation
开始并代数求解:
globalAxesDelta * startRot = nextRot
globalAxesDelta * startRot * inv(startRot) = nextRot * inv(startRot)
globalAxesDelta = nextRot * inv(startRot)
因此,要使用全局轴计算旋转增量,请使用 deltaRotation = rotations[i+1] * Quaternion.Inverse(rotations[i])
而不是 deltaRotations[i] = Quaternion .Inverse(rotations[i]) * rotations[i+1]
.然后,使用 ToAngleAxis
将它们转换为轴/角度形式:
Vector3[] deltaAxes = new Vector3[rotations.Length - 1];
for (int i = 0; i < deltaRotations.Length; i++)
{
Quaternion deltaRotation = rotations[i+1] * Quaternion.Inverse(rotations[i]);
float angle;
Vector3 axis;
deltaRotation.ToAngleAxis(out angle, out axis);
deltaAxes[i] = angle * axis;
}
然后平均这些全局轴:
Vector3 avgAxis = Vector3.zero;
foreach (Vector3 angleAxis in deltaAxes)
{
avgAxis += (1f/deltaRotations.Length) * angleAxis;
}
然后,您将使用类似 AddTorque(avgAxis * someTorqueFactor)
的方法来沿全局轴应用扭矩。
关于c# - 平均一系列旋转并使用它们来施加扭矩,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62785867/
我有2个刚体(a和b)和1个固定关节约束(带有相对转换rela)。 我的目标是实现: 1号。 b.transform = a.transform * rela 2号。质心(a + b)不变。 No.3
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
默认情况下,提交作业到扭矩队列的输出将保存到名为 job_name.o658392 的文件中。使用该示例,我想要做的是将输出文件命名为 658392.job_name.log。 我知道我可以通过在脚本
我在这里克隆了最早版本的 Torque 3D:Github - Torque3D.我使用项目管理器工具生成了一个“空”模板项目,然后启动 VS2013 Professional 进入构建过程。 在 V
我是一名优秀的程序员,十分优秀!