1 /****************************************************************************
2 **
3 ** This file is part of the LibreCAD project, a 2D CAD program
4 **
5 ** Copyright (C) 2015 A. Stebich (librecad@mail.lordofbikes.de)
6 ** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
7 ** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
8 **
9 **
10 ** This file may be distributed and/or modified under the terms of the
11 ** GNU General Public License version 2 as published by the Free Software
12 ** Foundation and appearing in the file gpl-2.0.txt included in the
13 ** packaging of this file.
14 **
15 ** This program is distributed in the hope that it will be useful,
16 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ** GNU General Public License for more details.
19 **
20 ** You should have received a copy of the GNU General Public License
21 ** along with this program; if not, write to the Free Software
22 ** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
23 **
24 ** This copyright notice MUST APPEAR in all copies of the script!
25 **
26 **********************************************************************/
27 
28 
29 #ifndef RS_CIRCLE_H
30 #define RS_CIRCLE_H
31 
32 #include <vector>
33 #include "rs_atomicentity.h"
34 
35 class LC_Quadratic;
36 
37 /**
38  * Holds the data that defines a circle.
39  */
40 struct RS_CircleData {
41 	RS_CircleData() = default;
42 	RS_CircleData(RS_Vector const& center, double radius);
43 	bool isValid() const;
44 	bool operator == (RS_CircleData const&) const;
45 	RS_Vector center;
46 	double radius;
47 };
48 
49 std::ostream& operator << (std::ostream& os, const RS_CircleData& ad);
50 
51 /**
52  * Class for a circle entity.
53  *
54  * @author Andrew Mustun
55  */
56 class RS_Circle : public RS_AtomicEntity {
57 public:
58 	RS_Circle()=default;
59     RS_Circle (RS_EntityContainer* parent,
60                const RS_CircleData& d);
61 	~RS_Circle() = default;
62 
63 	RS_Entity* clone() const override;
64 
65     /**	@return RS2::EntityCircle */
rtti()66 	RS2::EntityType rtti() const override{
67         return RS2::EntityCircle;
68     }
69     /** @return true */
isEdge()70 	bool isEdge() const  override{
71         return true;
72     }
73 
74     /** @return Copy of data that defines the circle. **/
getData()75 	const RS_CircleData& getData() const {
76         return data;
77     }
78 
79 	RS_VectorSolutions getRefPoints() const override;
80 
81     //no start/end point for whole circle
82 	//        RS_Vector getStartpoint() const {
83     //                return data.center + RS_Vector(data.radius, 0.0);
84     //        }
85 	//        RS_Vector getEndpoint() const {
86     //                return data.center + RS_Vector(data.radius, 0.0);
87     //        }
88     /**
89          * @return Direction 1. The angle at which the arc starts at
90          * the startpoint.
91          */
92 	double getDirection1() const override;
93     /**
94          * @return Direction 2. The angle at which the arc starts at
95          * the endpoint.
96          */
97 	double getDirection2() const override;
98 
99     /** @return The center point (x) of this arc */
100 	RS_Vector getCenter() const override;
101     /** Sets new center. */
102 	void setCenter(const RS_Vector& c);
103     /** @return The radius of this arc */
104 	double getRadius() const override;
105     /** Sets new radius. */
106 	void setRadius(double r);
107     double getAngleLength() const;
108 	double getLength() const override;
109 	bool isTangent(const RS_CircleData&  circleData) const override;
110 
111     bool createFromCR(const RS_Vector& c, double r);
112     bool createFrom2P(const RS_Vector& p1, const RS_Vector& p2);
113     bool createFrom3P(const RS_Vector& p1, const RS_Vector& p2,
114                       const RS_Vector& p3);
115     bool createFrom3P(const RS_VectorSolutions& sol);
116 	bool createInscribe(const RS_Vector& coord, const std::vector<RS_Line*>& lines);
117 	std::vector<RS_Entity* > offsetTwoSides(const double& distance) const override;
118 	RS_VectorSolutions createTan1_2P(const RS_AtomicEntity* circle, const std::vector<RS_Vector>& points);
119 	static RS_VectorSolutions createTan2(const std::vector<RS_AtomicEntity*>& circles, const double& r);
120     /** solve one of the eight Appollonius Equations
121 | Cx - Ci|^2=(Rx+Ri)^2
122 with Cx the center of the common tangent circle, Rx the radius. Ci and Ri are the Center and radius of the i-th existing circle
123 **/
124 	static std::vector<RS_Circle> solveAppolloniusSingle(const std::vector<RS_Circle>& circles);
125 
126 	std::vector<RS_Circle> createTan3(const std::vector<RS_AtomicEntity*>& circles);
127 	bool testTan3(const std::vector<RS_AtomicEntity*>& circles);
128 	RS_Vector getMiddlePoint(void)const override;
129 	RS_Vector getNearestEndpoint(const RS_Vector& coord,
130 										 double* dist = nullptr) const override;
131 	RS_Vector getNearestPointOnEntity(const RS_Vector& coord,
132 											  bool onEntity = true, double* dist = NULL, RS_Entity** entity=NULL)const override;
133 	RS_Vector getNearestCenter(const RS_Vector& coord,
134 									   double* dist = NULL)const override;
135 	RS_Vector getNearestMiddle(const RS_Vector& coord,
136                                        double* dist = nullptr,
137 									   int middlePoints = 1 ) const override;
138 	RS_Vector getNearestDist(double distance,
139                                      const RS_Vector& coord,
140 									 double* dist = NULL)const override;
141 	RS_Vector getNearestDist(double distance,
142 									 bool startp)const override;
143 	RS_Vector getNearestOrthTan(const RS_Vector& coord,
144                                         const RS_Line& normal,
145 										bool onEntity = false) const override;
146 
147 	bool offset(const RS_Vector& coord, const double& distance) override;
148 	RS_VectorSolutions getTangentPoint(const RS_Vector& point) const override;//find the tangential points seeing from given point
149 	RS_Vector getTangentDirection(const RS_Vector& point)const override;
150 	void move(const RS_Vector& offset) override;
151 	void rotate(const RS_Vector& center, const double& angle) override;
152 	void rotate(const RS_Vector& center, const RS_Vector& angleVector) override;
153 	void scale(const RS_Vector& center, const RS_Vector& factor) override;
154 	void mirror(const RS_Vector& axisPoint1, const RS_Vector& axisPoint2) override;
155 	void moveRef(const RS_Vector& ref, const RS_Vector& offset) override;
156     /** whether the entity's bounding box intersects with visible portion of graphic view */
157 	bool isVisibleInWindow(RS_GraphicView* view) const override;
158 	void draw(RS_Painter* painter, RS_GraphicView* view, double& patternOffset) override;
159     /** return the equation of the entity
160 for quadratic,
161 
162 return a vector contains:
163 m0 x^2 + m1 xy + m2 y^2 + m3 x + m4 y + m5 =0
164 
165 for linear:
166 m0 x + m1 y + m2 =0
167 **/
168 	LC_Quadratic getQuadratic() const override;
169 
170 /**
171 * @brief Returns area of full circle
172 * Note: Circular arcs are handled separately by RS_Arc (areaLIneIntegral)
173 * However, full ellipses and ellipse arcs are handled by RS_Ellipse
174 * @return \pi r^2
175 */
176 	double areaLineIntegral() const override;
177 
178     friend std::ostream& operator << (std::ostream& os, const RS_Circle& a);
179 
180 	void calculateBorders() override;
181 
182 protected:
183     RS_CircleData data;
184 };
185 
186 #endif
187