iOS OpenGL ES中的四元数转换和旋转

时间:2014-01-03 15:47:50

标签: matrix opengl-es rotation quaternions translate-animation

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

然而,我现在正试图实现能够将标签(即,将其翻译)从一个位置拖动到另一个位置。如果我们看下面的图像,我试图说明的是我希望能够将标签从“标签从”转换到“标签到”的位置。然后,当我来旋转立方体时,标签应保持在新位置并随立方体旋转。但是,我正在进行这种翻译,当我尝试旋转立方体时,标签跳转到一个新位置,因为我没有正确设置标签坐标。

open-ended cube

我有与多维数据集关联的四元数。

使用以下代码,我可以在四元数设置为[0,0,0,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];
}

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

当我们正面观察时,这是有效的,因此x,y值可以很容易地从像素坐标转换为普通坐标或世界坐标。 但是,当轴不是正面时,我很难弄明白。例如,我们将四元数设置为(0,sqrt(2)/ 2,0,sqrt(2)/ 2),然后所有x个转换对应于z世界坐标。那么如何进行此连接/计算?我相信这很容易,但我已经碰到了这个。

(winSz我已经设置为1.5。模型坐标在-1和1之间)

0 个答案:

没有答案