00001 #ifndef AFFINE_H
00002 #define AFFINE_H
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147 #include "TMatrix.h"
00148 #include "TMatrixUtility.h"
00149 #include "TinyVec.h"
00150 #include "TinyMat.h"
00151 #include "TQuaternion.h"
00152
00153
00154
00155 #ifndef PTM_PACK // 単体で使用する場合は,namespace に入れない
00156 namespace Spr {
00157 #endif
00158
00159 #ifdef _WIN32
00160 #ifdef _DEBUG
00161 #pragma optimize ("awgity", on)
00162 #pragma auto_inline(on)
00163 #pragma inline_recursion(on)
00164 #endif
00165 #endif
00166
00167
00168
00169 #undef M_PI
00170
00171 #ifdef __BORLANDC__
00172 #define M_PI 3.14159265358979323846
00173 #else
00174 const double M_PI = 3.14159265358979323846;
00175 #endif
00176
00177 #undef abs
00178
00179
00180 #ifdef __BORLANDC__
00181 #define DEF_ABS_FUNC(T) inline T abs(T t){ return t > T() ? t : -t; }
00182 DEF_ABS_FUNC(float)
00183 DEF_ABS_FUNC(double)
00184 DEF_ABS_FUNC(char)
00185 DEF_ABS_FUNC(int)
00186 DEF_ABS_FUNC(long)
00187 #else
00188 template <class T> T abs(T t){ return t > T() ? t : -t; }
00189 #endif
00190
00191 #undef sign
00192
00193 template <class T> T sign(T t){
00194 return t > T() ? T(1) : T(-1);
00195 }
00196
00197 #undef min
00198
00199 template <class T> T min(T a, T b){return a < b ? a : b;}
00200
00201 #undef max
00202
00203 template <class T> T max(T a, T b){return a > b ? a : b;}
00204
00205
00206 inline double Rad(double deg){
00207 return ((double)deg/360*2*M_PI);
00208 }
00209 inline float Radf(double deg){
00210 return (float)((double)deg/360*2*M_PI);
00211 }
00212
00213 inline double Deg(double rad){
00214 return (rad/(2*M_PI)) * 360;
00215 }
00216 inline float Degf(double rad){
00217 return (float)(rad/(2*M_PI)) * 360;
00218 }
00219
00220 template <class SC>
00221 inline SC Square(SC x){
00222 return x*x;
00223 }
00224
00225 template <class SC>
00226 inline SC Det2(SC a, SC b, SC c, SC d){
00227 return ((a)*(d) - (b)*(c));
00228 }
00229
00230
00231
00232
00233
00234 template <class T>
00235 class TAffine2:public PTM::TMatrixBase<DIMENC(3),DIMENC(3),
00236 PTM::TMatrixDescCol< TAffine2<T>, PTM::TMatrixRow<3,3,T>, 3,3,3,T> >{
00237 public:
00238 typedef PTM::TMatrixDescCol< TAffine2<T>, PTM::TMatrixRow<3,3,T>, 3,3,3,T> desc;
00239 typedef PTM::TMatrixBase<DIMENC(3),DIMENC(3),desc> base_type;
00240
00241 DEF_MATRIX_BASIC_MEMBER(TAffine2);
00242 union{
00243 struct{
00244 T xx, xy, xz;
00245 T yx, yy, yz;
00246 T px, py, pz;
00247 };
00248 T data[3][3];
00249 };
00250
00251 element_type& item_impl(size_t i, size_t j){ return data[j][i]; }
00252 const element_type& item_impl(size_t i, size_t j) const { return data[j][i]; }
00253
00254
00255
00256
00257 TVec2<element_type>& Ex(){
00258 return *(TVec2<element_type>*) &item(0,0);
00259 }
00260
00261 const TVec2<element_type>& Ex() const{
00262 return *(TVec2<element_type>*) &item(0,0);
00263 }
00264
00265 TVec2<element_type>& Ey(){
00266 return *(TVec2<element_type>*) &item(0,1);
00267 }
00268
00269 const TVec2<element_type>& Ey() const{
00270 return *(TVec2<element_type>*) &item(0,1);
00271 }
00272
00273 TVec2<element_type>& Trn(){
00274 return *(TVec2<element_type>*) &item(0,2);
00275 }
00276
00277 const TVec2<element_type>& Trn() const{
00278 return *(TVec2<element_type>*) &item(0,2);
00279 }
00280
00281 TVec2<element_type>& Pos(){ return Trn(); }
00282
00283 const TVec2<element_type>& Pos() const { return Trn(); }
00284
00285
00286
00287
00288
00289 element_type& ExX() {return Ex().X();}
00290
00291 element_type& ExY() {return Ex().Y();}
00292
00293 element_type& EyX() {return Ey().X();}
00294
00295 element_type& EyY() {return Ey().Y();}
00296
00297 element_type& TrnX() {return Trn().X();}
00298
00299 element_type& TrnY() {return Trn().Y();}
00300
00301 element_type& PosX() {return Trn().X();}
00302
00303 element_type& PosY() {return Trn().Y();}
00304
00305
00306
00307 PTM::TSubMatrixCol<2,2, desc>& Rot() { return sub_matrix(0,0,PTM::TSubMatrixCol<2,2, desc>()); }
00308
00309 const PTM::TSubMatrixCol<2,2, desc>& Rot() const { return sub_matrix(0,0,PTM::TSubMatrixCol<2,2, desc>()); }
00310
00311
00312
00313
00314 static TAffine2<T> Unit(){
00315 TAffine2<T> y;
00316 PTM::init_unitize(y);
00317 return y;
00318 }
00319
00320 static TAffine2<T> Trn(element_type px, element_type py){
00321 TAffine2<T> y;
00322 y.Trn().X() = px;
00323 y.Trn().Y() = py;
00324 return y;
00325 }
00326
00327 static TAffine2<T> Rot(element_type th, int d=0){
00328 TAffine2 y;
00329 PTM::init_rot(y.Rot(), th);
00330 return y;
00331 }
00332
00333 static TAffine2<T> Scale(element_type sx, element_type sy){
00334 TAffine2<T> y;
00335 y.item(0, 0) = sx; y.item(1, 1) = sy;
00336 return y;
00337 }
00338
00339 void set_default(){PTM::init_unitize(*this);}
00340
00341 };
00342
00343
00344
00345
00346 template <class T>
00347 class TAffine:public PTM::TMatrixBase<DIMENC(4),DIMENC(4),
00348 PTM::TMatrixDescCol< TAffine<T>, PTM::TMatrixRow<4,4,T>, 4,4,4,T> >{
00349 public:
00350 typedef PTM::TMatrixDescCol< TAffine<T>, PTM::TMatrixRow<4,4,T>, 4,4,4,T> desc;
00351 typedef PTM::TMatrixBase<DIMENC(4),DIMENC(4),desc> base_type;
00352
00353
00354 DEF_MATRIX_BASIC_MEMBER(TAffine);
00355 union{
00356 struct{
00357 T xx, xy, xz, xw;
00358 T yx, yy, yz, yw;
00359 T zx, zy, zz, zw;
00360 T px, py, pz, pw;
00361 };
00362 T data[4][4];
00363 };
00364
00365 element_type& item_impl(size_t i, size_t j){ return data[j][i]; }
00366 const element_type& item_impl(size_t i, size_t j) const { return data[j][i]; }
00367
00368
00369
00370
00371 TVec3<element_type>& Ex() { return (TVec3<element_type>&)col(0); }
00372
00373 const TVec3<element_type>& Ex() const { return (TVec3<element_type>&)col(0); }
00374
00375 TVec3<element_type>& Ey() { return (TVec3<element_type>&)col(1); }
00376
00377 const TVec3<element_type>& Ey() const { return (TVec3<element_type>&)col(1); }
00378
00379 TVec3<element_type>& Ez() { return (TVec3<element_type>&)col(2); }
00380
00381 const TVec3<element_type>& Ez() const { return (TVec3<element_type>&)col(2); }
00382
00383 TVec3<element_type>& Trn() { return (TVec3<element_type>&)col(3); }
00384
00385 const TVec3<element_type>& Trn() const { return (TVec3<element_type>&)col(3); }
00386
00387 TVec3<element_type>& Pos() {return Trn();}
00388
00389 const TVec3<element_type>& Pos() const {return Trn();}
00390
00391
00392
00393
00394
00395 element_type& ExX() {return Ex().X();}
00396 const element_type& ExX() const {return Ex().X();}
00397
00398 element_type& ExY() {return Ex().Y();}
00399 const element_type& ExY() const {return Ex().Y();}
00400
00401 element_type& ExZ() {return Ex().Z();}
00402 const element_type& ExZ() const {return Ex().Z();}
00403
00404 element_type& EyX() {return Ey().X();}
00405 const element_type& EyX() const {return Ey().X();}
00406
00407 element_type& EyY() {return Ey().Y();}
00408 const element_type& EyY() const {return Ey().Y();}
00409
00410 element_type& EyZ() {return Ey().Z();}
00411 const element_type& EyZ() const {return Ey().Z();}
00412
00413 element_type& EzX() {return Ez().X();}
00414 const element_type& EzX() const {return Ez().X();}
00415
00416 element_type& EzY() {return Ez().Y();}
00417 const element_type& EzY() const {return Ez().Y();}
00418
00419 element_type& EzZ() {return Ez().Z();}
00420 const element_type& EzZ() const {return Ez().Z();}
00421
00422 element_type& TrnX() {return Trn().X();}
00423 const element_type& TrnX() const {return Trn().X();}
00424
00425 element_type& TrnY() {return Trn().Y();}
00426 const element_type& TrnY() const {return Trn().Y();}
00427
00428 element_type& TrnZ() {return Trn().Z();}
00429 const element_type& TrnZ() const {return Trn().Z();}
00430
00431 element_type& PosX() {return TrnX();}
00432 const element_type& PosX() const {return TrnX();}
00433
00434 element_type& PosY() {return TrnY();}
00435 const element_type& PosY() const {return TrnY();}
00436
00437 element_type& PosZ() {return TrnZ();}
00438 const element_type& PosZ() const {return TrnZ();}
00439
00440 element_type& ExW() {return item(3,0);}
00441 const element_type& ExW() const {return item(3,0);}
00442
00443 element_type& EyW() {return item(3,1);}
00444 const element_type& EyW() const {return item(3,1);}
00445
00446 element_type& EzW() {return item(3,2);}
00447 const element_type& EzW() const {return item(3,2);}
00448
00449 element_type& TrnW() {return item(3,3);}
00450 const element_type& TrnW() const {return item(3,3);}
00451
00452 element_type& PosW() {return item(3,3);}
00453 const element_type& PosW() const {return item(3,3);}
00454
00455
00456
00457 PTM::TSubMatrixCol<3,3, desc>& Rot(){ return sub_matrix(PTM::TSubMatrixDim<0,0,3,3>()); }
00458
00459 const PTM::TSubMatrixCol<3,3, desc>& Rot() const { return sub_matrix(PTM::TSubMatrixDim<0,0,3,3>()); }
00460
00461
00462
00463 static TAffine<T> Unit(){
00464 TAffine<T> y;
00465 PTM::init_unitize(y);
00466 return y;
00467 }
00468
00469 static TAffine<T> Trn(element_type px, element_type py, element_type pz){
00470 TAffine<T> y;
00471 y.Trn().X() = px;
00472 y.Trn().Y() = py;
00473 y.Trn().Z() = pz;
00474 return y;
00475 }
00476
00477 static TAffine<T> Rot(element_type th, char axis)
00478 {
00479 TAffine<T> y;
00480 #ifdef __BORLANDC__
00481 TMatrix3<T> r = y.Rot();
00482 PTM::init_rot(r, th, axis);
00483 #else
00484 PTM::init_rot(y.Rot(), th, axis);
00485 #endif
00486 return y;
00487 }
00488
00489
00490
00491
00492
00493
00494 template <class BUF>
00495 static TAffine<T> Rot(element_type th, const PTM::TVectorBase<DIMENC(3), BUF>& axis)
00496 {
00497 TAffine<T> y;
00498 Matrix3f r;
00499 PTM::init_rot(r, th, axis);
00500 y.Rot() = r;
00501 return y;
00502 }
00503
00504 static TAffine<T> Scale(element_type sx, element_type sy, element_type sz){
00505 TAffine<T> y;
00506 y.item(0, 0) = sx; y.item(1, 1) = sy; y.item(2, 2) = sz;
00507 return y;
00508 }
00509
00510
00511
00512
00513
00514 template <class BUFS, class BUFZ>
00515 static TAffine<T> ProjectionGL(
00516 const PTM::TVectorBase<DIMENC(3), BUFS>& screen,
00517 const PTM::TVectorBase<DIMENC(2), BUFZ>& size,
00518 element_type front=1.0f, element_type back=10000.0f)
00519 {
00520 TAffine<T> y;
00521 PTM::init_projection_gl(y, screen, size, front, back);
00522 return y;
00523 }
00524
00525
00526
00527
00528
00529 template <class BUFS, class BUFZ>
00530 static TAffine<T> ProjectionD3D(const PTM::TVectorBase<DIMENC(3), BUFS>& screen,
00531 const PTM::TVectorBase<DIMENC(2), BUFZ>& size,
00532 element_type front=1.0f, element_type back=10000.0f)
00533 {
00534 TAffine<T> y;
00535 PTM::init_projection_d3d(y, screen, size, front, back);
00536 return y;
00537 }
00538
00539
00540 template <class BUF>
00541 void LookAt(const PTM::TVectorBase<DIMENC(3), BUF>& posi)
00542 {
00543 PTM::init_look_at(*this, posi);
00544 }
00545
00546 template <class BUFZ, class BUFY>
00547 void LookAt(const PTM::TVectorBase<DIMENC(3), BUFZ>& posz, const PTM::TVectorBase<DIMENC(3), BUFY>& posy)
00548 {
00549 PTM::init_look_at(*this, posz, posy);
00550 }
00551
00552 template <class BUF>
00553 void LookAtGL(const PTM::TVectorBase<DIMENC(3), BUF>& posi)
00554 {
00555 PTM::init_look_at_gl(*this, posi);
00556 }
00557
00558 template <class BUFZ, class BUFY>
00559 void LookAtGL(const PTM::TVectorBase<DIMENC(3), BUFZ>& posz, const PTM::TVectorBase<DIMENC(3), BUFY>& posy)
00560 {
00561 PTM::init_look_at_gl(*this, posz, posy);
00562 }
00563
00564
00565 void set_default(){PTM::init_unitize(*this);}
00566 };
00567 #define DEF_TAFFINE_CONSTRUCTORS(TAffine) \
00568 TAffine(){*this=Unit();} \
00569 TAffine(element_type px, element_type py, element_type pz){*this=Trn(px, py, pz);} \
00570 template <class BUFX, class BUFY> \
00571 TAffine(const PTM::TVectorBase<DIMENC(3), BUFX>& exi, \
00572 const PTM::TVectorBase<DIMENC(3), BUFY>& eyi){ \
00573 PTM::init_direct(Rot(), exi, eyi, 'x'); \
00574 item(3, 0) = 0; item(3, 1) = 0; item(3, 2) = 0; item(3, 3) = 1; \
00575 item(0, 3) = 0; item(1, 3) = 0; item(2, 3) = 0; \
00576 } \
00577 template <class BUFX, class BUFY, class BUFP> \
00578 TAffine( const PTM::TVectorBase<DIMENC(3), BUFX>& exi, \
00579 const PTM::TVectorBase<DIMENC(3), BUFY>& eyi, \
00580 const PTM::TVectorBase<DIMENC(3), BUFP>& posi){ \
00581 PTM::init_direct(Rot(), exi, eyi, 'x'); \
00582 item(3, 0) = 0; item(3, 1) = 0; item(3, 2) = 0; item(3, 3) = 1; \
00583 item(0, 3) = posi.X(); item(1, 3) = posi.Y(); item(2, 3) = posi.Z(); \
00584 } \
00585 template <class BUFA, class BUFB> \
00586 TAffine( const PTM::TVectorBase<DIMENC(3), BUFA>& a, \
00587 const PTM::TVectorBase<DIMENC(3), BUFB>& b, \
00588 char axis){ \
00589 PTM::init_direct(Rot(), exi, eyi, axis); \
00590 item(3, 0) = 0; item(3, 1) = 0; item(3, 2) = 0; item(3, 3) = 1; \
00591 item(0, 3) = 0; item(1, 3) = 0; item(2, 3) = 0; \
00592 } \
00593 template <class BUFA, class BUFB, class BUFP> \
00594 TAffine( const PTM::TVectorBase<DIMENC(3), BUFA>& a, \
00595 const PTM::TVectorBase<DIMENC(3), BUFB>& b, \
00596 char axis, const PTM::TVectorBase<DIMENC(3), BUFP>& posi){ \
00597 PTM::init_direct(Rot(), exi, eyi, axis); \
00598 item(3, 0) = 0; item(3, 1) = 0; item(3, 2) = 0; item(3, 3) = 1; \
00599 item(0, 3) = posi.X(); item(1, 3) = posi.Y(); item(2, 3) = posi.Z(); \
00600 }
00601
00602 #define DEF_TAFFINE_CONSTRUCTORS2(TAffine) \
00603 TAffine(element_type th, char axis) { \
00604 *this=Rot(th, axis); \
00605 } \
00606 template <class BUF> \
00607 TAffine(element_type th, char axis, \
00608 const PTM::TVectorBase<DIMENC(3), BUF>& posi) { \
00609 *this = Rot(th, axis); Pos() = posi; } \
00610 template <class BUFA> \
00611 TAffine(element_type th, const PTM::TVectorBase<DIMENC(3), BUFA>& axis){ \
00612 *this = Rot(th, axis.unit()); \
00613 } \
00614 template <class BUFA, class BUFP> \
00615 TAffine(element_type th, const PTM::TVectorBase<DIMENC(3), BUFA>& axis , const PTM::TVectorBase<DIMENC(3), BUFP>& posi){ \
00616 *this = Rot(th, axis.unit()); Pos() = posi; \
00617 } \
00618 template <class BUFS, class BUFZ> \
00619 TAffine(const PTM::TVectorBase<DIMENC(3), BUFS>& screen, const PTM::TVectorBase<DIMENC(2), BUFZ>& size, element_type front=1.0f, element_type back=10000.0f){ \
00620 *this = ProjectionGL(screen, size, front, back); \
00621 } \
00622 template <class BUF, class BUFV> \
00623 TAffine(const PTM::TMatrixOp<3, 3, BUF>& m, const PTM::TVectorBase<DIMENC(3), BUFV> posi){\
00624 Rot() = m; Pos() = posi; ExW() = 0; EyW() = 0; EzW() = 0; PosW() = 1; \
00625 }
00626
00627
00628 #ifdef _WIN32
00629 #pragma warning (disable: 4700)
00630 #endif
00631
00632 template <class T, class TV>
00633 TVec3<TV> operator * (
00634 const TAffine<T>& a,
00635 const TVec3<TV>& b){
00636 TVec3<TV> r;
00637 r[0] = a[0][0]*b[0] + a[0][1]*b[1] + a[0][2]*b[2] + a[0][3];
00638 r[1] = a[1][0]*b[0] + a[1][1]*b[1] + a[1][2]*b[2] + a[1][3];
00639 r[2] = a[2][0]*b[0] + a[2][1]*b[1] + a[2][2]*b[2] + a[2][3];
00640 return r;
00641 }
00642 #ifdef _WIN32
00643 #pragma warning (default: 4700)
00644 #endif
00645
00646
00647 typedef TAffine2<float> Affine2f;
00648
00649 typedef TAffine2<double> Affine2d;
00650
00651 typedef TAffine<float> Affinef;
00652
00653 typedef TAffine<double> Affined;
00654
00655
00656 #ifdef _WIN32
00657 #ifdef _DEBUG
00658 #pragma optimize ("", on)
00659 #pragma auto_inline(off)
00660 #pragma inline_recursion(off)
00661 #endif
00662 #endif
00663
00664 #ifndef PTM_PACK // 単体で使用する場合は,namespace に入れない
00665 }
00666 #endif
00667
00668 #endif