Reputation: 16081
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?
Upvotes: 2
Views: 2405
Reputation: 51845
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 matrices in OpenGL are column oriented not row oriented and coordinate vectors are homogenuous 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 matrices 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;
}
For more info see:
Upvotes: 1
Reputation: 26355
Your question is a little confusing, as I don't understand what you mean by this stopping criteria. But if you want to get the transformed values for points, then you can simply pass them through the appropriate transform matrices to get them into the space you want. If you want the values in eye space, then pass your vertex coordinates through the modelview matrix, for example. See here for details of how that works.
Upvotes: 0