如果没有OpenGL矩阵函数,我不知道如何做到这一点。
通过将每个顶点位置乘以2D来变换三角形 仿射缩放,旋转或平移矩阵,如下所述 通过键盘输入。
键盘输入:
's' key, scale by 1.1 units in X and Y 'r' key, rotate clockwise (in XY plane) by 2.0 degrees 't' key, translate 0.1 unit in X and Y 'q' key, quit program
您不能使用诸如glScale,glTranslate或glRotate之类的OpenGL矩阵函数来执行转换。
这就是我到目前为止......当我构建程序时,三角形不会移动,但是在按下某些键后我会得到随机数,所以我知道它正在做某事:
#include <iostream>
using namespace std;
#include <math.h>
#include <GLUT/glut.h>
void myInit();
void myDraw();
void keyboard( unsigned char, int, int );
float sum;
float theta = 3.14;
int k = 0;
float cVert[3][2]=
{
-1.0, -1.0,
1.0, -1.0,
0.0, 1.0
};
float triVert[3][2] =
{
-1.0, -1.0,
1.0, -1.0,
0.0, 1.0
};
float rotVert[3][3] =
{
1,0,0,
0, cos(theta), -sin(theta),
0, sin(theta), cos(theta)
};
float scaleVert[3][2] =
{
1.1, 0.0,
0.0, 1.1,
0.0, 0.0
};
int main( int argc, char *argv[] )
{
// Initialize window system
glutInit( &argc, argv );
glutInitDisplayMode( GLUT_SINGLE | GLUT_RGB );
glutInitWindowSize( 640, 480 );
glutCreateWindow( "Lab 4" );
// Initialize graphics
myInit();
// Callbacks
glutDisplayFunc( myDraw );
glutKeyboardFunc( keyboard );
// Event loop
glutMainLoop();
}
// Initialize drawing
void myInit()
{
// Background color
glClearColor(0.0, 0.0, 0.0, 1.0);
// 2D world projection
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
gluOrtho2D( -10.0, 10.0, -10.0, 10.0 );
}
// Display callback
void myDraw()
{
// Clear the screen
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT );
// // Draw triangle in initial position
// glColor3f( 1.0, 0.0, 0.0 );
// glBegin( GL_LINE_LOOP );
// glVertex2f( triVert[0][0], triVert[0][1] );
// glVertex2f( triVert[1][0], triVert[1][1] );
// glVertex2f( triVert[2][0], triVert[2][1] );
// glEnd();
// Draw triangle in new position here
glBegin( GL_LINE_LOOP );
glColor3f( 0.0, 1.0, 0.0 );
glVertex2f(cVert[0][0], cVert[0][1]);
glVertex2f(cVert[1][0], cVert[1][1]);
glVertex2f(cVert[2][0], cVert[2][1]);
cout << cVert[3][2] << " ";
glEnd();
// Execute draw commands
glFlush();
}
// Keyboard callback
void keyboard( unsigned char key, int x, int y )
{
// Process keys
switch (key)
{
case 's': //scale by 1.1 units in X and Y
for(k=0;k<3;++k)
{
cVert[3][2] = cVert[3][2]+(scaleVert[3][2]*triVert[3][2]);
cout << cVert[3][2]<<" ";
}
break;
case 'r': //rotate clockwise (in XY plane) by 2.0 degrees
for(k=0;k<3;++k)
{
cVert[3][2] = cVert[3][2]+(rotVert[3][3]*triVert[3][2]);
theta = theta + 2.0;
cout << cVert[3][2]<<" ";
cout << theta << " ";
}
break;
case 't': //translate 0.1 unit in X and Y
break;
case 'q': // exit program
exit(1);
break;
}
// Redraw the scene
glutPostRedisplay();
}
答案 0 :(得分:1)
这个程序的行为是未定义的,所以难怪你得到&#34;随机&#34;号。
cVert[3][2] = cVert[3][2]+(scaleVert[3][2]*triVert[3][2]);
这不执行矩阵加法或乘法。
它只是添加了一个矩阵和一个元素的一个元素的乘积
另一个矩阵到第三个矩阵的一个元素。
或者至少它会这样做,如果这些元素中的任何一个实际上在其中任何一个
矩阵,但实际上cVert
的右下角元素是cVert[2][1]
--remember,C ++编号从零开始的行和列,所以声明
float cVert[3][2]
表示第一个索引有3个值(0,1或2)
第二个有2个值(0或1) -
对于其他两个矩阵也是如此。
你的程序没有崩溃,因此所有这些位置都在可访问的内存中,
但是他们访问的数据与你想要的完全不同。
正如评论中已经指出的那样,矩阵加法和乘法不是内置的 C ++语言本身。您显然是要为它们编写源代码 你自己。您可能希望确定已经查看了矩阵乘法的方法 定义 - 矩阵的直接加法函数有两个嵌套循环, 但是直接的乘法函数有三个嵌套循环。
另一个问题是使用前一个静态初始化rotVert
theta
的静态定义。
本身没有任何问题(虽然也没有太大的好处),
但要了解您稍后对theta
的值所做的更改
not 自动传播回rotVert
。
大括号中rotVert
的初始值设定项在之前评估
main
函数运行,其数值被复制到rotVert
,然后
那段特殊的代码永远不会再使用了。
如果你不小心你的角度单位,你的旋转也会有点疯狂。
您知道sin(theta)
和cos(theta)
会将theta
解释为多个弧度。
如果你完全按照这种方式调用trig函数(使用参数theta
),那么
theta = theta + 2.0;
将添加两个弧度(约114度),而不是2度,
到你的旋转角度。要么弄清楚2度是弧度,
或者每次将它传递给三角函数时,将度数测量角度转换为弧度。
(角度单位的问题目前被这个值掩盖了
在静态初始化之后,theta
实际上从未在旋转矩阵中使用过
你的程序,所以你必须先解决矩阵初始化问题
真的看看角度单位是否正常工作。)