Matrix iOS-opengles中四元数的平移和旋转

Matrix iOS-opengles中四元数的平移和旋转,matrix,opengl-es,rotation,quaternions,translate-animation,Matrix,Opengl Es,Rotation,Quaternions,Translate Animation,我在iOS中努力使用一些四元数代码。我有一个开放的立方体,我已经旋转成一个等轴测视图。我可以用触摸旋转立方体,绕其轴旋转,也可以放大/缩小。我还有与立方体相关联的标签,它们也需要随立方体旋转。再一次,我成功地做到了这一点 然而,我现在正试图实现将标签从一个位置拖到另一个位置的功能。如果我们看下图,我试图说明的是,我希望能够将标签从“label from”转换为位置“label to”。然后,当我开始旋转立方体时,标签应该保持在它的新位置,并随着立方体旋转。然而,我正在做一个错误的翻译,当我尝试旋

我在iOS中努力使用一些四元数代码。我有一个开放的立方体,我已经旋转成一个等轴测视图。我可以用触摸旋转立方体,绕其轴旋转,也可以放大/缩小。我还有与立方体相关联的标签,它们也需要随立方体旋转。再一次,我成功地做到了这一点

然而,我现在正试图实现将标签从一个位置拖到另一个位置的功能。如果我们看下图,我试图说明的是,我希望能够将标签从“label from”转换为位置“label to”。然后,当我开始旋转立方体时,标签应该保持在它的新位置,并随着立方体旋转。然而,我正在做一个错误的翻译,当我尝试旋转立方体时,标签跳转到一个新的位置,因为我没有正确设置标签坐标

我有一个与立方体相关的四元数

通过下面的代码,当四元数设置为[0,0,0,1]时,我能够正确地转换标签(这样立方体就在前面-从这个位置看就像一个正方形)

如果拖动标签(基于UILabel)或旋转立方体(或opengl场景),则会命中这些方法

当我们向前看时,这就起作用了,这样x,y值就可以很容易地从像素坐标转换成普通坐标或世界坐标。 然而,当轴不在前面时,我很难找到它。例如,我们将四元数设置为(0,sqrt(2)/2,0,sqrt(2)/2),然后所有的x平移对应于z世界坐标。那么,我如何进行连接/计算?我相信这很容易,但我已经遇到了麻烦

(winSz i已设置为1.5。模型坐标非常介于-1和1之间)

- (void) rotateWithAngle:(float) radians andVector:(GLKVector3) axis andScale:(float) scale
{
    if (radians != self.lastRadians
        || (axis.v[0] != self.lastAxis.v[0] || axis.v[1] != self.lastAxis.v[1] || axis.v[2] != self.lastAxis.v[2])
        || scale != self.lastScale)
    {
        GLKMatrix4 m = GLKMatrix4MakeTranslation(self.normX, self.normY, self.normZ);

        if (radians != 0)
            m = GLKMatrix4Rotate(m, radians, axis.x, -axis.y, axis.z);

        m = GLKMatrix4Scale(m, scale, scale, scale);

        float x = (m.m00 * m.m30) + (m.m01 * m.m31) + (m.m02 * m.m32) + (m.m03 * m.m33);
        float y = (m.m10 * m.m30) + (m.m11 * m.m31) + (m.m12 * m.m32) + (m.m13 * m.m33);
        float z = (m.m20 * m.m30) + (m.m21 * m.m31) + (m.m22 * m.m32) + (m.m23 * m.m33);

        x /= m.m33;
        y /= m.m33;
        z /= m.m33;

        float w = (((x+self.winSz) / (self.winSz * 2.0)) * self.parentFrame.size.width) + self.parentFrame.origin.x;
        float h = (((y+self.winSz) / (self.winSz * 2.0)) * self.parentFrame.size.height) + self.parentFrame.origin.y;

        self.lastRadians = radians;
        self.lastAxis = axis;
        self.lastScale = scale;

        [self setCenter:CGPointMake(w,h)];
    }
}

- (void) translateFromTouch:(UIPanGestureRecognizer *) pan
{
    CGPoint translation = [pan translationInView:self];
    CGPoint imageViewPosition = self.center;

    GLKVector3 axis = GLKQuaternionAxis(*_quaternion);
    float rot = GLKQuaternionAngle(*_quaternion);

    CGFloat h = self.parentFrame.size.height;
    CGFloat w = self.parentFrame.size.width;

    imageViewPosition.x += translation.x;
    imageViewPosition.y += translation.y;

    self.center = imageViewPosition;

    // recalculate the norm position
    float x = ((2.0 * self.winSz * (imageViewPosition.x - self.parentFrame.origin.x)) / w) - self.winSz;
    float y = ((2.0 * self.winSz * (imageViewPosition.y - self.parentFrame.origin.y)) / h) - self.winSz;

    self.normX = x;
    self.normY = y;

    [pan setTranslation:CGPointZero inView:self];
}