1 /**************************************************************************** 2 ** 3 ** This file is part of the LibreCAD project, a 2D CAD program 4 ** 5 ** Copyright (C) 2011-2012 Dongxu Li (dongxuli2011@gmail.com) 6 7 Copyright (C) 2012 Dongxu Li (dongxuli2011@gmail.com) 8 9 This program is free software; you can redistribute it and/or 10 modify it under the terms of the GNU General Public License 11 as published by the Free Software Foundation; either version 2 12 of the License, or (at your option) any later version. 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 **********************************************************************/ 24 25 26 #ifndef LC_HYPERBOLA_H 27 #define LC_HYPERBOLA_H 28 29 #include "rs_atomicentity.h" 30 31 class RS_Circle; 32 class LC_Quadratic; 33 34 /** 35 * Holds the data that defines one branch of a hyperbola. 36 * majorP is the vector from center to the vertex 37 * ratio is the ratio between semi-major and semi-minor axis 38 39 */ 40 struct LC_HyperbolaData { 41 LC_HyperbolaData() = default; 42 LC_HyperbolaData(const RS_Vector& center, 43 const RS_Vector& majorP, 44 double ratio, 45 double angle1, double angle2, 46 bool reversed); 47 ~LC_HyperbolaData() = default; 48 /** create data based on foci and a point on hyperbola */ 49 LC_HyperbolaData(const RS_Vector& focus0, 50 const RS_Vector& focus1, 51 const RS_Vector& point); 52 53 //! Hyperbola center 54 RS_Vector center; 55 //! Endpoint of major axis relative to center. 56 RS_Vector majorP; 57 //! Ratio of minor axis to major axis. 58 double ratio; 59 //! Start angle 60 double angle1; 61 //! End angle 62 double angle2; 63 //! Reversed (cw) flag 64 bool reversed; 65 }; 66 67 std::ostream& operator << (std::ostream& os, const LC_HyperbolaData& ed); 68 69 70 /** 71 * Class for an hyperbola entity. 72 * 73 * @author Dongxu Li 74 */ 75 class LC_Hyperbola : public RS_AtomicEntity { 76 public: 77 LC_Hyperbola() = default; 78 LC_Hyperbola(RS_EntityContainer* parent, 79 const LC_HyperbolaData& d); 80 81 /** create data based on foci and a point on hyperbola */ 82 LC_Hyperbola(const RS_Vector& focus0, 83 const RS_Vector& focus1, 84 const RS_Vector& point); 85 86 RS_Entity* clone() const override; 87 88 /** @return RS2::EntityHyperbola */ rtti()89 RS2::EntityType rtti() const override{ 90 return RS2::EntityHyperbola; 91 } isValid()92 bool isValid() const{ 93 return m_bValid; 94 } 95 96 97 98 // double getLength() const; 99 100 // /** 101 // //Hyperbola must have ratio<1, and not reversed 102 // *@ x1, hyperbola angle 103 // *@ x2, hyperbola angle 104 // //@return the arc length between hyperbola angle x1, x2 105 // **/ 106 // double getHyperbolaLength(double a1, double a2) const; 107 // double getHyperbolaLength(double a2) const; 108 109 110 /** @return Copy of data that defines the hyperbola. **/ getData()111 LC_HyperbolaData getData() const { 112 return data; 113 } 114 RS_VectorSolutions getFoci() const; 115 RS_VectorSolutions getRefPoints() const override; 116 117 /** 118 * @retval true if the arc is reversed (clockwise), 119 * @retval false otherwise 120 */ isReversed()121 bool isReversed() const{ 122 return data.reversed; 123 } 124 /** sets the reversed status. */ setReversed(bool r)125 void setReversed(bool r){ 126 data.reversed = r; 127 } 128 129 /** @return The rotation angle of this hyperbola */ getAngle()130 double getAngle() const { 131 return data.majorP.angle(); 132 } 133 134 /** @return The start angle of this arc */ getAngle1()135 double getAngle1() const { 136 return data.angle1; 137 } 138 /** Sets new start angle. */ setAngle1(double a1)139 void setAngle1(double a1) { 140 data.angle1 = a1; 141 } 142 /** @return The end angle of this arc */ getAngle2()143 double getAngle2() const { 144 return data.angle2; 145 } 146 /** Sets new end angle. */ setAngle2(double a2)147 void setAngle2(double a2) { 148 data.angle2 = a2; 149 } 150 151 152 /** @return The center point (x) of this arc */ getCenter()153 RS_Vector getCenter() const override{ 154 return data.center; 155 } 156 /** Sets new center. */ setCenter(const RS_Vector & c)157 void setCenter(const RS_Vector& c) { 158 data.center = c; 159 } 160 161 /** @return The endpoint of the major axis (relative to center). */ getMajorP()162 RS_Vector getMajorP() const { 163 return data.majorP; 164 } 165 /** Sets new major point (relative to center). */ setMajorP(const RS_Vector & p)166 void setMajorP(const RS_Vector& p) { 167 data.majorP = p; 168 } 169 170 /** @return The ratio of minor to major axis */ getRatio()171 double getRatio() const { 172 return data.ratio; 173 } 174 /** Sets new ratio. */ setRatio(double r)175 void setRatio(double r) { 176 data.ratio = r; 177 } 178 179 180 /** @return The major radius of this hyperbola. Same as getRadius() */ getMajorRadius()181 double getMajorRadius() const { 182 return data.majorP.magnitude(); 183 } 184 185 /** @return The minor radius of this hyperbola */ getMinorRadius()186 double getMinorRadius() const { 187 return data.majorP.magnitude()*data.ratio; 188 } 189 calculateBorders()190 void calculateBorders() override{} 191 getMiddlePoint(void)192 RS_Vector getMiddlePoint(void)const override{return RS_Vector(false);} getNearestEndpoint(const RS_Vector &,double *)193 RS_Vector getNearestEndpoint(const RS_Vector& /*coord*/, 194 double*/* dist = NULL*/) const override 195 {return RS_Vector(false);} getNearestPointOnEntity(const RS_Vector &,bool,double *,RS_Entity **)196 RS_Vector getNearestPointOnEntity(const RS_Vector& /*coord*/, 197 bool /*onEntity = true*/, double*/* dist = NULL*/, RS_Entity**/* entity=NULL*/) const override 198 {return RS_Vector(false);} getNearestCenter(const RS_Vector &,double *)199 RS_Vector getNearestCenter(const RS_Vector& /*coord*/, 200 double*/* dist = NULL*/) const override 201 {return RS_Vector(false);} getNearestMiddle(const RS_Vector &,double *,int)202 RS_Vector getNearestMiddle(const RS_Vector& /*coord*/, 203 double*/* dist = NULL*/, 204 int/* middlePoints = 1*/ 205 )const override 206 {return RS_Vector(false);} getNearestDist(double,const RS_Vector &,double *)207 RS_Vector getNearestDist(double /*distance*/, 208 const RS_Vector&/* coord*/, 209 double*/* dist = NULL*/) const override 210 {return RS_Vector(false);} getNearestOrthTan(const RS_Vector &,const RS_Line &,bool)211 RS_Vector getNearestOrthTan(const RS_Vector& /*coord*/, 212 const RS_Line& /*normal*/, 213 bool /*onEntity = false*/) const override 214 {return RS_Vector(false);} getDistanceToPoint(const RS_Vector &,RS_Entity **,RS2::ResolveLevel,double)215 double getDistanceToPoint(const RS_Vector& /*coord*/, 216 RS_Entity** /*entity=NULL*/, 217 RS2::ResolveLevel/* level=RS2::ResolveNone*/, 218 double /*solidDist = RS_MAXDOUBLE*/) const override 219 {return RS_MAXDOUBLE;} 220 bool isPointOnEntity(const RS_Vector& /*coord*/, 221 double /*tolerance=RS_TOLERANCE*/) const override; 222 move(const RS_Vector &)223 void move(const RS_Vector& /*offset*/) override{} rotate(const double &)224 void rotate(const double& /*angle*/) {} rotate(const RS_Vector &)225 void rotate(const RS_Vector& /*angleVector*/){} rotate(const RS_Vector &,const double &)226 void rotate(const RS_Vector& /*center*/, const double& /*angle*/) override{} rotate(const RS_Vector &,const RS_Vector &)227 void rotate(const RS_Vector& /*center*/, const RS_Vector& /*angle*/)override{} scale(const RS_Vector &,const RS_Vector &)228 void scale(const RS_Vector& /*center*/, const RS_Vector& /*factor*/)override{} mirror(const RS_Vector &,const RS_Vector &)229 void mirror(const RS_Vector& /*axisPoint1*/, const RS_Vector& /*axisPoint2*/)override{} moveRef(const RS_Vector &,const RS_Vector &)230 void moveRef(const RS_Vector& /*ref*/, const RS_Vector& /*offset*/)override{} 231 draw(RS_Painter *,RS_GraphicView *,double &)232 void draw(RS_Painter* /*painter*/, RS_GraphicView* /*view*/, double& /*patternOffset*/)override{} 233 234 friend std::ostream& operator << (std::ostream& os, const LC_Hyperbola& a); 235 236 //void calculateEndpoints(); 237 // void calculateBorders(); 238 239 //direction of tangent at endpoints getDirection1()240 double getDirection1() const override{return 0.;} getDirection2()241 double getDirection2() const override{return 0.;} 242 /** return the equation of the entity 243 for quadratic, 244 245 return a vector contains: 246 m0 x^2 + m1 xy + m2 y^2 + m3 x + m4 y + m5 =0 247 248 for linear: 249 m0 x + m1 y + m2 =0 250 **/ 251 LC_Quadratic getQuadratic() const override; 252 253 protected: 254 LC_HyperbolaData data; 255 bool m_bValid; 256 257 }; 258 259 260 261 #endif 262 //EOF 263