opengl轨迹球

时间:2011-11-14 07:24:52

标签: opengl trackball

我正在尝试使用跟踪球旋转opengl场景。我遇到的问题是我在旋转屏幕的方向上旋转。这是代码片段。

         prevPoint.y = viewPortHeight - prevPoint.y;
        currentPoint.y = viewPortHeight - currentPoint.y;

        prevPoint.x = prevPoint.x - centerx;
        prevPoint.y = prevPoint.y - centery;
        currentPoint.x = currentPoint.x - centerx;
        currentPoint.y = currentPoint.y - centery;

        double angle=0;
        if (prevPoint.x == currentPoint.x && prevPoint.y == currentPoint.y) {
            return;
        }
         double d, z, radius = viewPortHeight * 0.5;
        if(viewPortWidth > viewPortHeight) {
            radius = viewPortHeight * 0.5f;
        } else {
            radius = viewPortWidth * 0.5f;
        }

         d = (prevPoint.x * prevPoint.x + prevPoint.y * prevPoint.y);
         if (d <= radius * radius * 0.5 ) {    /* Inside sphere */
             z = sqrt(radius*radius - d);
         } else {           /* On hyperbola */
             z = (radius * radius * 0.5) / sqrt(d);
         }
        Vector refVector1(prevPoint.x,prevPoint.y,z);
        refVector1.normalize();
        d = (currentPoint.x * currentPoint.x + currentPoint.y * currentPoint.y);
        if (d <= radius * radius * 0.5 ) {    /* Inside sphere */
            z = sqrt(radius*radius - d);
        } else {           /* On hyperbola */
             z = (radius * radius * 0.5) / sqrt(d);
        }
        Vector refVector2(currentPoint.x,currentPoint.y,z);
        refVector2.normalize();
        Vector axisOfRotation = refVector1.cross(refVector2);
        axisOfRotation.normalize();
        angle = acos(refVector1*refVector2);

1 个答案:

答案 0 :(得分:0)

我建议人工设置prevPoint和currentPoint为(0,0)(0,1),然后单步执行代码(使用调试器或用你的眼睛)来查看每个部分是否对你有意义,以及角度块的末端的旋转和轴是你期望的。

如果它们是您所期望的,那么我猜测错误是在此之后发生的逻辑中。即你然后取角度和轴并将它们转换成矩阵,该矩阵乘以移动模型。在这个管道中发生了许多约定选择 - 如果交换可能会导致你遇到的错误类型:

  • 公式是否假定角度绕轴左右缠绕。
  • 转换是用于旋转世界中的对象还是用于旋转相机。
  • 矩阵是否意味着左右相乘。
  • 矩阵的行或列是否在内存中是连续的。