[121] | 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. |
---|
[109] | 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); |
---|
[139] | 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;} |
---|
[109] | 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 |
---|