1 /**************************************************************************** 2 ** 3 ** This file is part of the LibreCAD project, a 2D CAD program 4 ** 5 ** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl) 6 ** Copyright (C) 2001-2003 RibbonSoft. All rights reserved. 7 ** 8 ** 9 ** This file may be distributed and/or modified under the terms of the 10 ** GNU General Public License version 2 as published by the Free Software 11 ** Foundation and appearing in the file gpl-2.0.txt included in the 12 ** packaging of this file. 13 ** 14 ** This program is distributed in the hope that it will be useful, 15 ** but WITHOUT ANY WARRANTY; without even the implied warranty of 16 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 ** GNU General Public License for more details. 18 ** 19 ** You should have received a copy of the GNU General Public License 20 ** along with this program; if not, write to the Free Software 21 ** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 22 ** 23 ** This copyright notice MUST APPEAR in all copies of the script! 24 ** 25 **********************************************************************/ 26 27 28 #ifndef RS_VECTOR_H 29 #define RS_VECTOR_H 30 31 #include <vector> 32 #include <iosfwd> 33 #include "rs.h" 34 35 /** 36 * Represents a 3d vector (x/y/z) 37 * 38 * @author Andrew Mustun 39 */ 40 class RS_Vector { 41 public: 42 RS_Vector()=default; 43 RS_Vector(double vx, double vy, double vz=0.0); 44 explicit RS_Vector(double angle); 45 //RS_Vector(double v[]); 46 explicit RS_Vector(bool valid); 47 ~RS_Vector()=default; 48 49 //! 50 //! \brief operator bool explicit and implicit conversion to bool 51 //! 52 explicit operator bool() const; 53 54 void set(double angle); // set to unit vector by the direction of angle 55 void set(double vx, double vy, double vz=0.0); 56 void setPolar(double radius, double angle); 57 //! \{ 58 //! construct by cartesian, or polar coordinates 59 static RS_Vector polar(double rho, double theta); 60 //! \} 61 62 double distanceTo(const RS_Vector& v) const; 63 double angle() const; 64 double angleTo(const RS_Vector& v) const; 65 double angleBetween(const RS_Vector& v1, const RS_Vector& v2) const; 66 double magnitude() const; 67 double squared() const; //return square of length 68 double squaredTo(const RS_Vector& v1) const; //return square of length 69 RS_Vector lerp(const RS_Vector& v, double t) const; 70 71 bool isInWindow(const RS_Vector& firstCorner, const RS_Vector& secondCorner) const; 72 bool isInWindowOrdered(const RS_Vector& vLow, const RS_Vector& vHigh) const; 73 74 RS_Vector toInteger(); 75 76 RS_Vector move(const RS_Vector& offset); 77 RS_Vector rotate(double ang); 78 RS_Vector rotate(const RS_Vector& angleVector); 79 RS_Vector rotate(const RS_Vector& center, double ang); 80 RS_Vector rotate(const RS_Vector& center, const RS_Vector& angleVector); 81 RS_Vector scale(double factor); 82 RS_Vector scale(const RS_Vector& factor); 83 RS_Vector scale(const RS_Vector& factor) const; 84 RS_Vector scale(const RS_Vector& center, const RS_Vector& factor); 85 RS_Vector mirror(const RS_Vector& axisPoint1, const RS_Vector& axisPoint2); 86 double dotP(const RS_Vector& v1) const; 87 88 RS_Vector operator + (const RS_Vector& v) const; 89 RS_Vector operator + (double d) const; 90 RS_Vector operator - (const RS_Vector& v) const; 91 RS_Vector operator - (double d) const; 92 RS_Vector operator * (const RS_Vector& v) const; 93 RS_Vector operator / (const RS_Vector& v) const; 94 RS_Vector operator * (double s) const; 95 RS_Vector operator / (double s) const; 96 RS_Vector operator - () const; 97 98 RS_Vector operator += (const RS_Vector& v); 99 RS_Vector operator -= (const RS_Vector& v); 100 RS_Vector operator *= (const RS_Vector& v); 101 RS_Vector operator /= (const RS_Vector& v); 102 RS_Vector operator *= (double s); 103 RS_Vector operator /= (double s); 104 105 bool operator == (const RS_Vector& v) const; 106 bool operator != (const RS_Vector& v) const { 107 return !operator==(v); 108 } 109 //! 110 //! \brief operator == comparison of validity with bool 111 //! \param valid boolean parameter 112 //! \return true is the parameter valid is the same as validity 113 //! 114 bool operator == (bool valid) const; 115 bool operator != (bool valid) const; 116 117 static RS_Vector minimum(const RS_Vector& v1, const RS_Vector& v2); 118 static RS_Vector maximum(const RS_Vector& v1, const RS_Vector& v2); 119 // crossP only defined for 3D 120 static RS_Vector crossP(const RS_Vector& v1, const RS_Vector& v2); 121 static double dotP(const RS_Vector& v1, const RS_Vector& v2); 122 static double posInLine(const RS_Vector& start, 123 const RS_Vector& end, 124 const RS_Vector& pos); 125 126 /** switch x,y for all vectors */ 127 RS_Vector flipXY(void) const; 128 129 friend std::ostream& operator << (std::ostream&, const RS_Vector& v); 130 131 #ifdef RS_TEST 132 133 static bool test(); 134 #endif 135 136 public: 137 double x=0.; 138 double y=0.; 139 double z=0.; 140 bool valid=false; 141 }; 142 143 144 /** 145 * Represents one to 4 vectors. Typically used to return multiple 146 * solutions from a function. 147 */ 148 class RS_VectorSolutions { 149 public: 150 typedef RS_Vector value_type; 151 RS_VectorSolutions(); 152 RS_VectorSolutions(const std::vector<RS_Vector>& s); 153 RS_VectorSolutions(std::initializer_list<RS_Vector> const& l); 154 RS_VectorSolutions(int num); 155 156 ~RS_VectorSolutions()=default; 157 158 void alloc(size_t num); 159 void clear(); 160 /** 161 * @brief get range safe method of member access 162 * @param i member index 163 * @return indexed member, or invalid vector, if out of range 164 */ 165 RS_Vector get(size_t i) const; 166 const RS_Vector& at(size_t i) const; 167 const RS_Vector& operator [] (const size_t i) const; 168 RS_Vector& operator [] (const size_t i); 169 size_t getNumber() const; 170 size_t size() const; 171 void resize(size_t n); 172 bool hasValid() const; 173 void set(size_t i, const RS_Vector& v); 174 void push_back(const RS_Vector& v); 175 void removeAt(const size_t i); 176 RS_VectorSolutions& push_back(const RS_VectorSolutions& v); 177 void setTangent(bool t); 178 bool isTangent() const; 179 RS_Vector getClosest(const RS_Vector& coord, 180 double* dist=nullptr, size_t* index=nullptr) const; 181 double getClosestDistance(const RS_Vector& coord, 182 int counts = -1); //default to search all 183 const std::vector<RS_Vector>& getVector() const; 184 std::vector<RS_Vector>::const_iterator begin() const; 185 std::vector<RS_Vector>::const_iterator end() const; 186 std::vector<RS_Vector>::iterator begin(); 187 std::vector<RS_Vector>::iterator end(); 188 void rotate(double ang); 189 void rotate(const RS_Vector& angleVector); 190 void rotate(const RS_Vector& center, double ang); 191 void rotate(const RS_Vector& center, const RS_Vector& angleVector); 192 void move(const RS_Vector& vp); 193 void scale(const RS_Vector& center, const RS_Vector& factor); 194 void scale(const RS_Vector& factor); 195 196 /** switch x,y for all vectors */ 197 RS_VectorSolutions flipXY(void) const; 198 199 friend std::ostream& operator << (std::ostream& os, 200 const RS_VectorSolutions& s); 201 202 private: 203 std::vector<RS_Vector> vector; 204 bool tangent; 205 }; 206 207 #endif 208 209 // EOF 210