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