Согласно моему вопросу по математике Stackexchange:
Я работаю над проектом для своего класса 3D-графики.Проект построен на C ++ и OpenGL / Glut.По сути, я создаю горизонтальное прямоугольное окно, разделенное на два квадрата.Слева у меня есть двумерная координатная плоскость, которая позволяет пользователям указывать, щелкать и определять профиль «кривая».Затем мне нужно обернуть эту кривую вокруг оси Y n раз.
Итак, кто-нибудь сможет мне подсказать, как я буду использовать тригонометрию для вычисления значений X и Z последовательных точек?Например, если пользователь щелкает и создает точку:
(1, 1, 0)
И его разрешение развертки (n) установлено, скажем, 10, то мне нужноперерисовывать эту точку каждые 36 (360/10) градусов вокруг оси Y.
Правильно ли я считаю, что тригонометрия поможет мне здесь?Если да, то может ли кто-нибудь немного рассказать мне о том, как рассчитать местоположение переведенной точки в трехмерном пространстве?Прошло много времени с тех пор, как я взял Trig, и я не думаю, что мы когда-либо оставляли 2D-пространство.
EDIT : я пытался использовать:
x'=xcos(theta)-zsin(theta)
y'=y
z'=xsin(theta)+zcos(theta)
,согласно моему пониманию ответа AMPerrine , и я не думаю, что это сработало так, как я надеялся:
// this is in a loop
// setup the new angle
double angle = i>0 ? (360/sweepResolutionMod)*i : 0;
angle = angle * (M_PI/180);
// for each point...
for( int i=0; i<clickedPoints.size(); i++ )
{
// initial point, normalized
GLfloat tempX = (clickedPoints[i].x-250)/250;
GLfloat tempY = (clickedPoints[i].y-250)/250;
GLfloat tempZ = 0.0;
// log the initial point
cout << "(" << tempX << ", " << tempY << ", 0.0) by " << angle << " radians = ";
// generate the new point
GLfloat newX = (tempX * cos(angle)) - (tempZ * sin(angle));
GLfloat newY = tempY;
GLfloat newZ = (tempX * sin(angle)) - (tempZ * cos(angle));
// log the new point
cout << "(" << newX << ", " << newY << ", " << newZ << ")\n";
// render the new point
glVertex3d(newX, newY, newZ);
}
Это не приводит к выводу экрана, но вывод консоли:
(0.048, -0.296, 0.0) by 0 radians = (0.048, -0.296, 0)
(0.376, -0.508, 0.0) by 0 radians = (0.376, -0.508, 0)
(0.72, -0.204, 0.0) by 0 radians = (0.72, -0.204, 0)
(0.652, 0.176, 0.0) by 0 radians = (0.652, 0.176, 0)
(0.368, 0.504, 0.0) by 0 radians = (0.368, 0.504, 0)
(0.048, -0.296, 0.0) by 0.628319 radians = (0.0388328, -0.296, 0.0282137)
(0.376, -0.508, 0.0) by 0.628319 radians = (0.30419, -0.508, 0.221007)
(0.72, -0.204, 0.0) by 0.628319 radians = (0.582492, -0.204, 0.423205)
(0.652, 0.176, 0.0) by 0.628319 radians = (0.527479, 0.176, 0.383236)
(0.368, 0.504, 0.0) by 0.628319 radians = (0.297718, 0.504, 0.216305)
(0.048, -0.296, 0.0) by 1.25664 radians = (0.0148328, -0.296, 0.0456507)
(0.376, -0.508, 0.0) by 1.25664 radians = (0.11619, -0.508, 0.357597)
(0.72, -0.204, 0.0) by 1.25664 radians = (0.222492, -0.204, 0.684761)
(0.652, 0.176, 0.0) by 1.25664 radians = (0.201479, 0.176, 0.620089)
(0.368, 0.504, 0.0) by 1.25664 radians = (0.113718, 0.504, 0.349989)
...
(0.048, -0.296, 0.0) by 6.28319 radians = (0.048, -0.296, -1.17566e-17)
(0.376, -0.508, 0.0) by 6.28319 radians = (0.376, -0.508, -9.20934e-17)
(0.72, -0.204, 0.0) by 6.28319 radians = (0.72, -0.204, -1.76349e-16)
(0.652, 0.176, 0.0) by 6.28319 radians = (0.652, 0.176, -1.59694e-16)
(0.368, 0.504, 0.0) by 6.28319 radians = (0.368, 0.504, -9.0134e-17)
Я не уверен, что именно здесь происходит, но я ужасно стараюсь понять это, поэтому, пожалуйста, не думайте, что я пытаюсь получить двойную репутацию или что-то в этом роде,Я просто действительно застрял.
РЕДАКТИРОВАТЬ 2: Вот моя целая процедура отображения для моего перспективного подпредставления:
void displayPersp(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode (GL_MODELVIEW);
glLoadIdentity ();
gluLookAt (-2.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0);
// draw the axis
glBegin(GL_LINES);
// x
glVertex3f(500.0, 0.0, 0.0);
glVertex3f(-500.0, 0.0, 0.0);
// y
glVertex3f(0.0, -500.0, 0.0);
glVertex3f(0.0, 500.0, 0.0);
// z
glVertex3f(0.0, 0.0, -500.0);
glVertex3f(0.0, 0.0, 500.0);
glEnd();
cout << endl;
// loop as many number of times as we are going to draw the points around the Y-Axis
for( int i=0; i<=sweepResolutionMod; i++ )
{
cout << endl;
// setup the new angle
double angle = i>0 ? (360/sweepResolutionMod)*i : 0;
angle = angle * (M_PI/180);
// for each point...
for( int i=0; i<clickedPoints.size(); i++ )
{
GLfloat tempX = (clickedPoints[i].x-250)/250;
GLfloat tempY = (clickedPoints[i].y-250)/250;
GLfloat tempZ = 0.0;
cout << "(" << tempX << ", " << tempY << ", 0.0) by " << angle << " degrees = ";
GLfloat newX = (tempX * cos(angle)) - (tempZ * sin(angle));
GLfloat newY = tempY;
GLfloat newZ = (tempX * sin(angle)) - (tempZ * cos(angle));
cout << "(" << newX << ", " << newY << ", " << newZ << ")\n";
glVertex3d(newX, newY, newZ);
}
// the following was my old solution, using OpenGL's rotate(), but that
// didn't allow me to get back the new point's coordinates.
/*
glRotatef(angle, 0.0, 1.0, 0.0);
// draw a line?
if( clickedPoints.size() > 1 )
{
glBegin(GL_LINE_STRIP);
for(int i=0; i<clickedPoints.size(); i++ )
{
glVertex3f((clickedPoints[i].x-250)/250, (clickedPoints[i].y-250)/250, 0.0);
}
glEnd();
}
// everyone gets points
glBegin(GL_POINTS);
for(int i=0; i<clickedPoints.size(); i++ )
{
glVertex3f((clickedPoints[i].x-250)/250, (clickedPoints[i].y-250)/250, 0.0);
}
glEnd();
*/
}
glutSwapBuffers();
}
РЕДАКТИРОВАТЬ 3: Вот ужасная иллюстрацияэто иллюстрирует то, что мне нужно сделать.Я знаю, что перспектива кажется неправильной, но я пытаюсь получить зеленые горизонтали в правом подпредставлении (здесь используется закомментированный код glRotatef () выше):
ЗАКЛЮЧИТЕЛЬНОЕ РЕДАКТИРОВАНИЕ (для будущих поколений!):
Вот то, что я наконец получил, после обсуждения некоторой линейной алгебры с учителем в колледже:
void displayPersp(void)
{
glClear(GL_COLOR_BUFFER_BIT);
gluLookAt (-2.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0);
glMatrixMode (GL_MODELVIEW);
glLoadIdentity ();
// draw the axis
glBegin(GL_LINES);
// x
glVertex3f(500.0, 0.0, 0.0);
glVertex3f(-500.0, 0.0, 0.0);
// y
glVertex3f(0.0, -500.0, 0.0);
glVertex3f(0.0, 500.0, 0.0);
// z
glVertex3f(0.0, 0.0, -500.0);
glVertex3f(0.0, 0.0, 500.0);
glEnd();
cout << endl;
double previousTheta = 0.0;
for( int i=0; i<=sweepResolutionMod; i++ )
{
double theta = i>0 ? (360/sweepResolutionMod)*i : 0;
theta = theta * (M_PI/180);
if( clickedPoints.size() > 1 )
{
// the 'vertical' piece
glBegin(GL_LINE_STRIP);
for(int i=0; i<clickedPoints.size(); i++ )
{
// normalize
GLfloat tempX = (clickedPoints[i].x-250)/250;
GLfloat tempY = (clickedPoints[i].y-250)/250;
GLfloat tempZ = 0.0;
// new points
GLfloat newX = ( tempX * cos(theta) ) + ( tempZ * sin(theta) );
GLfloat newY = tempY;
GLfloat newZ = ( tempZ * cos(theta) ) - ( tempX * sin(theta) );
glVertex3f(newX, newY, newZ);
}
glEnd();
// the 'horizontal' piece
if( previousTheta != theta )
{
glBegin(GL_LINES);
for(int i=0; i<clickedPoints.size(); i++ )
{
// normalize
GLfloat tempX = (clickedPoints[i].x-250)/250;
GLfloat tempY = (clickedPoints[i].y-250)/250;
GLfloat tempZ = 0.0;
// new points
GLfloat newX = ( tempX * cos(theta) ) + ( tempZ * sin(theta) );
GLfloat newY = tempY;
GLfloat newZ = ( tempZ * cos(theta) ) - ( tempX * sin(theta) );
// previous points
GLfloat previousX = ( tempX * cos(previousTheta) ) + ( tempZ * sin(previousTheta) );
GLfloat previousY = tempY;
GLfloat previousZ = ( tempZ * cos(previousTheta) ) - ( tempX * sin(previousTheta) );
// horizontal component
glVertex3f(newX, newY, newZ);
glVertex3f(previousX, previousY, previousZ);
}
glEnd();
}
}
previousTheta = theta;
}
glutSwapBuffers();
}