1 /* 2 This file is part of Kig, a KDE program for Interactive Geometry... 3 SPDX-FileCopyrightText: 2002 Maurizio Paolini <paolini@dmf.unicatt.it> 4 5 SPDX-License-Identifier: GPL-2.0-or-later 6 */ 7 8 #ifndef KIG_MISC_CONIC_COMMON_H 9 #define KIG_MISC_CONIC_COMMON_H 10 11 #include "coordinate.h" 12 #include <vector> 13 #include "kignumerics.h" 14 15 class ConicPolarData; 16 class Transformation; 17 class LineData; 18 19 /** 20 * Cartesian Conic Data. This class represents an equation of a conic 21 * in the form "ax^2 + by^2 + cxy + dx + ey + f = 0". 22 * \internal The coefficients are stored in the order a - f. 23 */ 24 class ConicCartesianData 25 { 26 public: 27 double coeffs[6]; 28 ConicCartesianData(); 29 /** 30 * Construct a ConicCartesianData from a ConicPolarData. 31 * Construct a ConicCartesianData that is the cartesian 32 * representation of the conic represented by d. 33 */ 34 explicit ConicCartesianData( const ConicPolarData& d ); 35 /** 36 * Construct a ConicCartesianData from its coefficients 37 * Construct a ConicCartesianData using the coefficients a through f 38 * from the equation "ax^2 + by^2 + cxy + dx + ey + f = 0" 39 */ ConicCartesianData(double a,double b,double c,double d,double e,double f)40 ConicCartesianData( double a, double b, double c, 41 double d, double e, double f ) 42 { 43 coeffs[0] = a; 44 coeffs[1] = b; 45 coeffs[2] = c; 46 coeffs[3] = d; 47 coeffs[4] = e; 48 coeffs[5] = f; 49 } 50 explicit ConicCartesianData( const double incoeffs[6] ); 51 52 /** 53 * Invalid conic. 54 * Return a ConicCartesianData representing an invalid conic. 55 * \see valid() 56 */ 57 static ConicCartesianData invalidData(); 58 /** 59 * Test validity. 60 * Return whether this is a valid conic. 61 * \see invalidData() 62 */ 63 bool valid() const; 64 }; 65 66 /** 67 * This class represents an equation of a conic in the form 68 * \f$ \rho(\theta) = \frac{p}{1 - e \cos\theta}\f$. focus and the 69 * ecostheta stuff represent the coordinate system in which the 70 * equation yields the good result.. 71 */ 72 class ConicPolarData 73 { 74 public: 75 /** 76 * Construct a ConicPolarData from a ConicCartesianData. 77 * 78 * Construct a ConicPolarData that is the polar 79 * representation of the conic represented by d. 80 */ 81 explicit ConicPolarData( const ConicCartesianData& data ); 82 explicit ConicPolarData(); 83 /** 84 * Construct a ConicPolarData using the parameters from the equation 85 * \f$ \rho(\theta) = \frac{p}{1 - e \cos\theta}\f$ 86 */ 87 ConicPolarData( const Coordinate& focus1, double dimen, 88 double ecostheta0, double esintheta0 ); 89 90 /** 91 * The first focus of this conic. 92 */ 93 Coordinate focus1; 94 /** 95 * The pdimen value from the polar equation. 96 */ 97 double pdimen; 98 /** 99 * The ecostheta0 value from the polar equation. 100 */ 101 double ecostheta0; 102 /** 103 * The esintheta0 value from the polar equation. 104 */ 105 double esintheta0; 106 }; 107 108 bool operator==( const ConicPolarData& lhs, const ConicPolarData& rhs ); 109 110 /** 111 * These are the constraint values that can be passed to the 112 * calcConicThroughPoints function. Their meaning is as follows: 113 * noconstraint: no additional points will be calculated. 114 * zerotilt: force the symmetry axes to be parallel to the coordinate 115 * system ( zero tilt ). 116 * parabolaifzt: the returned conic should be a parabola ( if used in 117 * combination with zerotilt ) 118 * circleifzt: the returned conic should be a circle ( if used in 119 * combination with zerotilt ) 120 * equilateral: the returned conic should be equilateral 121 * ysymmetry: the returned conic should be symmetric over the Y-axis. 122 * xsymmetry: the returned conic should be symmetric over the X-axis. 123 */ 124 enum LinearConstraints { 125 noconstraint, zerotilt, parabolaifzt, circleifzt, 126 equilateral, ysymmetry, xsymmetry 127 }; 128 129 /** 130 * Calculate a conic through a given set of points. points should 131 * contain at least one, and at most five points. If there are five 132 * points, then the conic is completely defined. If there are less, 133 * then additional points will be calculated according to the 134 * constraints given. See above for the various constraints. 135 * 136 * An invalid ConicCartesianData is returned if there is no conic 137 * through the given set of points, or if not enough constraints are 138 * given for a conic to be calculated. 139 */ 140 const ConicCartesianData calcConicThroughPoints ( 141 const std::vector<Coordinate>& points, 142 const LinearConstraints c1 = noconstraint, 143 const LinearConstraints c2 = noconstraint, 144 const LinearConstraints c3 = noconstraint, 145 const LinearConstraints c4 = noconstraint, 146 const LinearConstraints c5 = noconstraint); 147 148 /** 149 * This function is used by ConicBFFP. It calcs the polar equation 150 * for a hyperbola ( type == -1 ) or ellipse ( type == 1 ) with 151 * focuses args[0] and args[1], and with args[2] on the edge of the 152 * conic. args.size() should be two or three. If it is two, the two 153 * points are taken to be the focuses, and a third point is chosen in 154 * a sensible way.. 155 */ 156 const ConicPolarData calcConicBFFP( 157 const std::vector<Coordinate>& args, 158 int type ); 159 160 /** 161 * function used by ConicBDFP. It calcs the conic with directrix d, 162 * focus f, and point p on the conic.. 163 */ 164 const ConicPolarData calcConicBDFP( 165 const LineData& d, const Coordinate& f, const Coordinate& p ); 166 167 /** 168 * This calcs the hyperbola defined by its two asymptotes line1 and 169 * line2, and a point p on the edge. 170 */ 171 const ConicCartesianData calcConicByAsymptotes( 172 const LineData& line1, 173 const LineData& line2, 174 const Coordinate& p ); 175 176 /** 177 * This function calculates the polar line of the point cpole with 178 * respect to the given conic data. As the last argument, you should 179 * pass a reference to a boolean. This boolean will be set to true if 180 * the returned LineData is valid, and to false if the returned line 181 * is not valid. The latter condition only occurs if a "line at 182 * infinity" would have had to be returned. 183 */ 184 const LineData calcConicPolarLine ( 185 const ConicCartesianData& data, 186 const Coordinate& cpole, 187 bool& valid ); 188 189 /** 190 * This function calculates the polar point of the line polar with 191 * respect to the given conic data. As the last argument, you should 192 * pass a reference to a boolean. This boolean will be set to true if 193 * the returned LineData is valid, and to false if the returned line 194 * is not valid. The latter condition only occurs if a "point at 195 * infinity" would have had to be returned. 196 */ 197 const Coordinate calcConicPolarPoint ( 198 const ConicCartesianData& data, 199 const LineData& polar ); 200 201 /** 202 * This function calculates the intersection of a given line ( l ) and 203 * a given conic ( c ). A line and a conic have two intersections in 204 * general, and as such, which should be set to -1 or 1 depending on 205 * which intersection you want. As the last argument, you should pass 206 * a reference to a boolean. This boolean will be set to true if the 207 * returned point is valid, and to false if the returned point is not 208 * valid. The latter condition only occurs if the given conic and 209 * line do not have the specified intersection. 210 * 211 * knownparam is something special: If you already know one 212 * intersection of the line and the conic, and you want the other one, 213 * then you should set which to 0, knownparam to the curve parameter 214 * of the point you already know ( i.e. the value returned by 215 * conicimp->getParam( otherpoint ) ). 216 */ 217 const Coordinate calcConicLineIntersect( const ConicCartesianData& c, 218 const LineData& l, 219 double knownparam, 220 int which ); 221 222 /** 223 * This function calculates the asymptote of the given conic ( data ). 224 * A conic has two asymptotes in general, so which should be set to +1 225 * or -1 depending on which asymptote you want. As the last argument, 226 * you should pass a reference to a boolean. This boolean will be set 227 * to true if the returned line is valid, and to false if the returned 228 * line is not valid. The latter condition only occurs if the given 229 * conic does not have the specified asymptote. 230 */ 231 const LineData calcConicAsymptote( 232 const ConicCartesianData &data, 233 int which, bool &valid ); 234 235 /** 236 * This function calculates the radical line of two conics. A radical 237 * line is the line that goes through two of the intersections of two 238 * conics. Since two conics have up to four intersections in general, 239 * there are three sets of two radical lines. zeroindex specifies 240 * which set of radical lines you want ( set it to 1, 2 or 3 ), and 241 * which is set to -1 or +1 depending on which of the two radical 242 * lines in the set you want. As the last argument, you should pass a 243 * reference to a boolean. This boolean will be set to true if the 244 * returned line is valid, and to false if the returned line is not 245 * valid. The latter condition only occurs if the given conics do not 246 * have the specified radical line. 247 */ 248 const LineData calcConicRadical( const ConicCartesianData& cequation1, 249 const ConicCartesianData& cequation2, 250 int which, int zeroindex, bool& valid ); 251 252 /** 253 * This calculates the image of the given conic ( data ) through the 254 * given transformation ( t ). As the last argument, you should pass 255 * a reference to a boolean. This boolean will be set to true if the 256 * returned line is valid, and to false if the returned line is not 257 * valid. The latter condition only occurs if the given 258 * transformation is singular, and as such, the transformation of the 259 * conic cannot be calculated. 260 */ 261 const ConicCartesianData calcConicTransformation ( 262 const ConicCartesianData& data, 263 const Transformation& t, bool& valid ); 264 265 #endif // KIG_MISC_CONIC_COMMON_H 266