#include "EdgeArcCircle.hxx"
#include "Node.hxx"
-#include <cmath>
-
using namespace INTERP_KERNEL;
const double& Bounds::operator[](int i) const
return sqrt(a*a+b*b);
}
+/*!
+ * See Node::applySimilarity to see signification of params.
+ */
+void Bounds::applySimilarity(double xBary, double yBary, double dimChar)
+{
+ _xMin=(_xMin-xBary)/dimChar;
+ _xMax=(_xMax-xBary)/dimChar;
+ _yMin=(_yMin-yBary)/dimChar;
+ _yMax=(_yMax-yBary)/dimChar;
+}
+
void Bounds::getBarycenter(double& xBary, double& yBary) const
{
xBary=(_xMin+_xMax)/2.;
_xMin=fmin(_xMin,other._xMin); _xMax=fmax(_xMax,other._xMax);
_yMin=fmin(_yMin,other._yMin); _yMax=fmax(_yMax,other._yMax);
}
-
-double Bounds::getCaracteristicDim() const
-{
- return fmax(_xMax-_xMin,_yMax-_yMin);
-}
#ifndef __BOUNDS_HXX__
#define __BOUNDS_HXX__
+#include <cmath>
+
namespace INTERP_KERNEL
{
/*!
const double& operator[](int i) const;
double getDiagonal() const;
void getBarycenter(double& xBary, double& yBary) const;
+ void applySimilarity(double xBary, double yBary, double dimChar);
Bounds& operator=(const Bounds& other) { _xMin=other._xMin; _xMax=other._xMax; _yMin=other._yMin; _yMax=other._yMax; return *this; }
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; }
//! Idem where method but with approximations.
Position nearlyWhere(double x, double y) const;
void aggregate(const Bounds& other);
- double getCaracteristicDim() const;
+ double getCaracteristicDim() const { return fmax(_xMax-_xMin,_yMax-_yMin); }
protected:
double _xMin;
double _xMax;
{
Bounds b;
b.prepareForAggregation();
- fillBounds(b);
+ fillBounds(b);
other->fillBounds(b);
- double dimChar=b.getDiagonal();
+ double dimChar=b.getCaracteristicDim();
double xBary,yBary;
b.getBarycenter(xBary,yBary);
- applySimilarity(xBary,yBary,dimChar);
- other->applySimilarity(xBary,yBary,dimChar);
+ applyGlobalSimilarity(xBary,yBary,dimChar);
+ other->applyGlobalSimilarity(xBary,yBary,dimChar);
return dimChar;
}
(*iter)->fillBounds(output);
}
+/*!
+ * \b WARNING : applies similarity \b ONLY on edges without any change on Nodes. To perform a global similarity call applyGlobalSimilarity.
+ */
void ComposedEdge::applySimilarity(double xBary, double yBary, double dimChar)
{
for(list<ElementaryEdge *>::iterator iter=_subEdges.begin();iter!=_subEdges.end();iter++)
(*iter)->applySimilarity(xBary,yBary,dimChar);
}
+/*!
+ * Perform Similarity transformation on all elements of this Nodes and Edges.
+ */
+void ComposedEdge::applyGlobalSimilarity(double xBary, double yBary, double dimChar)
+{
+ set<Node *> allNodes;
+ getAllNodes(allNodes);
+ for(set<Node *>::iterator iter=allNodes.begin();iter!=allNodes.end();iter++)
+ (*iter)->applySimilarity(xBary,yBary,dimChar);
+ for(list<ElementaryEdge *>::iterator iter=_subEdges.begin();iter!=_subEdges.end();iter++)
+ (*iter)->applySimilarity(xBary,yBary,dimChar);
+}
+
/*!
* @param part1 INOUT parameter. If an edge in 'this' is found with an id in 'ids1', 'part1' is \b incremented.
* @param part2 INOUT parameter. If an edge in 'this' is found with an id in 'ids2', 'part2' is \b incremented.
double normalize(ComposedEdge *other);
void fillBounds(Bounds& output) const;
void applySimilarity(double xBary, double yBary, double dimChar);
+ void applyGlobalSimilarity(double xBary, double yBary, double dimChar);
void dispatchPerimeter(const std::set<int>& ids1, const std::set<int>& ids2,
double& part1, double& part2, double& commonPart) const;
double dispatchPerimeterAdv(const ComposedEdge& father, std::vector<double>& result) const;
return ret;
}
+/*!
+ * See Node::applySimilarity to see signification of params.
+ */
void Edge::applySimilarity(double xBary, double yBary, double dimChar)
{
- _start->applySimilarity(xBary,yBary,dimChar);
- _end->applySimilarity(xBary,yBary,dimChar);
+ _bounds.applySimilarity(xBary,yBary,dimChar);
}
bool Edge::intersect(const Edge *f1, const Edge *f2, Intersector *intersector, const Bounds *whereToFind, MergePoints& commonNode,
{
Edge::applySimilarity(xBary,yBary,dimChar);
_radius/=dimChar;
+ _center[0]=(_center[0]-xBary)/dimChar;
+ _center[1]=(_center[1]-yBary)/dimChar;
}
double EdgeArcCircle::getAbsoluteAngle(const double *vect, double& normVect)
void updateBounds();
Edge *buildEdgeLyingOnMe(Node *start, Node *end, bool direction=true) const;
protected:
- //Value between -2Pi and 2Pi
+ //!Value between -2Pi and 2Pi
double _angle;
- //Value between -Pi and Pi
+ //!Value between -Pi and Pi
double _angle0;
double _radius;
double _center[2];
using namespace std;
using namespace INTERP_KERNEL;
-Node::Node(double x, double y):_isToDel(true),_cnt(1),_loc(UNKNOWN)
+Node::Node(double x, double y):_cnt(1),_loc(UNKNOWN)
{
- const unsigned SPACEDIM=2;
- _coords=new double[SPACEDIM];
_coords[0]=x; _coords[1]=y;
}
-Node::Node(const double *coords):_isToDel(false),_cnt(1),_loc(UNKNOWN),_coords((double *)coords)
+Node::Node(const double *coords):_cnt(1),_loc(UNKNOWN)
{
+ _coords[0]=coords[0];
+ _coords[1]=coords[1];
}
-Node::Node(std::istream& stream):_isToDel(true),_cnt(1),_loc(UNKNOWN)
+Node::Node(std::istream& stream):_cnt(1),_loc(UNKNOWN)
{
- const unsigned SPACEDIM=2;
- _coords=new double[SPACEDIM];
- for(unsigned i=0;i<SPACEDIM;i++)
- {
- int tmp;
- stream >> tmp;
- _coords[i]=((double) tmp)/1e4;
- }
+ int tmp;
+ stream >> tmp;
+ _coords[0]=((double) tmp)/1e4;
+ stream >> tmp;
+ _coords[1]=((double) tmp)/1e4;
}
Node::~Node()
{
- if(_isToDel)
- delete [] _coords;
}
bool Node::decrRef()
return -ret;
}
+/*!
+ * apply a Similarity transformation on this.
+ * @param xBary is the opposite of the X translation to do.
+ * @param yBary is the opposite of the Y translation to do.
+ * @param dimChar is the reduction factor.
+ */
void Node::applySimilarity(double xBary, double yBary, double dimChar)
{
- _coords[0]=(_coords[0]+xBary)/dimChar;
- _coords[1]=(_coords[1]+yBary)/dimChar;
+ _coords[0]=(_coords[0]-xBary)/dimChar;
+ _coords[1]=(_coords[1]-yBary)/dimChar;
}
protected:
~Node();
protected:
- bool _isToDel;
mutable unsigned char _cnt;
mutable TypeOfLocInPolygon _loc;
- double *_coords;
+ double _coords[2];
};
}
ComposedEdge::dumpInXfigFile(stream,resolution,box);
}
+/*!
+ * Warning contrary to intersectWith method this method is \b NOT const. 'this' and 'other' are modified after call of this method.
+ */
+double QuadraticPolygon::intersectWithAbs(QuadraticPolygon& other)
+{
+ double ret=0.;
+ double fact=normalize(&other);
+ vector<QuadraticPolygon *> polygs=intersectMySelfWith(other);
+ for(vector<QuadraticPolygon *>::iterator iter=polygs.begin();iter!=polygs.end();iter++)
+ {
+ ret+=fabs((*iter)->getArea());
+ delete *iter;
+ }
+ return ret*fact*fact;
+}
+
double QuadraticPolygon::intersectWith(const QuadraticPolygon& other) const
{
double ret=0.;
void circularPermute();
void dumpInXfigFile(const char *fileName) const;
void dumpInXfigFileWithOther(const ComposedEdge& other, const char *fileName) const;
+ //! Before intersecting as intersectWith a normalization is done.
+ double intersectWithAbs(QuadraticPolygon& other);
double intersectWith(const QuadraticPolygon& other) const;
std::vector<QuadraticPolygon *> intersectMySelfWith(const QuadraticPolygon& other) const;
void intersectForPerimeter(const QuadraticPolygon& other, double& perimeterThisPart, double& perimeterOtherPart, double& perimeterCommonPart, double& area) const;
delete pol1;
delete pol2;
}
+
+void QuadraticPlanarInterpTest::checkNormalize()
+{
+ INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-14);
+ Node *n1=new Node(0.,0.); Node *n4=new Node(0.,-3.);
+ Node *n2=new Node(10.,0.); Node *n5=new Node(10.,-3.);
+ Node *n3=new Node(5.,10.); Node *n6=new Node(5.,7.);
+ EdgeLin *e1_2=new EdgeLin(n1,n2); EdgeLin *e4_5=new EdgeLin(n4,n5);
+ EdgeLin *e2_3=new EdgeLin(n2,n3); EdgeLin *e5_6=new EdgeLin(n5,n6);
+ EdgeLin *e3_1=new EdgeLin(n3,n1); EdgeLin *e6_4=new EdgeLin(n6,n4);
+ //
+ QuadraticPolygon pol1; pol1.pushBack(e1_2); pol1.pushBack(e2_3); pol1.pushBack(e3_1);
+ QuadraticPolygon pol2; pol2.pushBack(e4_5); pol2.pushBack(e5_6); pol2.pushBack(e6_4);
+ n1->decrRef(); n2->decrRef(); n3->decrRef(); n4->decrRef(); n5->decrRef(); n6->decrRef();
+ double area1Start=pol1.getArea();
+ double fact=pol1.normalize(&pol2);
+ double area1End=pol1.getArea();
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(area1Start,area1End*fact*fact,1e-14);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(13.,fact,1.e-14);
+ double area=pol1.intersectWith(pol2);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(24.5,area*fact*fact,1e-14);
+ //
+ n1=new Node(0.,0.); n4=new Node(0.,-3.);
+ n2=new Node(10.,0.); n5=new Node(10.,-3.);
+ n3=new Node(5.,10.); n6=new Node(5.,7.);
+ e1_2=new EdgeLin(n1,n2); e4_5=new EdgeLin(n4,n5);
+ e2_3=new EdgeLin(n2,n3); e5_6=new EdgeLin(n5,n6);
+ e3_1=new EdgeLin(n3,n1); e6_4=new EdgeLin(n6,n4);
+ QuadraticPolygon pol3; pol3.pushBack(e1_2); pol3.pushBack(e2_3); pol3.pushBack(e3_1);
+ QuadraticPolygon pol4; pol4.pushBack(e4_5); pol4.pushBack(e5_6); pol4.pushBack(e6_4);
+ n1->decrRef(); n2->decrRef(); n3->decrRef(); n4->decrRef(); n5->decrRef(); n6->decrRef();
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(24.5,pol3.intersectWithAbs(pol4),1.e-14);
+ // Ok testing EdgeArcCircle update.
+ double center[2]={5.,5.};
+ double radius=300.;
+ EdgeArcCircle *e1=buildArcOfCircle(center,radius,M_PI/4.,M_PI/3.);
+ const Bounds& b=e1->getBounds();
+ double x,y,fact2;
+ fact2=b.getCaracteristicDim();
+ b.getBarycenter(x,y);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(78.539816339744817,e1->getCurveLength(),1e-13);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(15106.061037591669,e1->getAreaOfZone(),1e-10);
+ e1->getStartNode()->applySimilarity(x,y,fact2);
+ e1->getEndNode()->applySimilarity(x,y,fact2);
+ e1->applySimilarity(x,y,fact2);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(62.132034355964237,fact2,1e-13);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(1.2640792652913602,e1->getCurveLength(),1e-14);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(0.034741420428165526,e1->getAreaOfZone(),1e-13);
+ e1->decrRef();
+}