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