/** This file is part of Kig, a KDE program for Interactive Geometry... Copyright (C) 2002 Maurizio Paolini This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA **/ #ifndef KIG_MISC_CONIC_COMMON_H #define KIG_MISC_CONIC_COMMON_H #include "coordinate.h" #include #include "kignumerics.h" class ConicPolarData; class Transformation; class LineData; /** * Cartesian Conic Data. This class represents an equation of a conic * in the form "ax^2 + by^2 + cxy + dx + ey + f = 0". * \internal The coefficients are stored in the order a - f. */ class ConicCartesianData { public: double coeffs[6]; ConicCartesianData(); /** * Construct a ConicCartesianData from a ConicPolarData. * Construct a ConicCartesianData that is the cartesian * representation of the conic represented by d. */ explicit ConicCartesianData( const ConicPolarData& d ); /** * Construct a ConicCartesianData from its coefficients * Construct a ConicCartesianData using the coefficients a through f * from the equation "ax^2 + by^2 + cxy + dx + ey + f = 0" */ ConicCartesianData( double a, double b, double c, double d, double e, double f ) { coeffs[0] = a; coeffs[1] = b; coeffs[2] = c; coeffs[3] = d; coeffs[4] = e; coeffs[5] = f; } ConicCartesianData( const double incoeffs[6] ); /** * Invalid conic. * Return a ConicCartesianData representing an invalid conic. * \see valid() */ static ConicCartesianData invalidData(); /** * Test validity. * Return whether this is a valid conic. * \see invalidData() */ bool valid() const; }; /** * This class represents an equation of a conic in the form * \f$ \rho(\theta) = \frac{p}{1 - e \cos\theta}\f$. focus and the * ecostheta stuff represent the coordinate system in which the * equation yields the good result.. */ class ConicPolarData { public: /** * Construct a ConicPolarData from a ConicCartesianData. * * Construct a ConicPolarData that is the polar * representation of the conic represented by d. */ explicit ConicPolarData( const ConicCartesianData& data ); explicit ConicPolarData(); /** * Construct a ConicPolarData using the parameters from the equation * \f$ \rho(\theta) = \frac{p}{1 - e \cos\theta}\f$ */ ConicPolarData( const Coordinate& focus1, double dimen, double ecostheta0, double esintheta0 ); /** * The first focus of this conic. */ Coordinate focus1; /** * The pdimen value from the polar equation. */ double pdimen; /** * The ecostheta0 value from the polar equation. */ double ecostheta0; /** * The esintheta0 value from the polar equation. */ double esintheta0; }; bool operator==( const ConicPolarData& lhs, const ConicPolarData& rhs ); /** * These are the constraint values that can be passed to the * calcConicThroughPoints function. Their meaning is as follows: * noconstraint: no additional points will be calculated. * zerotilt: force the symmetry axes to be parallel to the coordinate * system ( zero tilt ). * parabolaifzt: the returned conic should be a parabola ( if used in * combination with zerotilt ) * circleifzt: the returned conic should be a circle ( if used in * combination with zerotilt ) * equilateral: the returned conic should be equilateral * ysymmetry: the returned conic should be symmetric over the Y-axis. * xsymmetry: the returned conic should be symmetric over the X-axis. */ enum LinearConstraints { noconstraint, zerotilt, parabolaifzt, circleifzt, equilateral, ysymmetry, xsymmetry }; /** * Calculate a conic through a given set of points. points should * contain at least one, and at most five points. If there are five * points, then the conic is completely defined. If there are less, * then additional points will be calculated according to the * constraints given. See above for the various constraints. * * An invalid ConicCartesianData is returned if there is no conic * through the given set of points, or if not enough constraints are * given for a conic to be calculated. */ const ConicCartesianData calcConicThroughPoints ( const std::vector& points, const LinearConstraints c1 = noconstraint, const LinearConstraints c2 = noconstraint, const LinearConstraints c3 = noconstraint, const LinearConstraints c4 = noconstraint, const LinearConstraints c5 = noconstraint); /** * This function is used by ConicBFFP. It calcs the polar equation * for a hyperbola ( type == -1 ) or ellipse ( type == 1 ) with * focuses args[0] and args[1], and with args[2] on the edge of the * conic. args.size() should be two or three. If it is two, the two * points are taken to be the focuses, and a third point is chosen in * a sensible way.. */ const ConicPolarData calcConicBFFP( const std::vector& args, int type ); /** * function used by ConicBDFP. It calcs the conic with directrix d, * focus f, and point p on the conic.. */ const ConicPolarData calcConicBDFP( const LineData& d, const Coordinate& f, const Coordinate& p ); /** * This calcs the hyperbola defined by its two asymptotes line1 and * line2, and a point p on the edge. */ const ConicCartesianData calcConicByAsymptotes( const LineData& line1, const LineData& line2, const Coordinate& p ); /** * This function calculates the polar line of the point cpole with * respect to the given conic data. As the last argument, you should * pass a reference to a boolean. This boolean will be set to true if * the returned LineData is valid, and to false if the returned line * is not valid. The latter condition only occurs if a "line at * infinity" would have had to be returned. */ const LineData calcConicPolarLine ( const ConicCartesianData& data, const Coordinate& cpole, bool& valid ); /** * This function calculates the polar point of the line polar with * respect to the given conic data. As the last argument, you should * pass a reference to a boolean. This boolean will be set to true if * the returned LineData is valid, and to false if the returned line * is not valid. The latter condition only occurs if a "point at * infinity" would have had to be returned. */ const Coordinate calcConicPolarPoint ( const ConicCartesianData& data, const LineData& polar ); /** * This function calculates the intersection of a given line ( l ) and * a given conic ( c ). A line and a conic have two intersections in * general, and as such, which should be set to -1 or 1 depending on * which intersection you want. As the last argument, you should pass * a reference to a boolean. This boolean will be set to true if the * returned point is valid, and to false if the returned point is not * valid. The latter condition only occurs if the given conic and * line do not have the specified intersection. * * knownparam is something special: If you already know one * intersection of the line and the conic, and you want the other one, * then you should set which to 0, knownparam to the curve parameter * of the point you already know ( i.e. the value returned by * conicimp->getParam( otherpoint ) ). */ const Coordinate calcConicLineIntersect( const ConicCartesianData& c, const LineData& l, double knownparam, int which ); /** * This function calculates the asymptote of the given conic ( data ). * A conic has two asymptotes in general, so which should be set to +1 * or -1 depending on which asymptote you want. As the last argument, * you should pass a reference to a boolean. This boolean will be set * to true if the returned line is valid, and to false if the returned * line is not valid. The latter condition only occurs if the given * conic does not have the specified asymptote. */ const LineData calcConicAsymptote( const ConicCartesianData data, int which, bool &valid ); /** * This function calculates the radical line of two conics. A radical * line is the line that goes through two of the intersections of two * conics. Since two conics have up to four intersections in general, * there are three sets of two radical lines. zeroindex specifies * which set of radical lines you want ( set it to 1, 2 or 3 ), and * which is set to -1 or +1 depending on which of the two radical * lines in the set you want. As the last argument, you should pass a * reference to a boolean. This boolean will be set to true if the * returned line is valid, and to false if the returned line is not * valid. The latter condition only occurs if the given conics do not * have the specified radical line. */ const LineData calcConicRadical( const ConicCartesianData& cequation1, const ConicCartesianData& cequation2, int which, int zeroindex, bool& valid ); /** * This calculates the image of the given conic ( data ) through the * given transformation ( t ). As the last argument, you should pass * a reference to a boolean. This boolean will be set to true if the * returned line is valid, and to false if the returned line is not * valid. The latter condition only occurs if the given * transformation is singular, and as such, the transformation of the * conic cannot be calculated. */ const ConicCartesianData calcConicTransformation ( const ConicCartesianData& data, const Transformation& t, bool& valid ); #endif // KIG_MISC_CONIC_COMMON_H