📄 affine.h
字号:
#ifndef _AFFINE_H#define _AFFINE_H#include <iostream>using namespace std;#include "common.h"// @@@@@@@@@@@@@@@@@@@@@ Affine4 class @@@@@@@@@@@@@@@@ class Affine4 {// manages homogeneous affine transformations // including inverse transformations // and a stack to put them on // used by Scene class to read SDL files public: float m[16]; // hold a 4 by 4 matrix Affine4(){ // make identity transform m[0] = m[5] = m[10] = m[15] = 1.0; m[1] = m[2] = m[3] = m[4] = 0.0; m[6] = m[7] = m[8] = m[9] = 0.0; m[11]= m[12] = m[13] = m[14] = 0.0; } void setIdentityMatrix(){ // make identity transform m[0] = m[5] = m[10] = m[15] = 1.0; m[1] = m[2] = m[3] = m[4] = 0.0; m[6] = m[7] = m[8] = m[9] = 0.0; m[11]= m[12] = m[13] = m[14] = 0.0; } void set(Affine4 a)// set this matrix to a { for(int i = 0; i < 16; i++) m[i]=a.m[i]; } //<<<<<<<<<<<< postMult >>>>>>>>>>> void postMult(Affine4 n){// postmultiplies this with n float sum; Affine4 tmp; tmp.set(*this); // tmp copy for(int c = 0; c < 4; c++)// form this = tmp * n for(int r = 0; r <4 ; r++) { sum = 0; for(int k = 0; k < 4; k++) sum += tmp.m[4 * k + r]* n.m[4 * c + k]; m[4 * c + r] = sum; }// end of for loops } //<<<<<<<<<<<< preMult >>>>>>>>>>> void preMult(Affine4 n){// premultiplies this with n float sum; Affine4 tmp; tmp.set(*this); // tmp copy for(int c = 0; c < 4; c++)// form this = n * tmp for(int r = 0; r <4 ; r++) { sum = 0; for(int k = 0; k < 4; k++) sum += n.m[4 * k + r]* tmp.m[4 * c + k]; m[4 * c + r] = sum; }// end of for loops } void print(void) { for(int i=0; i<4; i++) { for(int j=0; j<4; j++) cout <<m[i*4 + j]<<" "; cout<<endl; } return; } void applyTransform(float v[]) { float q[4]; for(int i=0;i<4; i++) { q[i] = 0; for(int k=0; k < 4; k++) { q[i] += m[4*k + i] * v[k]; } } for(int ii=0; ii<4; ii++) v[ii] = q[ii]; return; } void transpose(Affine4 &t) { for(int i=0; i < 4; i++) for(int j=0; j<4; j++) t.m[i*4 + j] = m[j*4 + i]; return ; }}; // end of Affine4 class //@@@@@@@@@@ AffineNode class @@@@@@@@@@@ class AffineNode{ // used by Scene class to read SDL files public: Affine4 * affn; Affine4 * invAffn; AffineNode * next; AffineNode() { next = NULL; affn = new Affine4; // new affine with identity in it invAffn = new Affine4; // and for the inverse } ~AffineNode() //destructor { delete affn; delete invAffn; } }; //@@@@@@@@@@@@@@@@ AffineStack class @@@@@@@@@@@@ class AffineStack{ // used by Scene class to read SDL files public: AffineNode * tos; AffineStack()//default constructor;puts identity on top { tos = new AffineNode; // node with identity in it tos->next = NULL; } void dup() { AffineNode* tmp = new AffineNode; tmp->affn = new Affine4(*(tos->affn)); tmp->invAffn = new Affine4(*(tos->invAffn)); tmp->next = tos; tos = tmp; } void setIdentity() // make top item the identity matrix { assert(tos != NULL); tos->affn->setIdentityMatrix(); tos->invAffn->setIdentityMatrix(); } void popAndDrop() { if(tos == NULL) return; // do nothing AffineNode *tmp = tos; tos = tos->next; delete tmp; // should call destructor, which deletes trices } void releaseAffines() { // pop and drop all remaining items while(tos) popAndDrop(); } void rotate(float angle, Vector3 u) { Affine4 rm; // make identity matrix Affine4 invRm; u.normalize(); // make the rotation axis unit length float ang = angle * 3.14159265/ 180; // deg to float c = cos(ang), s = sin(ang); float mc = 1.0 - c; //fill the 3x3 upper left matrix - Chap.5 p. 29 rm.m[0] = c + mc * u.x * u.x; rm.m[1] = mc * u.x * u.y + s * u.z; rm.m[2] = mc * u.x * u.z - s * u.y; rm.m[4] = mc * u.y * u.x - s * u.z; rm.m[5] = c + mc * u.y * u.y; rm.m[6] = mc * u.y * u.z + s * u.x; rm.m[8] = mc * u.z * u.x + s * u.y; rm.m[9] = mc * u.z * u.y - s * u.x; rm.m[10] = c + mc * u.z * u.z; // same for inverse : just sign of s is changed invRm.m[0] = c + mc * u.x * u.x; invRm.m[1] = mc * u.x * u.y - s * u.z; invRm.m[2] = mc * u.x * u.z + s * u.y; invRm.m[4] = mc * u.y * u.x + s * u.z; invRm.m[5] = c + mc * u.y * u.y; invRm.m[6] = mc * u.y * u.z - s * u.x; invRm.m[8] = mc * u.z * u.x - s * u.y; invRm.m[9] = mc * u.z * u.y + s * u.x; invRm.m[10] = c + mc * u.z * u.z; tos->affn->postMult(rm); tos->invAffn->preMult(invRm); } void scale(float sx, float sy, float sz) { // post-multiply top item by scaling #define sEps 0.00001 Affine4 scl;// make an identity Affine4 invScl; scl.m[0] = sx; scl.m[5] = sy; scl.m[10] = sz;// adjust it to a scaling matrix if(fabs(sx) < sEps || fabs(sy) < sEps || fabs(sz) < sEps) { cerr << "degenerate scaling transformation!\n"; } invScl.m[0] = 1/sx; invScl.m[5] = 1/sy; invScl.m[10] = 1/sz; tos->affn->postMult(scl); // tos->invAffn->preMult(invScl); } void translate(Vector3 d) { Affine4 tr; // make identity matrix Affine4 invTr; tr.m[12] = d.x; tr.m[13] = d.y; tr.m[14] = d.z; invTr.m[12] = -d.x; invTr.m[13] = -d.y; invTr.m[14] = -d.z; tos->affn->postMult(tr); tos->invAffn->preMult(invTr); } }; #endif // _AFFINE_H
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -