限制俯仰,偏航和滚 [英] Constrain pitch, yaw, & roll

查看:118
本文介绍了限制俯仰,偏航和滚的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我将旋转表示为四元数,并试图限制音调,偏航和横滚轴。我试着这样做:

I've a rotation represented as a quaternion and am trying to constrain the pitch, yaw, & roll axes. I tried doing so thusly:

public struct Orientation
{
    public Vector3 up, forward;

    public Orientation(Vector3 up, Vector3 forward)
    {
        this.up = up;
        this.forward = forward;
    }
}

public static Orientation[] orientations = new Orientation[3]
{
    new Orientation(Vector3.right, Vector3.up),
    new Orientation(Vector3.up, Vector3.forward),
    new Orientation(Vector3.forward, Vector3.right)
};

public enum Axis
{
    Pitch,
    Yaw,
    Roll
};

private Vector3 ConstrainAxis(Vector3 vector, Axis axis, float from, float to)
{
    Orientation orientation = orientations[(int)axis];

    float theta = (to - from) * 0.5F;

    Vector3 cons = Quaternion.AngleAxis(from + theta, orientation.up) * orientation.forward;
    Vector3 proj = Vector3.ProjectOnPlane(vector, orientation.up);

    return ConstrainVector(cons.normalized, proj.normalized, theta);
}

private Vector3 ConstrainVector(Vector3 from, Vector3 to, float angle)
{
    float theta = Mathf.Abs(angle / Vector3.Angle(from, to));

    if(theta < 1.0F)
    {
        return Vector3.Slerp(from, to, theta);
    }

    return to;
}

事实证明,这不过是过于复杂的约束方式欧拉角表示的各个组成部分,都面临着奇怪的抖动问题(与万向锁定有关吗?)。

Which turned out to be nothing more than an over-complicated way of constraining the individual components of an euler angle representation, of which both are subject to a strange jittering issue (gimbal lock related?).

约束这些轴的最佳方法是什么?

What is the best approach to constraining these axes?

推荐答案

对于关节约束,通常的做法是使用摆动扭曲参数化。
表示当前旋转为四元数的摆动扭曲,theare是很好的分解
http://www.alinenormoyle.com/weblog/?p=726

For joint constraints it is common practice to use "swing twist" parametrization. To represent current rotation as "swing twist" for quaternions, theare are good decomposition http://www.alinenormoyle.com/weblog/?p=726

可以限制摆动和扭曲四元数。

And constraint for "swing" and "twist" can be done with quaternions.

如果我们想将摆动限制为+ -30度,伪代码应为

if we want to constrain swing to +-30 degrees , pseudocode looks like

Quaternion swing;
const double maxMagnitude = sin( 0.5 * toRad(30) );
const double maxMagnitudeW = sqrt(1.0 - maxMagnitude*maxMagnitude );
if(swing.vec().normSqr() > maxMagnitude*maxMagnitude)
{
  swing.vec() = swing.vec().normalized() * maxMagnitude;
  swing.w() = maxMagnitudeW;
}

这篇关于限制俯仰,偏航和滚的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆