]> SALOME platform Git repositories - tools/medcoupling.git/commitdiff
Salome HOME
adding Anthony modification for integration in V 5.0
authorvbd <vbd>
Fri, 18 Apr 2008 08:24:32 +0000 (08:24 +0000)
committervbd <vbd>
Fri, 18 Apr 2008 08:24:32 +0000 (08:24 +0000)
19 files changed:
src/INTERP_KERNEL/Geometric2D/AbstractEdge.hxx
src/INTERP_KERNEL/Geometric2D/Bounds.cxx
src/INTERP_KERNEL/Geometric2D/Bounds.hxx
src/INTERP_KERNEL/Geometric2D/ComposedEdge.cxx
src/INTERP_KERNEL/Geometric2D/ComposedEdge.hxx
src/INTERP_KERNEL/Geometric2D/Edge.hxx
src/INTERP_KERNEL/Geometric2D/EdgeArcCircle.cxx
src/INTERP_KERNEL/Geometric2D/EdgeArcCircle.hxx
src/INTERP_KERNEL/Geometric2D/EdgeLin.cxx
src/INTERP_KERNEL/Geometric2D/EdgeLin.hxx
src/INTERP_KERNEL/Geometric2D/ElementaryEdge.cxx
src/INTERP_KERNEL/Geometric2D/ElementaryEdge.hxx
src/INTERP_KERNEL/Geometric2D/Makefile.am
src/INTERP_KERNEL/Geometric2D/Node.cxx
src/INTERP_KERNEL/Geometric2D/Node.hxx
src/INTERP_KERNEL/Geometric2D/Precision.cxx [new file with mode: 0644]
src/INTERP_KERNEL/Geometric2D/Precision.hxx
src/INTERP_KERNEL/Geometric2D/QuadraticPolygon.cxx
src/INTERP_KERNEL/Geometric2D/QuadraticPolygon.hxx

index a30eaf23b87210e6d7be4441f24f30d9f2a0e354..ec2e21e5be64c06389a973686dba37df6693ead1 100644 (file)
@@ -57,6 +57,7 @@ namespace INTERP_KERNEL
     virtual double getAreaOfZone() const = 0;
     virtual void fillBounds(Bounds& output) const = 0;
     virtual void getAllNodes(std::set<Node *>& output) const = 0;
+    virtual void getBarycenter(double *bary, double& weigh) const = 0;
     virtual ElementaryEdge* &getLastElementary(IteratorOnComposedEdge::ItOnFixdLev &delta) = 0;
     virtual ElementaryEdge* &getFirstElementary(IteratorOnComposedEdge::ItOnFixdLev &delta) = 0;
     virtual const AbstractEdge *&operator[](IteratorOnComposedEdge::ItOnFixdLev i) const = 0;
@@ -65,9 +66,9 @@ namespace INTERP_KERNEL
     virtual Node *getStartNode() const = 0;
     virtual bool changeStartNodeWith(Node *node) const = 0;
     virtual bool changeEndNodeWith(Node *node) const = 0;
-    virtual void dumpInXfigFile(std::ostream& stream) const = 0;
     virtual bool intresicEqual(const AbstractEdge *other) const = 0;
     virtual bool intresicEqualDirSensitive(const AbstractEdge *other) const = 0;
+    virtual void dumpInXfigFile(std::ostream& stream, int resolution, const Bounds& box) const = 0;
     virtual bool intresincEqCoarse(const Edge *other) const = 0;
     virtual bool getDirection() const = 0;
   };
index 74bfc7ab6e3c1b74f7746477172109f1f1278668..bd6297221b60de280dbeccfc08c8accadec16900 100644 (file)
@@ -43,6 +43,22 @@ void Bounds::prepareForAggregation()
   _xMin=1e200; _xMax=-1e200; _yMin=1e200; _yMax=-1e200;
 }
 
+double Bounds::fitXForXFigD(double val, int res) const
+{
+  double delta=fmax(_xMax-_xMin,_yMax-_yMin)/2.;
+  double ret=val-(_xMax+_xMin)/2.+delta;
+  delta=11.1375*res/(2.*delta);
+  return ret*delta;
+}
+
+double Bounds::fitYForXFigD(double val, int res) const
+{
+  double delta=fmax(_xMax-_xMin,_yMax-_yMin)/2.;
+  double ret=val-(_yMax+_yMin)/2.+delta;
+  delta=11.1375*res/(2.*delta);
+  return ret*delta;
+}
+
 Bounds *Bounds::nearlyAmIIntersectingWith(const Bounds& other) const
 {
   if( (other._xMin > _xMax+QUADRATIC_PLANAR::_precision) || (other._xMax < _xMin-QUADRATIC_PLANAR::_precision) || (other._yMin > _yMax+QUADRATIC_PLANAR::_precision) 
index 89ccf82422455880da9327d81cd89f6a8ad3fb68..6b3553786826d1d262f24441623feacdd74d94c3 100644 (file)
@@ -24,6 +24,10 @@ namespace INTERP_KERNEL
     Bounds(double xMin, double xMax, double yMin, double yMax):_xMin(xMin),_xMax(xMax),_yMin(yMin),_yMax(yMax) { }
     void setValues(double xMin, double xMax, double yMin, double yMax) { _xMin=xMin; _xMax=xMax; _yMin=yMin; _yMax=yMax; }
     void prepareForAggregation();
+    int fitXForXFig(double val, int res) const { return (int)fitXForXFigD(val,res); }
+    int fitYForXFig(double val, int res) const { return (int)fitYForXFigD(val,res); }
+    double fitXForXFigD(double val, int res) const;
+    double fitYForXFigD(double val, int res) const;
     Bounds *nearlyAmIIntersectingWith(const Bounds& other) const;
     Bounds *amIIntersectingWith(const Bounds& other) const;
     //! No approximations.
index ed0f94c3f92520d1d2d44aa046bebba821843374..5d7f1eebd398c2eacf810df68b67b10fbf62d2e7 100644 (file)
@@ -103,10 +103,11 @@ double ComposedEdge::getAreaOfZone() const
   return ret;
 }
 
-void ComposedEdge::dumpInXfigFile(std::ostream& stream) const
+void ComposedEdge::dumpInXfigFile(std::ostream& stream, int resolution, const Bounds& box) const
 {
+  stream.precision(10);
   for(std::vector<AbstractEdge *>::const_iterator iter=_subEdges.begin();iter!=_subEdges.end();iter++)
-    (*iter)->dumpInXfigFile(stream);
+    (*iter)->dumpInXfigFile(stream,resolution,box);
 }
 
 Node *ComposedEdge::getEndNode() const
@@ -186,6 +187,21 @@ void ComposedEdge::getAllNodes(std::set<Node *>& output) const
     (*iter)->getAllNodes(output);
 }
 
+void ComposedEdge::getBarycenter(double *bary, double& weigh) const
+{
+  weigh=0.; bary[0]=0.; bary[1]=0.;
+  double tmp1,tmp2[2];
+  for(vector<AbstractEdge *>::const_iterator iter=_subEdges.begin();iter!=_subEdges.end();iter++)
+    {
+      (*iter)->getBarycenter(tmp2,tmp1);
+      weigh+=tmp1;
+      bary[0]+=tmp1*tmp2[0];
+      bary[1]+=tmp1*tmp2[1];
+    }
+  bary[0]/=weigh;
+  bary[1]/=weigh;
+}
+
 bool ComposedEdge::isInOrOut(Node *nodeToTest) const
 {
   Bounds b; b.prepareForAggregation();
index 60c93e1e92ff722336bd8938b477e21f6dba1739..16a24adf17b442524c5bb035aca88eb550a69c04 100644 (file)
@@ -21,6 +21,7 @@ namespace INTERP_KERNEL
     double getAreaOfZone() const;
     void fillBounds(Bounds& output) const;
     void getAllNodes(std::set<Node *>& output) const;
+    void getBarycenter(double *bary, double& weigh) const;
     bool completed() const { return getEndNode()==getStartNode(); }
     ElementaryEdge * &getLastElementary(IteratorOnComposedEdge::ItOnFixdLev &delta);
     ElementaryEdge * &getFirstElementary(IteratorOnComposedEdge::ItOnFixdLev &delta);
@@ -42,7 +43,7 @@ namespace INTERP_KERNEL
     bool addEdgeIfIn(ElementaryEdge *edge);
     bool changeEndNodeWith(Node *node) const;
     bool changeStartNodeWith(Node *node) const;
-    void dumpInXfigFile(std::ostream& stream) const;
+    void dumpInXfigFile(std::ostream& stream, int resolution, const Bounds& box) const;
     bool intresicEqual(const AbstractEdge *other) const;
     bool intresicEqualDirSensitive(const AbstractEdge *other) const;
     bool isInOrOut(Node *nodeToTest) const;
index 608fed38a4720439b65346e800a1451a0083574b..2a72b6c3949e9c219e348b302ac3e6433bb29674 100644 (file)
@@ -189,6 +189,7 @@ namespace INTERP_KERNEL
     //! returns area between this and axe Ox delimited along Ox by _start and _end.
     virtual double getAreaOfZone() const = 0;
     virtual double getCurveLength() const = 0;
+    virtual void getBarycenter(double *bary) const = 0;
     //! Retrieves a point that is owning to this, well placed for IN/OUT detection of this. Typically midlle of this is returned.
     virtual Node *buildRepresentantOfMySelf() const = 0;
     //! Given a magnitude specified by sub-type returns if in or not. See getCharactValue method.
@@ -203,7 +204,7 @@ namespace INTERP_KERNEL
                                  const EdgeArcCircle * &arcSeg) const = 0;
     bool intersectWith(const Edge *other, MergePoints& commonNode,
                        ComposedEdge& outVal1, ComposedEdge& outVal2) const;
-    virtual void dumpInXfigFile(std::ostream& stream, bool direction) const = 0;
+    virtual void dumpInXfigFile(std::ostream& stream, bool direction, int resolution, const Bounds& box) const = 0;
   protected:
     Edge():_cnt(1),_loc(FULL_UNKNOWN),_start(0),_end(0) { }
     virtual ~Edge();
index bd8ad250e50a5879681905e6c28837f434ee0fec..9b91e860ec75e1d491ddcd2e312385ab4c8098fe 100644 (file)
@@ -122,8 +122,71 @@ std::list< IntersectElement > ArcCArcCIntersector::getIntersectionsCharacteristi
   double u[2];//u is normalized vector from center1 to center2.
   u[0]=(center2[0]-center1[0])/_dist; u[1]=(center2[1]-center1[1])/_dist;
   double angle0_1=EdgeArcCircle::safeAcos(u[0]);
-  double angle0_2;
+  if(u[1]<0.)
+    angle0_1=-angle0_1;
+  double d1_1y=EdgeArcCircle::safeSqrt(radius1*radius1-d1_1*d1_1);
+  double angleE1=normalizeAngle(getE1().getAngle0()+getE1().getAngle());
+  double angleE2=normalizeAngle(getE2().getAngle0()+getE2().getAngle());
+  if(!Node::areDoubleEquals(d1_1y,0))
+    {
+      //2 intersections
+      double v1[2],v2[2];
+      v1[0]=u[0]*d1_1-u[1]*d1_1y; v1[1]=u[1]*d1_1+u[0]*d1_1y;
+      v2[0]=u[0]*d1_1+u[1]*d1_1y; v2[1]=u[1]*d1_1-u[0]*d1_1y;
+      Node *node1=new Node(center1[0]+v1[0],center1[1]+v1[1]); node1->declareOn();
+      Node *node2=new Node(center1[0]+v2[0],center1[1]+v2[1]); node2->declareOn();
+      double angle1_1=EdgeArcCircle::safeAcos(v1[0]/radius1);
+      if(v1[1]<0.)
+       angle1_1=-angle1_1;
+      double angle2_1=EdgeArcCircle::safeAcos(v2[0]/radius1);
+      if(v2[1]<0.)
+       angle2_1=-angle2_1;
+      double v3[2],v4[2];
+      v3[0]=center1[0]-center2[0]+v1[0]; v3[1]=center1[1]-center2[1]+v1[1];
+      v4[0]=center1[0]-center2[0]+v2[0]; v4[1]=center1[1]-center2[1]+v2[1];
+      double angle1_2=EdgeArcCircle::safeAcos(v3[0]/radius2);
+      if(v3[1]<0.)
+       angle1_2=-angle1_2;
+      double angle2_2=EdgeArcCircle::safeAcos(v4[0]/radius2);
+      if(v4[1]<0.)
+       angle2_2=-angle2_2;
+      //
+      bool e1_1S=Node::areDoubleEqualsWP(angle1_1,getE1().getAngle0(),radius1);
+      bool e1_1E=Node::areDoubleEqualsWP(angle1_1,angleE1,radius1);
+      bool e1_2S=Node::areDoubleEqualsWP(angle1_2,getE2().getAngle0(),radius1);
+      bool e1_2E=Node::areDoubleEqualsWP(angle1_2,angleE2,radius1);
+      //
+      bool e2_1S=Node::areDoubleEqualsWP(angle2_1,getE1().getAngle0(),radius2);
+      bool e2_1E=Node::areDoubleEqualsWP(angle2_1,angleE1,radius2);
+      bool e2_2S=Node::areDoubleEqualsWP(angle2_2,getE2().getAngle0(),radius2);
+      bool e2_2E=Node::areDoubleEqualsWP(angle2_2,angleE2,radius2);
+      ret.push_back(IntersectElement(angle1_1,angle1_2,e1_1S,e1_1E,e1_2S,e1_2E,node1,_e1,_e2,keepOrder()));
+      ret.push_back(IntersectElement(angle2_1,angle2_2,e2_1S,e2_1E,e2_2S,e2_2E,node2,_e1,_e2,keepOrder()));
+    }
+  else
+    {
+      //tangent intersection
+      double v1[2],v2[2];
+      v1[0]=d1_1*u[0]; v1[1]=d1_1*u[1];
+      v2[0]=center1[0]-center2[0]+v1[0]; v2[1]=center1[1]-center2[1]+v1[1];
+      double angle0_1=EdgeArcCircle::safeAcos(v1[0]/radius1);
+      if(v1[1]<0.)
+       angle0_1=-angle0_1;
+      double angle0_2=EdgeArcCircle::safeAcos(v2[0]/radius2);
+      if(v2[1]<0.)
+       angle0_2=-angle0_2;
+      bool e0_1S=Node::areDoubleEqualsWP(angle0_1,getE1().getAngle0(),radius1);
+      bool e0_1E=Node::areDoubleEqualsWP(angle0_1,angleE1,radius1);
+      bool e0_2S=Node::areDoubleEqualsWP(angle0_2,getE2().getAngle0(),radius2);
+      bool e0_2E=Node::areDoubleEqualsWP(angle0_2,angleE2,radius2);
+      Node *node=new Node(center1[0]+d1_1*u[0],center1[1]+d1_1*u[1]); node->declareOnTangent();
+      ret.push_back(IntersectElement(angle0_1,angle0_2,e0_1S,e0_1E,e0_2S,e0_2E,node,_e1,_e2,keepOrder()));
+    }
+  return ret;
+}
+  /*double angle0_2;
   double signDeltaAngle2;
+  double d1_2;
   if(u[1]<0.)
     angle0_1=-angle0_1;
   if(d1_1>=0.)
@@ -151,8 +214,7 @@ std::list< IntersectElement > ArcCArcCIntersector::getIntersectionsCharacteristi
   double angleE2=normalizeAngle(getE2().getAngle0()+getE2().getAngle());
   if(!(Node::areDoubleEquals(d1_1,radius1) || Node::areDoubleEquals(d1_1,-radius1)) )
     {
-      //2 intersections
-      double d1_2=_dist-d1_1;
+      //2 intersections   
       double deltaAngle1=EdgeArcCircle::safeAcos(fabs(d1_1)/radius1); //owns to 0;Pi/2 by construction
       double deltaAngle2=EdgeArcCircle::safeAcos(fabs(d1_2)/radius2); //owns to 0;Pi/2 by construction
       double angle1_1=normalizeAngle(angle0_1+deltaAngle1);// Intersection 1 seen for _e1
@@ -184,8 +246,7 @@ std::list< IntersectElement > ArcCArcCIntersector::getIntersectionsCharacteristi
       Node *node=new Node(center1[0]+radius1*cos(angle0_1),center1[0]+radius1*sin(angle0_1)); node->declareOnTangent();
       ret.push_back(IntersectElement(angle0_1,angle0_2,e0_1S,e0_1E,e0_2S,e0_2E,node,_e1,_e2,keepOrder()));
     }
-  return ret;
-}
+    return ret;*/
 
 /*!
  * Idem isAngleNotIn except that here 'start' in ]-Pi;Pi[ and delta in ]-2*Pi;2Pi[. 
@@ -257,8 +318,7 @@ std::list< IntersectElement > ArcCSegIntersector::getIntersectionsCharacteristic
   const double *center=getE1().getCenter();
   if(!(fabs(_determinant)<(QUADRATIC_PLANAR::_precision*10.)))//QUADRATIC_PLANAR::_precision*QUADRATIC_PLANAR::_precision*_drSq*_drSq/(2.*_dx*_dx))
     {
-      double determinant=fmax(_determinant,0.);
-      determinant=sqrt(_determinant);
+      double determinant=EdgeArcCircle::safeSqrt(_determinant);
       double x1=(_cross*_dy+Node::sign(_dy)*_dx*determinant)/_drSq+center[0];
       double y1=(-_cross*_dx+fabs(_dy)*determinant)/_drSq+center[1];
       Node *intersect1=new Node(x1,y1); intersect1->declareOn();
@@ -327,6 +387,7 @@ EdgeArcCircle::EdgeArcCircle(Node *start, Node *end, const double *center, doubl
 {
   _center[0]=center[0];
   _center[1]=center[1];
+  updateBounds();
 }
 
 void EdgeArcCircle::changeMiddle(Node *newMiddle)
@@ -342,7 +403,7 @@ Edge *EdgeArcCircle::buildEdgeLyingOnMe(Node *start, Node *end, bool direction)
   double ex=((*end)[0]-_center[0])/_radius;
   double ey=((*end)[1]-_center[1])/_radius;
   double angle0=safeAcos(direction?sx:ex);
-  angle0=direction?sy:ey>0.?angle0:-angle0;
+  angle0=(direction?sy:ey)>0.?angle0:-angle0;
   double deltaAngle=safeAcos(sx*ex+sy*ey);
   deltaAngle=sx*ey-sy*ex>0.?deltaAngle:-deltaAngle;
   if(deltaAngle>0. && _angle<0.)
@@ -361,7 +422,7 @@ void EdgeArcCircle::getArcOfCirclePassingThru(const double *start, const double
   double b2=(end[1]*end[1]+end[0]*end[0]-middle[0]*middle[0]-middle[1]*middle[1])/2;
   center[0]=((end[1]-middle[1])*b1+(start[1]-middle[1])*b2)/delta;
   center[1]=((middle[0]-end[0])*b1+(middle[0]-start[0])*b2)/delta;
-  radius=sqrt((start[0]-center[0])*(start[0]-center[0])+(start[1]-center[1])*(start[1]-center[1]));
+  radius=safeSqrt((start[0]-center[0])*(start[0]-center[0])+(start[1]-center[1])*(start[1]-center[1]));
   angleInRad0=safeAcos((start[0]-center[0])/radius);
   if((start[1]-center[1])<0.)
     angleInRad0=-angleInRad0;
@@ -375,7 +436,7 @@ void EdgeArcCircle::getArcOfCirclePassingThru(const double *start, const double
     angleInRad=angleInRad<0?2*M_PI+angleInRad:angleInRad-2*M_PI;
 }
 
-void EdgeArcCircle::dumpInXfigFile(std::ostream& stream, bool direction) const
+void EdgeArcCircle::dumpInXfigFile(std::ostream& stream, bool direction, int resolution, const Bounds& box) const
 {
   stream << "5 1 0 1 ";
   fillXfigStreamForLoc(stream);
@@ -385,12 +446,12 @@ void EdgeArcCircle::dumpInXfigFile(std::ostream& stream, bool direction) const
   else
     stream << '1';//'1'
   stream << " 0 0 ";
-  stream << (int)(_center[0]*Node::CST_FOR_XFIG) << " " << (int)(_center[1]*Node::CST_FOR_XFIG) << " ";
-  direction?_start->dumpInXfigFile(stream):_end->dumpInXfigFile(stream);
+  stream << box.fitXForXFigD(_center[0],resolution) << " " << box.fitYForXFigD(_center[1],resolution) << " ";
+  direction?_start->dumpInXfigFile(stream,resolution,box):_end->dumpInXfigFile(stream,resolution,box);
   Node *middle=buildRepresentantOfMySelf();
-  middle->dumpInXfigFile(stream);
+  middle->dumpInXfigFile(stream,resolution,box);
   middle->decrRef();
-  direction?_end->dumpInXfigFile(stream):_start->dumpInXfigFile(stream);
+  direction?_end->dumpInXfigFile(stream,resolution,box):_start->dumpInXfigFile(stream,resolution,box);
   stream << endl;
 }
 
@@ -410,6 +471,12 @@ double EdgeArcCircle::getCurveLength() const
   return fabs(_angle*_radius);
 }
 
+void EdgeArcCircle::getBarycenter(double *bary) const
+{
+  bary[0]=((*_start)[0]+(*_end)[0])/2.;
+  bary[1]=((*_start)[1]+(*_end)[1])/2.;
+}
+
 /*!
  * Characteristic value used is angle in ]_Pi;Pi[ from axe 0x.
  */
index d787a6f7e8d883049b7f921723f8a6d572a9b3f0..d8868d231c9c44331cc34174ea55aabb3bf7b27c 100644 (file)
@@ -57,10 +57,11 @@ namespace INTERP_KERNEL
     EdgeArcCircle(Node *start, Node *end, const double *center, double radius, double angle0, double deltaAngle, bool direction=true);
     //! for tests
     void changeMiddle(Node *newMiddle);
-    void dumpInXfigFile(std::ostream& stream, bool direction) const;
+    void dumpInXfigFile(std::ostream& stream, bool direction, int resolution, const Bounds& box) const;
     void update(Node *m);
     double getAreaOfZone() const;
     double getCurveLength() const;
+    void getBarycenter(double *bary) const;
     bool isIn(double characterVal) const;
     Node *buildRepresentantOfMySelf() const;
     bool isLower(double val1, double val2) const;
@@ -78,6 +79,7 @@ namespace INTERP_KERNEL
     static void getArcOfCirclePassingThru(const double *start, const double *middle, const double *end, 
                                           double *center, double& radius, double& angleInRad, double& angleInRad0);
     //! To avoid in aggressive optimizations nan.
+    static double safeSqrt(double val) { double ret=fmax(val,0.); return sqrt(ret); }
     static double safeAcos(double cosAngle) { double ret=fmin(cosAngle,1.); ret=fmax(ret,-1.); return acos(ret); }
   protected:
     void updateBounds();
index 749eb08e1c3f3150cff09442f58ca2cdffe4bcf6..fd4b86178675e8f025e4a93013de3ed4f92a781d 100644 (file)
@@ -1,5 +1,6 @@
 #include "EdgeLin.hxx"
 #include "Node.hxx"
+#include "InterpolationUtils.hxx"
 
 using namespace std;
 using namespace INTERP_KERNEL;
@@ -78,6 +79,17 @@ std::list< IntersectElement > SegSegIntersector::getIntersectionsCharacteristicV
   return ret;
 }
 
+/*!
+ * retrieves if segs are colinears.
+ * WARNING !!! Contrary to areOverlappedOrOnlyColinears method, this method use an
+ * another precision to detect colinearity !
+ */
+bool SegSegIntersector::areColinears() const
+{
+  double determinant=_matrix[0]*_matrix[3]-_matrix[1]*_matrix[2];
+  return fabs(determinant)<QUADRATIC_PLANAR::_arcDetectionPrecision;
+}
+
 /*!
  * Should be called \b once ! non const method.
  * \param whereToFind specifies the box where final seek should be done. Essentially it is used for caracteristic reason.
@@ -104,13 +116,6 @@ void SegSegIntersector::areOverlappedOrOnlyColinears(const Bounds *whereToFind,
       double x=(*(_e1.getStartNode()))[0]-(*(_e2.getStartNode()))[0];
       double y=(*(_e1.getStartNode()))[1]-(*(_e2.getStartNode()))[1];
       areOverlapped=fabs((_matrix[1]*y+_matrix[0]*x)/deno)<QUADRATIC_PLANAR::_precision;
-      /*double tmp=_matrix[0]; _matrix[0]=_matrix[3]; _matrix[3]=tmp;
-      _matrix[1]=-_matrix[1]; _matrix[2]=-_matrix[2];
-      double dist1=(_col[0]-(*whereToFind)[2*(_ind)]*_matrix[!_ind])/_matrix[_ind];
-      double dist2=(_col[1]-(*whereToFind)[2*(_ind)]*_matrix[!_ind+2])/_matrix[_ind+2];
-      double dist3=(_col[0]-(*whereToFind)[2*(_ind)+1]*_matrix[!_ind])/_matrix[_ind];
-      double dist4=(_col[1]-(*whereToFind)[2*(_ind)+1]*_matrix[!_ind+2])/_matrix[_ind+2];
-      areOverlapped=(fmax(fabs(dist1-dist2),fabs(dist3-dist4))<1.4142135623730951*QUADRATIC_PLANAR::_precision);*/
     }
 }
 
@@ -157,13 +162,13 @@ double EdgeLin::getCharactValue(const Node& node) const
   return (car1_1x*car1_2x+car1_1y*car1_2y)/(car1_2x*car1_2x+car1_2y*car1_2y);
 }
 
-void EdgeLin::dumpInXfigFile(std::ostream& stream, bool direction) const
+void EdgeLin::dumpInXfigFile(std::ostream& stream, bool direction, int resolution, const Bounds& box) const
 {
   stream << "2 1 0 1 ";
   fillXfigStreamForLoc(stream);
   stream << " 7 50 -1 -1 0.000 0 0 -1 0 0 2" << endl;
-  direction?_start->dumpInXfigFile(stream):_end->dumpInXfigFile(stream);
-  direction?_end->dumpInXfigFile(stream):_start->dumpInXfigFile(stream);
+  direction?_start->dumpInXfigFile(stream,resolution,box):_end->dumpInXfigFile(stream,resolution,box);
+  direction?_end->dumpInXfigFile(stream,resolution,box):_start->dumpInXfigFile(stream,resolution,box);
   stream << endl;
 }
 
@@ -182,6 +187,12 @@ double EdgeLin::getAreaOfZone() const
   return ((*_start)[0]-(*_end)[0])*((*_start)[1]+(*_end)[1])/2.;
 }
 
+void EdgeLin::getBarycenter(double *bary) const
+{
+  bary[0]=((*_start)[0]+(*_end)[0])/2.;
+  bary[1]=((*_start)[1]+(*_end)[1])/2.;
+}
+
 double EdgeLin::getCurveLength() const
 {
   double x=(*_start)[0]-(*_end)[0];
index ec8d5f101c2ae50c5d32036fef57d25b8aba2ad8..23cde49822956dc5e2ebc898b28f51f748fa2382 100644 (file)
@@ -10,6 +10,7 @@ namespace INTERP_KERNEL
       friend class Edge;
     public:
       SegSegIntersector(const EdgeLin& e1, const EdgeLin& e2);
+      bool areColinears() const;
       bool haveTheySameDirection() const;
       void getPlacements(Node *start, Node *end, TypeOfLocInEdge& whereStart, TypeOfLocInEdge& whereEnd, MergePoints& commonNode) const;
       void areOverlappedOrOnlyColinears(const Bounds *whereToFind, bool& obviousNoIntersection, bool& areOverlapped);
@@ -32,11 +33,12 @@ namespace INTERP_KERNEL
     EdgeLin(double sX, double sY, double eX, double eY);
     ~EdgeLin();
     TypeOfFunction getTypeOfFunc() const { return SEG; }
-    void dumpInXfigFile(std::ostream& stream, bool direction) const;
+    void dumpInXfigFile(std::ostream& stream, bool direction, int resolution, const Bounds& box) const;
     void update(Node *m);
     double getNormSq() const;
     double getAreaOfZone() const;
     double getCurveLength() const;
+    void getBarycenter(double *bary) const;
     bool isIn(double characterVal) const;
     Node *buildRepresentantOfMySelf() const;
     double getCharactValue(const Node& node) const;
index 797feee4853cedad26662057d6df3064c4e476f7..be84a880b6fa13dad3b69efe583473ac36e62e40 100644 (file)
@@ -30,6 +30,12 @@ void ElementaryEdge::getAllNodes(std::set<Node *>& output) const
   output.insert(_ptr->getEndNode());
 }
 
+void ElementaryEdge::getBarycenter(double *bary, double& weigh) const
+{
+  _ptr->getBarycenter(bary);
+  weigh=_ptr->getCurveLength();
+}
+
 AbstractEdge *ElementaryEdge::clone() const
 {
   return new ElementaryEdge(*this);
@@ -145,9 +151,9 @@ bool ElementaryEdge::changeStartNodeWith(Node *node) const
     return _ptr->changeEndNodeWith(node);
 }
 
-void ElementaryEdge::dumpInXfigFile(std::ostream& stream) const
+void ElementaryEdge::dumpInXfigFile(std::ostream& stream, int resolution, const Bounds& box) const
 {
-  _ptr->dumpInXfigFile(stream,_direction);
+  _ptr->dumpInXfigFile(stream,_direction,resolution,box);
 }
 
 bool ElementaryEdge::intresicEqual(const AbstractEdge *other) const
index 364d22f165946b15cef5781aa40dc04779783b29..ae2dab9361858d788a1ef2211ba4ea2a918f68d6 100644 (file)
@@ -26,6 +26,7 @@ namespace INTERP_KERNEL
     double getAreaOfZone() const { return getAreaOfZoneFast(); }
     void fillBounds(Bounds& output) const;
     void getAllNodes(std::set<Node *>& output) const;
+    void getBarycenter(double *bary, double& weigh) const;
     double getAreaOfZoneFast() const { double ret=_ptr->getAreaOfZone(); return _direction?ret:-ret; }
     AbstractEdge *clone() const;
     int recursiveSize() const;
@@ -39,9 +40,9 @@ namespace INTERP_KERNEL
     double getCurveLength() const { return _ptr->getCurveLength(); }
     bool changeEndNodeWith(Node *node) const;
     bool changeStartNodeWith(Node *node) const;
-    void dumpInXfigFile(std::ostream& stream) const;
     bool intresicEqual(const AbstractEdge *other) const;
     bool intresicEqualDirSensitive(const AbstractEdge *other) const;
+    void dumpInXfigFile(std::ostream& stream, int resolution, const Bounds& box) const;
     bool getDirection() const { return _direction; }
     bool intresincEqCoarse(const Edge *other) const;
   private:
index 75551d0cde0b27a6503ba3cf0804a74818d5722a..65a017b53c26fcd3fd47f759f3548fde94da6505 100644 (file)
@@ -32,6 +32,7 @@ noinst_LTLIBRARIES = libInterpGeometric2DAlg.la
 dist_libInterpGeometric2DAlg_la_SOURCES = \
 AbstractEdge.cxx     \
 Bounds.cxx           \
+Precision.cxx        \
 ComposedEdge.cxx     \
 EdgeArcCircle.cxx    \
 Edge.cxx             \
index ed60e38bf54e155cf7f785a051d85ed481bf84f0..1f88b6d94187fba5ffb0ab60ea6607f299566502 100644 (file)
@@ -4,8 +4,6 @@
 using namespace std;
 using namespace INTERP_KERNEL;
 
-const double Node::CST_FOR_XFIG=1e4;
-
 Node::Node(double x, double y):_isToDel(true),_cnt(1),_loc(UNKNOWN)
 {
   const unsigned SPACEDIM=2;
@@ -25,7 +23,7 @@ Node::Node(std::istream& stream):_isToDel(true),_cnt(1),_loc(UNKNOWN)
     {
       int tmp;
       stream >> tmp;
-      _coords[i]=((double) tmp)/CST_FOR_XFIG;
+      _coords[i]=((double) tmp)/1e4;
     }
 }
 
@@ -76,9 +74,9 @@ bool Node::isEqualAndKeepTrack(const Node& other, std::vector<Node *>& track) co
   return ret;
 }
 
-void Node::dumpInXfigFile(std::ostream& stream) const
+void Node::dumpInXfigFile(std::ostream& stream, int resolution, const Bounds& box) const
 {
-  stream << (int)(_coords[0]*CST_FOR_XFIG) << " " << (int)(_coords[1]*CST_FOR_XFIG) << " ";
+  stream << box.fitXForXFig(_coords[0],resolution) << " " << box.fitYForXFig(_coords[1],resolution) << " ";
 }
 
 double Node::distanceWithSq(const Node& other) const
index 45c4025c10f4ddab7ab882c6c366da9359ef3640..5c5c9fadff70c42332a10a8289aa7efe075f0a1c 100644 (file)
@@ -18,6 +18,8 @@ namespace INTERP_KERNEL
       OUT_1     = 10,
       UNKNOWN   = 11
     } TypeOfLocInPolygon;
+
+  class Bounds;
   
   /*!
    * As nodes can be shared between edges it is dealed with ref counting.
@@ -40,7 +42,7 @@ namespace INTERP_KERNEL
     bool isEqual(const Node& other) const;
     double getSlope(const Node& other) const;
     bool isEqualAndKeepTrack(const Node& other, std::vector<Node *>& track) const;
-    void dumpInXfigFile(std::ostream& stream) const;
+    void dumpInXfigFile(std::ostream& stream, int resolution, const Bounds& box) const;
     double distanceWithSq(const Node& other) const;
     double operator[](int i) const { return _coords[i]; }
     //!for tests only !
@@ -57,8 +59,6 @@ namespace INTERP_KERNEL
     mutable unsigned char _cnt;
     mutable TypeOfLocInPolygon _loc;
     double *_coords;
-  public:
-    static const double CST_FOR_XFIG;
   };
 }
 
diff --git a/src/INTERP_KERNEL/Geometric2D/Precision.cxx b/src/INTERP_KERNEL/Geometric2D/Precision.cxx
new file mode 100644 (file)
index 0000000..cb67b20
--- /dev/null
@@ -0,0 +1,15 @@
+#include "Precision.hxx"
+
+double INTERP_KERNEL::QUADRATIC_PLANAR::_precision=1e-14;
+
+double INTERP_KERNEL::QUADRATIC_PLANAR::_arcDetectionPrecision=1e-14;
+
+void INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(double precision)
+{ 
+  INTERP_KERNEL::QUADRATIC_PLANAR::_precision=precision;
+}
+
+void INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(double precision)
+{
+  INTERP_KERNEL::QUADRATIC_PLANAR::_arcDetectionPrecision=precision;
+}
index 5eb79135962d8273951cbf3d6c862a8f6735f44b..9eb3d275ee8c395b4d71a19fba28812804cb3899 100644 (file)
@@ -1,7 +1,11 @@
 namespace INTERP_KERNEL
 {
-  namespace QUADRATIC_PLANAR
+  class QUADRATIC_PLANAR
   {
-    static double _precision=1e-14;
-  }
+  public:
+    static double _precision;
+    static double _arcDetectionPrecision;
+    static void setPrecision(double precision);
+    static void setArcDetectionPrecision(double precision);
+  };
 }
index 712eb8c0fd5437ba695585e0f41e2a09381b681b..c12a58678ddb266cc52755de2e881c211d803f1c 100644 (file)
@@ -65,19 +65,25 @@ QuadraticPolygon *QuadraticPolygon::buildArcCirclePolygon(std::vector<Node *>& n
     {
       EdgeLin *e1,*e2;
       e1=new EdgeLin(nodes[i],nodes[i+size/2]);
-      e2=new EdgeLin(nodes[i+size/2],nodes[(i+1)%size]);
+      e2=new EdgeLin(nodes[i+size/2],nodes[(i+1)%(size/2)]);
       SegSegIntersector inters(*e1,*e2);
-      bool colinearity,areOverlapped;
-      inters.areOverlappedOrOnlyColinears(0,colinearity,areOverlapped);
+      bool colinearity=inters.areColinears();
+      delete e1; delete e2;
       if(colinearity)
-        ret->pushBack(new EdgeLin(nodes[i],nodes[(i+1)%size]));
+        ret->pushBack(new EdgeLin(nodes[i],nodes[(i+1)%(size/2)]));
       else
-        ret->pushBack(new EdgeArcCircle(nodes[i],nodes[i+size/2],nodes[(i+1)%size]));
+        ret->pushBack(new EdgeArcCircle(nodes[i],nodes[i+size/2],nodes[(i+1)%(size/2)]));
       nodes[i]->decrRef(); nodes[i+size/2]->decrRef();
     }
   return ret;
 }
 
+void QuadraticPolygon::closeMe() const
+{
+  if(!front()->changeStartNodeWith(back()->getEndNode()))
+    throw(Exception("big error: not closed polygon..."));
+}
+
 void QuadraticPolygon::circularPermute()
 {
   vector<AbstractEdge *>::iterator iter1=_subEdges.begin();
@@ -112,24 +118,45 @@ double QuadraticPolygon::getPerimeterFast() const
   return ret;
 }
 
-double QuadraticPolygon::getHydroulicDiameter() const
+double QuadraticPolygon::getHydraulicDiameter() const
 {
   return 4*fabs(getAreaFast())/getPerimeterFast();
 }
 
+void QuadraticPolygon::dumpInXfigFileWithOther(const ComposedEdge& other, const char *fileName) const
+{
+  ofstream file(fileName);
+  const int resolution=1200;
+  Bounds box;
+  box.prepareForAggregation();
+  fillBounds(box);
+  other.fillBounds(box);
+  dumpInXfigFile(file,resolution,box);
+  other.ComposedEdge::dumpInXfigFile(file,resolution,box);
+}
+
 void QuadraticPolygon::dumpInXfigFile(const char *fileName) const
 {
   ofstream file(fileName);
-  file << "#FIG 3.2  Produced by xfig version 3.2.5-alpha5" << endl;
-  file << "Landscape" << endl;
-  file << "Center" << endl;
-  file << "Inches" << endl;
-  file << "Letter" << endl;
-  file << "100.00" << endl;
-  file << "Single" << endl;
-  file << "-2" << endl;
-  file << "1200 2" << endl;
-  ComposedEdge::dumpInXfigFile(file);
+  const int resolution=1200;
+  Bounds box;
+  box.prepareForAggregation();
+  fillBounds(box);
+  dumpInXfigFile(file,resolution,box);
+}
+
+void QuadraticPolygon::dumpInXfigFile(std::ostream& stream, int resolution, const Bounds& box) const
+{
+  stream << "#FIG 3.2  Produced by xfig version 3.2.5-alpha5" << endl;
+  stream << "Landscape" << endl;
+  stream << "Center" << endl;
+  stream << "Metric" << endl;
+  stream << "Letter" << endl;
+  stream << "100.00" << endl;
+  stream << "Single" << endl;
+  stream << "-2" << endl;
+  stream << resolution << " 2" << endl;
+  ComposedEdge::dumpInXfigFile(stream,resolution,box);
 }
 
 double QuadraticPolygon::intersectWith(const QuadraticPolygon& other) const
@@ -138,7 +165,7 @@ double QuadraticPolygon::intersectWith(const QuadraticPolygon& other) const
   vector<QuadraticPolygon *> polygs=intersectMySelfWith(other);
   for(vector<QuadraticPolygon *>::iterator iter=polygs.begin();iter!=polygs.end();iter++)
     {
-      ret+=fabs((*iter)->getAreaFast());
+      ret+=fabs((*iter)->getAreaOfZone());
       delete *iter;
     }
   return ret;
@@ -197,10 +224,10 @@ void QuadraticPolygon::splitPolygonsEachOther(QuadraticPolygon& pol1, QuadraticP
               c2=new ComposedEdgeWithIt;
             }
           else
-                                               {
-                                                       updateNeighbours(merge,it1,it2,curE1,curE2);
-                                                       it1.next();
-                                               }
+           {
+             updateNeighbours(merge,it1,it2,curE1,curE2);
+             it1.next();
+           }
         }
     }
   ComposedEdge::Delete(c1); delete c2;
index 3232b914f36aaf11ed9fe8bef8781bfaae894a46..9096db02d7a9575150a7b92dd081e993c46c02cc 100644 (file)
@@ -19,12 +19,14 @@ namespace INTERP_KERNEL
     static QuadraticPolygon *buildLinearPolygon(std::vector<Node *>& nodes);
     static QuadraticPolygon *buildArcCirclePolygon(std::vector<Node *>& nodes);
     ~QuadraticPolygon();
+    void closeMe() const;
     void circularPermute();
     //! warning : use it if and only if this is composed of ElementaryEdges only : typical case.
     double getAreaFast() const;
     double getPerimeterFast() const;
-    double getHydroulicDiameter() const;
+    double getHydraulicDiameter() const;
     void dumpInXfigFile(const char *fileName) const;
+    void dumpInXfigFileWithOther(const ComposedEdge& other, const char *fileName) const;
     double intersectWith(const QuadraticPolygon& other) const;
     std::vector<QuadraticPolygon *> intersectMySelfWith(const QuadraticPolygon& other) const;
   public://Only public for tests reasons
@@ -34,6 +36,7 @@ namespace INTERP_KERNEL
     bool amIAChanceToBeCompletedBy(const QuadraticPolygon& pol1Splitted, const QuadraticPolygon& pol2NotSplitted, bool& direction);
   protected:
     std::list<QuadraticPolygon *> zipConsecutiveInSegments() const;
+    void dumpInXfigFile(std::ostream& stream, int resolution, const Bounds& box) const;
     void closePolygons(std::list<QuadraticPolygon *>& pol2Zip, const QuadraticPolygon& pol1, std::vector<QuadraticPolygon *>& results) const;
     static void updateNeighbours(const MergePoints& merger, IteratorOnComposedEdge it1, IteratorOnComposedEdge it2,
                                 const AbstractEdge *e1, const AbstractEdge *e2);