/*************************************************************************** * Copyright (c) Konstantinos Poulios (logari81@gmail.com) 2011 * * * * This file is part of the FreeCAD CAx development system. * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of the GNU Library General Public * * License as published by the Free Software Foundation; either * * version 2 of the License, or (at your option) any later version. * * * * This library 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 Library General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this library; see the file COPYING.LIB. If not, * * write to the Free Software Foundation, Inc., 59 Temple Place, * * Suite 330, Boston, MA 02111-1307, USA * * * ***************************************************************************/ #ifndef PLANEGCS_GEO_H #define PLANEGCS_GEO_H #include #include "Util.h" namespace GCS { class Point { public: Point(){x = 0; y = 0;} double *x; double *y; }; ///Class DeriVector2 holds a vector value and its derivative on the ///parameter that the derivatives are being calculated for now. x,y is the ///actual vector (v). dx,dy is a derivative of the vector by a parameter ///(dv/dp). The easiest way to fill the vector in is by passing a point and ///a derivative parameter pointer to its constructor. x,y are read from the ///pointers in Point, and dx,dy are set to either 0 or 1 depending on what ///pointers of Point match the supplied pointer. The derivatives can be set ///manually as well. The class also provides a bunch of methods to do math ///on it (and derivatives are calculated implicitly). /// class DeriVector2 { public: DeriVector2(){x=0; y=0; dx=0; dy=0;} DeriVector2(double x, double y) {this->x = x; this->y = y; this->dx = 0; this->dy = 0;} DeriVector2(double x, double y, double dx, double dy) {this->x = x; this->y = y; this->dx = dx; this->dy = dy;} DeriVector2(const Point &p, double* derivparam); double x, dx; double y, dy; double length() const {return sqrt(x*x + y*y);} double length(double &dlength) const; //returns length and writes length deriv into the dlength argument. //unlike other vectors in FreeCAD, this normalization creates a new vector instead of modifying existing one. DeriVector2 getNormalized() const; //returns zero vector if the original is zero. double scalarProd(const DeriVector2 &v2, double* dprd=0) const;//calculates scalar product of two vectors and returns the result. The derivative of the result is written into argument dprd. DeriVector2 sum(const DeriVector2 &v2) const {//adds two vectors and returns result return DeriVector2(x + v2.x, y + v2.y, dx + v2.dx, dy + v2.dy);} DeriVector2 subtr(const DeriVector2 &v2) const {//subtracts two vectors and returns result return DeriVector2(x - v2.x, y - v2.y, dx - v2.dx, dy - v2.dy);} DeriVector2 mult(double val) const { return DeriVector2(x*val, y*val, dx*val, dy*val);}//multiplies the vector by a number. Derivatives are scaled. DeriVector2 multD(double val, double dval) const {//multiply vector by a variable with a derivative. return DeriVector2(x*val, y*val, dx*val+x*dval, dy*val+y*dval);} DeriVector2 divD(double val, double dval) const;//divide vector by a variable with a derivative DeriVector2 rotate90ccw() const {return DeriVector2(-y,x,-dy,dx);} DeriVector2 rotate90cw() const {return DeriVector2(y,-x,dy,-dx);} DeriVector2 linCombi(double m1, const DeriVector2 &v2, double m2) const {//linear combination of two vectors return DeriVector2(x*m1 + v2.x*m2, y*m1 + v2.y*m2, dx*m1 + v2.dx*m2, dy*m1 + v2.dy*m2);} }; /////////////////////////////////////// // Geometries /////////////////////////////////////// class Curve //a base class for all curve-based objects (line, circle/arc, ellipse/arc) { public: virtual ~Curve(){} //returns normal vector. The vector should point to the left when one // walks along the curve from start to end. Ellipses and circles are // assumed to be walked counterclockwise, so the vector should point // into the shape. //derivparam is a pointer to a curve parameter (or point coordinate) to // compute the derivative for. The derivative is returned through dx,dy // fields of DeriVector2. virtual DeriVector2 CalculateNormal(Point &p, double* derivparam = 0) = 0; /** * @brief Value: returns point (vector) given the value of parameter * @param u: value of parameter * @param du: derivative of parameter by derivparam * @param derivparam: pointer to sketch parameter to calculate the derivative for * @return */ virtual DeriVector2 Value(double u, double du, double* derivparam = 0); //adds curve's parameters to pvec (used by constraints) virtual int PushOwnParams(VEC_pD &pvec) = 0; //recunstruct curve's parameters reading them from pvec starting from index cnt. //cnt will be incremented by the same value as returned by PushOwnParams() virtual void ReconstructOnNewPvec (VEC_pD &pvec, int &cnt) = 0; virtual Curve* Copy() = 0; //DeepSOIC: I haven't found a way to simply copy a curve object provided pointer to a curve object. }; class Line: public Curve { public: Line(){} virtual ~Line(){} Point p1; Point p2; DeriVector2 CalculateNormal(Point &p, double* derivparam = 0); DeriVector2 Value(double u, double du, double* derivparam = 0); virtual int PushOwnParams(VEC_pD &pvec); virtual void ReconstructOnNewPvec (VEC_pD &pvec, int &cnt); virtual Line* Copy(); }; class Circle: public Curve { public: Circle(){rad = 0;} virtual ~Circle(){} Point center; double *rad; DeriVector2 CalculateNormal(Point &p, double* derivparam = 0); DeriVector2 Value(double u, double du, double* derivparam = 0); virtual int PushOwnParams(VEC_pD &pvec); virtual void ReconstructOnNewPvec (VEC_pD &pvec, int &cnt); virtual Circle* Copy(); }; class Arc: public Circle { public: Arc(){startAngle=0;endAngle=0;rad=0;} virtual ~Arc(){} double *startAngle; double *endAngle; //double *rad; //inherited Point start; Point end; //Point center; //inherited virtual int PushOwnParams(VEC_pD &pvec); virtual void ReconstructOnNewPvec (VEC_pD &pvec, int &cnt); virtual Arc* Copy(); }; class MajorRadiusConic: public Curve { public: virtual ~MajorRadiusConic(){} virtual double getRadMaj(const DeriVector2 ¢er, const DeriVector2 &f1, double b, double db, double &ret_dRadMaj) = 0; virtual double getRadMaj(double* derivparam, double &ret_dRadMaj) = 0; virtual double getRadMaj() = 0; DeriVector2 CalculateNormal(Point &p, double* derivparam = 0) = 0; }; class Ellipse: public MajorRadiusConic { public: Ellipse(){ radmin = 0;} virtual ~Ellipse(){} Point center; Point focus1; double *radmin; virtual double getRadMaj(const DeriVector2 ¢er, const DeriVector2 &f1, double b, double db, double &ret_dRadMaj); virtual double getRadMaj(double* derivparam, double &ret_dRadMaj); virtual double getRadMaj(); DeriVector2 CalculateNormal(Point &p, double* derivparam = 0); DeriVector2 Value(double u, double du, double* derivparam = 0); virtual int PushOwnParams(VEC_pD &pvec); virtual void ReconstructOnNewPvec (VEC_pD &pvec, int &cnt); virtual Ellipse* Copy(); }; class ArcOfEllipse: public Ellipse { public: ArcOfEllipse(){startAngle=0;endAngle=0;radmin = 0;} virtual ~ArcOfEllipse(){} double *startAngle; double *endAngle; //double *radmin; //inherited Point start; Point end; //Point center; //inherited //double *focus1.x; //inherited //double *focus1.y; //inherited virtual int PushOwnParams(VEC_pD &pvec); virtual void ReconstructOnNewPvec (VEC_pD &pvec, int &cnt); virtual ArcOfEllipse* Copy(); }; class Hyperbola: public MajorRadiusConic { public: Hyperbola(){ radmin = 0;} virtual ~Hyperbola(){} Point center; Point focus1; double *radmin; virtual double getRadMaj(const DeriVector2 ¢er, const DeriVector2 &f1, double b, double db, double &ret_dRadMaj); virtual double getRadMaj(double* derivparam, double &ret_dRadMaj); virtual double getRadMaj(); DeriVector2 CalculateNormal(Point &p, double* derivparam = 0); virtual DeriVector2 Value(double u, double du, double* derivparam = 0); virtual int PushOwnParams(VEC_pD &pvec); virtual void ReconstructOnNewPvec (VEC_pD &pvec, int &cnt); virtual Hyperbola* Copy(); }; class ArcOfHyperbola: public Hyperbola { public: ArcOfHyperbola(){startAngle=0;endAngle=0;radmin = 0;} virtual ~ArcOfHyperbola(){} // parameters double *startAngle; double *endAngle; Point start; Point end; // interface helpers virtual int PushOwnParams(VEC_pD &pvec); virtual void ReconstructOnNewPvec (VEC_pD &pvec, int &cnt); virtual ArcOfHyperbola* Copy(); }; } //namespace GCS #endif // PLANEGCS_GEO_H