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