c ++ OpenGL旋转和计算 [英] c++ OpenGL rotations and calculations

查看:157
本文介绍了c ++ OpenGL旋转和计算的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在一个OpenGL项目中,我有一个旋转模型的函数:



glRotatef(M_PI / 4,0,0,1) ; //旋转PI / 4弧度,即45度



现在当我绘制点。我会在点(1 / sqrt(2),1 / sqrt(2))这只是单位圆几何。但是,将使用变量坐标 x1,x2,y1,y2 绘制点。此外,我想停止绘图后,我的近似足够近。



问题是我的停止标准仍然是在全局坐标方面,而不是相对于旋转。例如,考虑y2 = y1,其中方程涉及变换。因此,在全局坐标中,这只是y2 = y1 * sin(pi / 4),因此y2将较低并且在y1的右边。然而,y2的值只是设置为y1,这在我的停止标准y2-y1中产生一个问题,然后它将为零。



从OpenGL的y2的旋转值?



非常感谢所有帮助!让我知道如果你需要更多的信息!

解决方案

如果你使用glRotatef从OpenGL不要忘记旋转角度是度以弧度为单位。



对于转换和混淆部分,user1118321是完全正确的。



目的你只需要应用GL_MODELVIEW_MATRIX



如果你需要模型空间中的坐标,你必须乘以全局坐标向量的逆模型视图矩阵。



如果你需要在全局空间中的坐标,而不是必须乘以模型坐标向量的modelview矩阵。



由顶点发送的坐标在模型空间
你可以得到具有gl函数的实际modelview矩阵glGetFlotav / glGetDoublev

  double m [16] 
glGetDoublev(GL_MODELVIEW_MATRIX,m);

在OpenGL中不存在逆矩阵和矩阵x向量乘法,因此您必须自己编写代码, 11b。不要忘记OpenGL中的矩阵是面向列的而不是面向行的,坐标向量是同质的,所以x,y,z,w,其中w = 1为您的目的。这里是用于我的OpenGL子计算的代码,所有的向量都是double [4],矩阵是double [16]。

  void matrix_mul_vector(double * c,double * a,double * b)
{
double q [3];
q [0] =(a [0] * b [0])+(a [4] * b [1])+(a [8] * b [2] ;
q [1] =(a [1] * b [0])+(a [5] * b [1])+(a [9] * b [2] ;
q [2] =(a [2] * b [0])+(a [6] * b [1])+(a [10] * b [2] ;
for(int i = 0; i <3; i ++)c [i] = q [i]
}
void matrix_subdet(double * c,double * a)
{
double q [16];
int i,j;
for(i = 0; i <4; i ++)
for(j = 0; j <4; j ++)
q [j +(i << 2)] = matrix_subdet ,i,j);
for(i = 0; i <16; i ++)c [i] = q [i]
}
double matrix_subdet(double * a,int r,int s)
{
double c,q [9]
int i,j,k;
k = 0; // q = sub matrix
for(j = 0; j <4; j ++)
if(j!= s)
for(i = 0; i <4; i ++) b $ b if(i!= r)
{
q [k] = a [i +(j <2)
k ++;
}
c = 0;
c + = q [0] * q [4] * q [8];
c + = q [1] * q [5] * q [6];
c + = q [2] * q [3] * q [7];
c- = q [0] * q [5] * q [7];
c- = q [1] * q [3] * q [8];
c- = q [2] * q [4] * q [6];
if(int((r + s)& 1))c = -c; // add signum
return c;
}
double matrix_det(double * a)
{
double c = 0;
c + = a [0] * matrix_subdet(a,0,0);
c + = a [4] * matrix_subdet(a,0,1);
c + = a [8] * matrix_subdet(a,0,2);
c + = a [12] * matrix_subdet(a,0,3);
return c;
}
double matrix_det(double * a,double * b)
{
double c = 0;
c + = a [0] * b [0];
c + = a [4] * b [1];
c + = a [8] * b [2];
c + = a [12] * b [3];
return c;
}
void matrix_inv(double * c,double * a)
{
double d [16],D;
matrix_subdet(d,a);
D = matrix_det(a,d);
if(D)D = 1.0 / D;
for(int i = 0; i <16; i ++)c [i] = d [i] * D;
}


In an OpenGL project, I have a function that rotates the model:

glRotatef(M_PI/4, 0, 0, 1); //rotate by PI/4 radians i.e 45 degrees

Now when I draw the point (0, 1) with respect to the rotation. I will be at the point (1/sqrt(2), 1/sqrt(2)) this is just unit circle geometry. However the points will be drawn with variable coordinates x1, x2, y1, y2. Also, I would like to stop drawing after my approximation is close enough.

The problem is my stopping criteria is still in terms of global coordinates and not with respect to the rotation. For example, consider y2 = y1 where the equation respects the transformation. Thus in the global coordinates this would just be y2=y1*sin(pi/4) and so y2 will be lower and to the right of y1. However the value of y2 is just set to y1 and this creates a problem in my stopping criteria y2-y1 which would then be zero.

How can I get the rotated value for y2 from OpenGL?

All help is greatly appreciated! Let me know if you need more information!

解决方案

if you use glRotatef from OpenGL do not forget that rotation angle is in Degrees not in radians !!!

for the transformation and confusion part user1118321 is absolutely right.

I thing for your purposes you need only to apply GL_MODELVIEW_MATRIX

if you need coordinates in model space you must multiply inverse modelview matrix by global coordinates vector.

If you need coordinates in global space than you must multiply modelview matrix by model coordinates vector.

coordinates send by vertex are in model space you can obtain actual modelview matrix with gl functions glGetFlotav/glGetDoublev

double m[16];
glGetDoublev(GL_MODELVIEW_MATRIX,m);

inverse matrix and matrix x vector multiplication is not present in OpenGL so you must code it yourself or use some lib. Do not forget that matrixes in OpenGL are column oriented not row oriented and coordinate vectors are homogenous so x,y,z,w where w=1 for your purposes. Here is code i use for my OpenGL sub-calculations, all vectors are double[4] and matrixes are double[16]

void  matrix_mul_vector(double *c,double *a,double *b)
        {
        double q[3];
        q[0]=(a[ 0]*b[0])+(a[ 4]*b[1])+(a[ 8]*b[2])+(a[12]);
        q[1]=(a[ 1]*b[0])+(a[ 5]*b[1])+(a[ 9]*b[2])+(a[13]);
        q[2]=(a[ 2]*b[0])+(a[ 6]*b[1])+(a[10]*b[2])+(a[14]);
        for(int i=0;i<3;i++) c[i]=q[i];
        }
void  matrix_subdet    (double *c,double *a)
        {
        double   q[16];
        int     i,j;
        for (i=0;i<4;i++)
         for (j=0;j<4;j++)
          q[j+(i<<2)]=matrix_subdet(a,i,j);
        for (i=0;i<16;i++) c[i]=q[i];
        }
double matrix_subdet    (         double *a,int r,int s)
        {
        double   c,q[9];
        int     i,j,k;
        k=0;                            // q = sub matrix
        for (j=0;j<4;j++)
         if (j!=s)
          for (i=0;i<4;i++)
           if (i!=r)
                {
                q[k]=a[i+(j<<2)];
                k++;
                }
        c=0;
        c+=q[0]*q[4]*q[8];
        c+=q[1]*q[5]*q[6];
        c+=q[2]*q[3]*q[7];
        c-=q[0]*q[5]*q[7];
        c-=q[1]*q[3]*q[8];
        c-=q[2]*q[4]*q[6];
        if (int((r+s)&1)) c=-c;       // add signum
        return c;
        }
double matrix_det       (         double *a)
        {
        double c=0;
        c+=a[ 0]*matrix_subdet(a,0,0);
        c+=a[ 4]*matrix_subdet(a,0,1);
        c+=a[ 8]*matrix_subdet(a,0,2);
        c+=a[12]*matrix_subdet(a,0,3);
        return c;
        }
double matrix_det       (         double *a,double *b)
        {
        double c=0;
        c+=a[ 0]*b[ 0];
        c+=a[ 4]*b[ 1];
        c+=a[ 8]*b[ 2];
        c+=a[12]*b[ 3];
        return c;
        }
void  matrix_inv       (double *c,double *a)
        {
        double   d[16],D;
        matrix_subdet(d,a);
        D=matrix_det(a,d);
        if (D) D=1.0/D;
        for (int i=0;i<16;i++) c[i]=d[i]*D;
        }

这篇关于c ++ OpenGL旋转和计算的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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