source: cpp/frams/util/3d.h @ 1026

Last change on this file since 1026 was 1022, checked in by Maciej Komosinski, 4 years ago

Cosmetic

  • Property svn:eol-style set to native
File size: 6.1 KB
RevLine 
[286]1// This file is a part of Framsticks SDK.  http://www.framsticks.com/
[1020]2// Copyright (C) 1999-2020  Maciej Komosinski and Szymon Ulatowski.
[286]3// See LICENSE.txt for details.
[109]4
5#ifndef _3D_H_
6#define _3D_H_
7
[225]8#if defined SHP || defined __ANDROID__
[109]9#include <string.h> //memcpy
10#else
11#include <memory.h> //memcpy
12#endif
13
14/**********************************
15\file 3d.h 3d.cpp
16
[255]17basic 3D classes and operators
[109]18*********************************/
19
[255]20/// point in 3D space
[109]21class Pt3D
22{
[255]23public:
24        double x, y, z;
25        static bool report_errors;
[109]26
[255]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
[1020]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; }
[255]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); }
[1020]40        Pt3D    operator*(double d) const { return Pt3D(x * d, y * d, z * d); }
[255]41        Pt3D    operator/(double d) const { return Pt3D(x / d, y / d, z / d); }
[1020]42        bool    allCoordsLowerThan(const Pt3D& p) const { return (x < p.x) && (y < p.y) && (z < p.z); }
43        bool    allCoordsHigherThan(const Pt3D& p) const { return (x > p.x) && (y > p.y) && (z > p.z); }
[255]44        void getMin(const Pt3D& p);
45        void getMax(const Pt3D& p);
[1022]46        double minComponentValue() const;
47        double maxComponentValue() const;
[255]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()(); }
[1020]52        double length2() const { return x * x + y * y + z * z; }
[255]53        double distanceTo(const Pt3D& p) const;
54        double manhattanDistanceTo(const Pt3D& p) const;
55        /** calculate angle between (0,0)-(dx,dy), @return 1=ok, 0=can't calculate */
[305]56        static double getAngle(double dx, double dy);
[255]57        /** calculate 3 rotation angles translating (1,0,0) into 'X' and (0,0,1) into 'dir' */
58        void getAngles(const Pt3D& X, const Pt3D& dir);
59        void vectorProduct(const Pt3D& a, const Pt3D& b);
[1020]60        Pt3D vectorProduct(const Pt3D& p) const { return (*this) * p; }
61        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
62        double dotProduct(const Pt3D& p) const { return x * p.x + y * p.y + z * p.z; }
[255]63        bool normalize();
[109]64};
65
[255]66Pt3D operator+(const Pt3D &p1, const Pt3D &p2);
67Pt3D operator-(const Pt3D &p1, const Pt3D &p2);
68
[109]69class Pt3D_DontReportErrors
70{
[255]71        bool state;
[109]72public:
[255]73        Pt3D_DontReportErrors() { state = Pt3D::report_errors; Pt3D::report_errors = false; }
74        ~Pt3D_DontReportErrors() { Pt3D::report_errors = state; }
[109]75};
76
[255]77///  orientation in 3D space = rotation matrix
[109]78class Matrix44;
79
80class Orient
81{
[255]82public:
83        Pt3D x, y, z; ///< 3 vectors (= 3x3 matrix)
[109]84
85        Orient() {}
[255]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;}
[109]89        Orient(const Matrix44& m);
90        void operator=(const Pt3D &rot);
91        void rotate(const Pt3D &); ///< rotate matrix around 3 axes
92
[255]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; }
[109]97
[255]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        Orient transform(const Orient& src) const { Orient o; transform(o, src); return o; }    ///< transform other orient
101        Orient revTransform(const Orient& src) const { Orient o; revTransform(o, src); return o; } ///< reverse transform other orient
[109]102
[255]103        void transformSelf(const Orient &rot) { Orient tmp; rot.transform(tmp, *this); *this = tmp; }
104        void revTransformSelf(const Orient &rot) { Orient tmp; rot.revTransform(tmp, *this); *this = tmp; }
[109]105
106        void getAngles(Pt3D &) const; ///< calculate rotation from current matrix
[255]107        Pt3D getAngles() const { Pt3D ret; getAngles(ret); return ret; }; ///< calculate rotation from current matrix
108        void lookAt(const Pt3D &X, const Pt3D &dir); ///< calculate orientation matrix from 2 vectors: X becomes (normalized) Orient.x, dir is the preferred "up" direction (Orient.z). Use lookAt(Pt3D) if only X is relevant.
109        void lookAt(const Pt3D &X); ///< calculate orientation matrix from 1 vector, X becomes (normalized) Orient.x, the other coordinates are deterministic but not continuous. Use lookAt(Pt3D,Pt3D) if you need more control.
[109]110
111        bool normalize();
112};
113
114class Matrix44
115{
116public:
[255]117        double m[16];
118        Matrix44() {}
119        Matrix44(const Matrix44& src) { memcpy(m, src.m, sizeof(m)); }
120        Matrix44(double *srcm) { memcpy(m, srcm, sizeof(m)); }
121        Matrix44(const Orient &rot);
[109]122
[255]123        const double& operator()(int i, int j) const { return m[i + 16 * j]; }
124        const double& operator[](int i) const { return m[i]; }
125        double& operator()(int i, int j) { return m[i + 16 * j]; }
126        double& operator[](int i) { return m[i]; }
[109]127
[255]128        void operator+=(const Pt3D &); ///< translate matrix
129        void operator*=(const Pt3D &); ///< scale matrix
130        void operator*=(double sc); ///< scale matrix
[109]131};
132
133extern Pt3D Pt3D_0; ///< zero vector
134extern Orient Orient_1; ///< standard unit matrix: 100 010 001
135extern Matrix44 Matrix44_1; ///< standard unit matrix: 1000 0100 0010 0001
136
[255]137void rotate2D(double, double &, double &); ///< rotate 2d vector, given angle
138void rotate2D(double, double, double &, double &); ///< rotate 2d vector, given sin and cos
139double d2(double, double); ///< distance in 2D
[109]140
141#endif
Note: See TracBrowser for help on using the repository browser.