1 | // This file is a part of Framsticks GDK library. |
---|
2 | // Copyright (C) 2002-2006 Szymon Ulatowski. See LICENSE.txt for details. |
---|
3 | // Refer to http://www.frams.alife.pl/ for further information. |
---|
4 | |
---|
5 | #ifndef _3D_H_ |
---|
6 | #define _3D_H_ |
---|
7 | |
---|
8 | #include <memory.h> |
---|
9 | |
---|
10 | /********************************** |
---|
11 | \file 3d.h 3d.cpp |
---|
12 | |
---|
13 | basic 3d classes and operators |
---|
14 | *********************************/ |
---|
15 | |
---|
16 | /// point in 3d space |
---|
17 | |
---|
18 | class Pt3D |
---|
19 | { |
---|
20 | public: double x,y,z; |
---|
21 | static bool report_errors; |
---|
22 | |
---|
23 | Pt3D(double _x,double _y,double _z):x(_x),y(_y),z(_z) {} ///< constructor initializing all coords |
---|
24 | Pt3D(double xyz):x(xyz),y(xyz),z(xyz) {} ///< all coords equal |
---|
25 | Pt3D() {} ///< coords will be not initialized! |
---|
26 | Pt3D(const Pt3D &p):x(p.x),y(p.y),z(p.z) {} ///< copy from another point |
---|
27 | bool operator==(const Pt3D& p) {return (x==p.x)&&(y==p.y)&&(z==p.z);} |
---|
28 | void operator+=(const Pt3D& p) {x+=p.x;y+=p.y;z+=p.z;} |
---|
29 | void operator-=(const Pt3D& p) {x-=p.x;y-=p.y;z-=p.z;} |
---|
30 | void operator*=(double d) {x*=d;y*=d;z*=d;} |
---|
31 | Pt3D operator*(const Pt3D &p) const {return Pt3D(y*p.z-z*p.y, z*p.x-x*p.z, x*p.y-y*p.x);} |
---|
32 | void operator/=(double d) {x/=d; y/=d; z/=d;} |
---|
33 | //Pt3D operator+(const Pt3D& p) const {return Pt3D(x+p.x,y+p.y,z+p.z);} |
---|
34 | //Pt3D operator-(const Pt3D& p) const {return Pt3D(x-p.x,y-p.y,z-p.z);} |
---|
35 | Pt3D operator-() const {return Pt3D(-x,-y,-z);} |
---|
36 | Pt3D operator*(double d) const {return Pt3D(x*d,y*d,z*d);} |
---|
37 | Pt3D operator/(double d) const {return Pt3D(x/d,y/d,z/d);} |
---|
38 | int operator<(const Pt3D& p) const {return (x<p.x)&&(y<p.y)&&(z<p.z);} |
---|
39 | ///< check if all coords are below the second point |
---|
40 | int operator>(const Pt3D& p) const {return (x>p.x)&&(y>p.y)&&(z>p.z);} |
---|
41 | ///< check if all coords are above the second point |
---|
42 | int operator<=(const Pt3D& p) const {return (x<p.x)||(y<p.y)||(z<p.z);} |
---|
43 | ///< check if some coords are below the second point |
---|
44 | int operator>=(const Pt3D& p) const {return (x>p.x)||(y>p.y)||(z>p.z);} |
---|
45 | ///< check if some coords are above the second point |
---|
46 | void getMin(const Pt3D& p); |
---|
47 | void getMax(const Pt3D& p); |
---|
48 | /** vector length = \f$\sqrt{x^2+y^2+z^2}\f$ */ |
---|
49 | double operator()() const; |
---|
50 | /** vector length = \f$\sqrt{x^2+y^2+z^2}\f$ */ |
---|
51 | double length() const {return operator()();} |
---|
52 | double distanceTo(const Pt3D& p) const; |
---|
53 | double manhattanDistanceTo(const Pt3D& p) const; |
---|
54 | /** calculate angle between (0,0)-(dx,dy), @return 1=ok, 0=can't calculate */ |
---|
55 | static int getAngle(double dx,double dy,double &angle); |
---|
56 | /** calculate 3 rotation angles translating (1,0,0) into 'X' and (0,0,1) into 'dir' */ |
---|
57 | void getAngles(const Pt3D& X,const Pt3D& dir); |
---|
58 | void vectorProduct(const Pt3D& a,const Pt3D& b); |
---|
59 | bool normalize(); |
---|
60 | }; |
---|
61 | Pt3D operator+(const Pt3D &p1,const Pt3D &p2); |
---|
62 | Pt3D operator-(const Pt3D &p1,const Pt3D &p2); |
---|
63 | |
---|
64 | class Pt3D_DontReportErrors |
---|
65 | { |
---|
66 | bool state; |
---|
67 | public: |
---|
68 | Pt3D_DontReportErrors() {state=Pt3D::report_errors; Pt3D::report_errors=false;} |
---|
69 | ~Pt3D_DontReportErrors() {Pt3D::report_errors=state;} |
---|
70 | }; |
---|
71 | |
---|
72 | /// orientation in 3d space = rotation matrix |
---|
73 | |
---|
74 | class Matrix44; |
---|
75 | |
---|
76 | class Orient |
---|
77 | { |
---|
78 | public: Pt3D x,y,z; ///< 3 vectors (= 3x3 matrix) |
---|
79 | |
---|
80 | Orient() {} |
---|
81 | Orient(const Orient& src) {x=src.x; y=src.y; z=src.z;} |
---|
82 | Orient(const Pt3D& a,const Pt3D& b,const Pt3D& c):x(a),y(b),z(c) {} |
---|
83 | // Orient(const Pt3D& rot) {*this=rot;} |
---|
84 | Orient(const Matrix44& m); |
---|
85 | void operator=(const Pt3D &rot); |
---|
86 | void rotate(const Pt3D &); ///< rotate matrix around 3 axes |
---|
87 | |
---|
88 | void transform(Pt3D &target,const Pt3D &src) const; ///< transform a vector |
---|
89 | void revTransform(Pt3D &target,const Pt3D &src) const; ///< reverse transform |
---|
90 | Pt3D transform(const Pt3D &src) const {Pt3D t; transform(t,src); return t;} |
---|
91 | Pt3D revTransform(const Pt3D &src) const {Pt3D t; revTransform(t,src); return t;} |
---|
92 | |
---|
93 | void transform(Orient& target,const Orient& src) const; ///< transform other orient |
---|
94 | void revTransform(Orient& target,const Orient& src) const; ///< reverse transform other orient |
---|
95 | |
---|
96 | void transform(const Orient &rot) {Orient tmp; rot.transform(tmp,*this); *this=tmp;} |
---|
97 | void revTransform(const Orient &rot) {Orient tmp; rot.revTransform(tmp,*this); *this=tmp;} |
---|
98 | |
---|
99 | void getAngles(Pt3D &) const; ///< calculate rotation from current matrix |
---|
100 | void lookAt(const Pt3D &X,const Pt3D &dir); ///< calculate orientation matrix from 2 vectors |
---|
101 | |
---|
102 | bool normalize(); |
---|
103 | }; |
---|
104 | |
---|
105 | class Matrix44 |
---|
106 | { |
---|
107 | public: |
---|
108 | double m[16]; |
---|
109 | Matrix44() {} |
---|
110 | Matrix44(const Matrix44& src) {memcpy(m,src.m,sizeof(m));} |
---|
111 | Matrix44(double *srcm) {memcpy(m,srcm,sizeof(m));} |
---|
112 | Matrix44(const Orient &rot); |
---|
113 | |
---|
114 | const double& operator()(int i,int j) const {return m[i+16*j];} |
---|
115 | const double& operator[](int i) const {return m[i];} |
---|
116 | double& operator()(int i,int j) {return m[i+16*j];} |
---|
117 | double& operator[](int i) {return m[i];} |
---|
118 | |
---|
119 | void operator+=(const Pt3D &); ///< translate matrix |
---|
120 | void operator*=(const Pt3D &); ///< scale matrix |
---|
121 | void operator*=(double sc); ///< scale matrix |
---|
122 | }; |
---|
123 | |
---|
124 | extern Pt3D Pt3D_0; ///< zero vector |
---|
125 | extern Orient Orient_1; ///< standard unit matrix: 100 010 001 |
---|
126 | extern Matrix44 Matrix44_1; ///< standard unit matrix: 1000 0100 0010 0001 |
---|
127 | |
---|
128 | void rotate2D(double,double &,double &); ///< rotate 2d vector, given angle |
---|
129 | void rotate2D(double,double,double &,double &); ///< rotate 2d vector, given sin and cos |
---|
130 | double d2(double,double); ///< distance in 2D |
---|
131 | |
---|
132 | #endif |
---|
133 | |
---|