#include <cmath> namespace nu { typedef float real_t; inline real_t to_radian(real_t degree) { return degree * (real_t)3.14159265358979 / (real_t)180.0; } //! @brief 回転行列作成 //! @param [out] m 結果を格納する要素数16の配列 //! @param [in] angle_degree 回転角を度で指定 //! @param [in] x 回転軸のX成分 //! @param [in] y 回転軸のY成分 //! @param [in] z 回転軸のZ成分 //! @return なし void myrotate( real_t* m, real_t angle_degree, real_t x, real_t y, real_t z) { //len(x y z) != 0ならnormalizeする real_t len = sqrt(x * x + y * y + z * z); if (abs(1.0 - len) > 0.000001) { x = x / len; y = y / len; z = z / len; } real_t angle_rad = to_radian(angle_degree); real_t c = std::cos(angle_rad); real_t s = std::sin(angle_rad); m[0] = x * x * (1 - c) + c; m[1] = y * x * (1 - c) + z * s; m[2] = x * z * (1 - c) - y * s; m[3] = 0.0; m[4] = x * y * (1 - c) - z * s; m[5] = y * y * (1 - c) + c; m[6] = y * z * (1 - c) + x * s; m[7] = 0.0; m[8] = x * z * (1 - c) + y * s; m[9] = y * z * (1 - c) - x * s; m[10] = z * z * (1 - c) + c; m[11] = 0.0; m[12] = 0.0; m[13] = 0.0; m[14] = 0.0; m[15] = 1.0; } }
#include <windows.h> #include <gl/GLU.h> #include <gl/freeglut.h> #include <cstdio> //検証用 #include <cassert> //自前実装版glRotate #include "myrotate.h" #pragma comment(lib,"opengl32.lib") #pragma comment(lib,"glu32.lib") #pragma comment(lib,"freeglut.lib") void display(void) { GLfloat glrmat[16]; //gl関数で生成 GLfloat myrmat[16]; //自分関数で生成 //glRotate,myrotateへの入力の値を色々変える static int i = 0; i++; GLfloat x = 1.0+i; GLfloat y = 1.0 * (i * 0.1); GLfloat z = 1.0 * (i / 0.2); GLfloat angle=i+25; glMatrixMode(GL_MODELVIEW); glLoadIdentity(); //openglで計算 glRotatef(angle, x, y, z); glGetFloatv(GL_MODELVIEW_MATRIX, glrmat); //自前計算 nu::myrotate(myrmat,angle,x,y,z); puts("----------------------------------------------"); printf("** %d :: %lf %lf %lf %lf\n", i,angle,x,y,z); for (int k = 0; k < 16; k++) { //比較 printf("m[%2d] %+5.10lf %+5.10lf \n", k, glrmat[k], myrmat[k]); //自前計算とglRotate計算の値があまりにかけ離れていたらassertで落ちる assert(abs(glrmat[k] - myrmat[k]) < 0.0001); } puts("----------------------------------------------"); } void mouse(int button, int state, int x, int y) { display(); } int main(int argc, char* argv[]) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGBA); glutCreateWindow(argv[0]); glutInitWindowPosition(0, 0); glutInitWindowSize(100,100); glutDisplayFunc(display); glutMouseFunc(mouse); glutMainLoop(); return 0; }