| 1 | // This file is a part of the Framsticks GDK library. |
|---|
| 2 | // Copyright (C) 2002-2011 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 | bool normalize(); |
|---|
| 65 | }; |
|---|
| 66 | Pt3D operator+(const Pt3D &p1,const Pt3D &p2); |
|---|
| 67 | Pt3D operator-(const Pt3D &p1,const Pt3D &p2); |
|---|
| 68 | |
|---|
| 69 | class Pt3D_DontReportErrors |
|---|
| 70 | { |
|---|
| 71 | bool state; |
|---|
| 72 | public: |
|---|
| 73 | Pt3D_DontReportErrors() {state=Pt3D::report_errors; Pt3D::report_errors=false;} |
|---|
| 74 | ~Pt3D_DontReportErrors() {Pt3D::report_errors=state;} |
|---|
| 75 | }; |
|---|
| 76 | |
|---|
| 77 | /// orientation in 3d space = rotation matrix |
|---|
| 78 | |
|---|
| 79 | class Matrix44; |
|---|
| 80 | |
|---|
| 81 | class Orient |
|---|
| 82 | { |
|---|
| 83 | public: Pt3D x,y,z; ///< 3 vectors (= 3x3 matrix) |
|---|
| 84 | |
|---|
| 85 | Orient() {} |
|---|
| 86 | Orient(const Orient& src) {x=src.x; y=src.y; z=src.z;} |
|---|
| 87 | Orient(const Pt3D& a,const Pt3D& b,const Pt3D& c):x(a),y(b),z(c) {} |
|---|
| 88 | // Orient(const Pt3D& rot) {*this=rot;} |
|---|
| 89 | Orient(const Matrix44& m); |
|---|
| 90 | void operator=(const Pt3D &rot); |
|---|
| 91 | void rotate(const Pt3D &); ///< rotate matrix around 3 axes |
|---|
| 92 | |
|---|
| 93 | void transform(Pt3D &target,const Pt3D &src) const; ///< transform a vector |
|---|
| 94 | void revTransform(Pt3D &target,const Pt3D &src) const; ///< reverse transform |
|---|
| 95 | Pt3D transform(const Pt3D &src) const {Pt3D t; transform(t,src); return t;} |
|---|
| 96 | Pt3D revTransform(const Pt3D &src) const {Pt3D t; revTransform(t,src); return t;} |
|---|
| 97 | |
|---|
| 98 | void transform(Orient& target,const Orient& src) const; ///< transform other orient |
|---|
| 99 | void revTransform(Orient& target,const Orient& src) const; ///< reverse transform other orient |
|---|
| 100 | |
|---|
| 101 | void transform(const Orient &rot) {Orient tmp; rot.transform(tmp,*this); *this=tmp;} |
|---|
| 102 | void revTransform(const Orient &rot) {Orient tmp; rot.revTransform(tmp,*this); *this=tmp;} |
|---|
| 103 | |
|---|
| 104 | void getAngles(Pt3D &) const; ///< calculate rotation from current matrix |
|---|
| 105 | void lookAt(const Pt3D &X,const Pt3D &dir); ///< calculate orientation matrix from 2 vectors |
|---|
| 106 | |
|---|
| 107 | bool normalize(); |
|---|
| 108 | }; |
|---|
| 109 | |
|---|
| 110 | class Matrix44 |
|---|
| 111 | { |
|---|
| 112 | public: |
|---|
| 113 | double m[16]; |
|---|
| 114 | Matrix44() {} |
|---|
| 115 | Matrix44(const Matrix44& src) {memcpy(m,src.m,sizeof(m));} |
|---|
| 116 | Matrix44(double *srcm) {memcpy(m,srcm,sizeof(m));} |
|---|
| 117 | Matrix44(const Orient &rot); |
|---|
| 118 | |
|---|
| 119 | const double& operator()(int i,int j) const {return m[i+16*j];} |
|---|
| 120 | const double& operator[](int i) const {return m[i];} |
|---|
| 121 | double& operator()(int i,int j) {return m[i+16*j];} |
|---|
| 122 | double& operator[](int i) {return m[i];} |
|---|
| 123 | |
|---|
| 124 | void operator+=(const Pt3D &); ///< translate matrix |
|---|
| 125 | void operator*=(const Pt3D &); ///< scale matrix |
|---|
| 126 | void operator*=(double sc); ///< scale matrix |
|---|
| 127 | }; |
|---|
| 128 | |
|---|
| 129 | extern Pt3D Pt3D_0; ///< zero vector |
|---|
| 130 | extern Orient Orient_1; ///< standard unit matrix: 100 010 001 |
|---|
| 131 | extern Matrix44 Matrix44_1; ///< standard unit matrix: 1000 0100 0010 0001 |
|---|
| 132 | |
|---|
| 133 | void rotate2D(double,double &,double &); ///< rotate 2d vector, given angle |
|---|
| 134 | void rotate2D(double,double,double &,double &); ///< rotate 2d vector, given sin and cos |
|---|
| 135 | double d2(double,double); ///< distance in 2D |
|---|
| 136 | |
|---|
| 137 | #endif |
|---|