]> SALOME platform Git repositories - tools/medcoupling.git/blob - src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DNode.cxx
Salome HOME
Merge from V6_main_20120808 08Aug12
[tools/medcoupling.git] / src / INTERP_KERNEL / Geometric2D / InterpKernelGeo2DNode.cxx
1 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 #include "InterpKernelGeo2DNode.hxx"
21 #include "InterpKernelGeo2DEdgeArcCircle.hxx"
22
23 using namespace INTERP_KERNEL;
24
25 Node::Node(double x, double y):_cnt(1),_loc(UNKNOWN)
26 {
27   _coords[0]=x; _coords[1]=y;
28 }
29
30 Node::Node(const double *coords):_cnt(1),_loc(UNKNOWN)
31 {
32   _coords[0]=coords[0];
33   _coords[1]=coords[1];
34 }
35
36 Node::Node(std::istream& stream):_cnt(1),_loc(UNKNOWN)
37 {
38   int tmp;
39   stream >> tmp;
40   _coords[0]=((double) tmp)/1e4;
41   stream >> tmp;
42   _coords[1]=((double) tmp)/1e4;
43 }
44
45 Node::~Node()
46 {
47 }
48
49 bool Node::decrRef()
50 {
51   bool ret=(--_cnt==0);
52   if(ret)
53     delete this;
54   return ret;
55 }
56
57 bool Node::isEqual(const Node& other) const
58 {
59   const unsigned SPACEDIM=2;
60   bool ret=true;
61   for(unsigned i=0;i<SPACEDIM;i++)
62     ret&=areDoubleEquals((*this)[i],other[i]);
63   return ret;
64 }
65
66 double Node::getSlope(const Node& other) const
67 {
68   return computeSlope(*this, other);
69 }
70
71 /*!
72  * Convenient method. Equivalent to isEqual method. In case of true is returned, '&other' is
73  * added in 'track' container.
74  */
75 bool Node::isEqualAndKeepTrack(const Node& other, std::vector<Node *>& track) const
76 {
77   bool ret=isEqual(other);
78   if(ret)
79     track.push_back(const_cast<Node *>(&other));
80   return ret;
81 }
82
83 void Node::dumpInXfigFile(std::ostream& stream, int resolution, const Bounds& box) const
84 {
85   stream << box.fitXForXFig(_coords[0],resolution) << " " << box.fitYForXFig(_coords[1],resolution) << " ";
86 }
87
88 double Node::distanceWithSq(const Node& other) const
89 {
90   return (_coords[0]-other._coords[0])*(_coords[0]-other._coords[0])+(_coords[1]-other._coords[1])*(_coords[1]-other._coords[1]);
91 }
92
93 /*!
94  * WARNING different from 'computeAngle' method ! The returned value are not in the same interval !
95  * Here in -Pi/2; Pi/2. Typically this method returns the same value by exchanging pt1 and pt2.
96  * Use in process of detection of a point in or not in polygon.
97  */
98 double Node::computeSlope(const double *pt1, const double *pt2)
99 {
100   double x=pt2[0]-pt1[0];
101   double y=pt2[1]-pt1[1];
102   double norm=sqrt(x*x+y*y);
103   double ret=EdgeArcCircle::SafeAcos(fabs(x)/norm);
104   if( (x>=0. && y>=0.) || (x<0. && y<0.) )
105     return ret;
106   else
107     return M_PI-ret;
108 }
109
110 /*!
111  * WARNING different from 'computeSlope' method. Here angle in -Pi;Pi is returned.
112  * This method is anti-symetric.
113  */
114 double Node::computeAngle(const double *pt1, const double *pt2)
115 {
116   double x=pt2[0]-pt1[0];
117   double y=pt2[1]-pt1[1];
118   double norm=sqrt(x*x+y*y);
119   return EdgeArcCircle::GetAbsoluteAngleOfNormalizedVect(x/norm,y/norm);
120 }
121
122 /*!
123  * apply a Similarity transformation on this.
124  * @param xBary is the opposite of the X translation to do.
125  * @param yBary is the opposite of the Y translation to do.
126  * @param dimChar is the reduction factor.
127  */
128 void Node::applySimilarity(double xBary, double yBary, double dimChar)
129 {
130   _coords[0]=(_coords[0]-xBary)/dimChar;
131   _coords[1]=(_coords[1]-yBary)/dimChar;
132 }
133
134 /*!
135  * apply the reverse Similarity transformation on this.
136  * This method is the opposite of Node::applySimilarity method to retrieve the initial state.
137  * @param xBary is the opposite of the X translation to do.
138  * @param yBary is the opposite of the Y translation to do.
139  * @param dimChar is the reduction factor.
140  */
141 void Node::unApplySimilarity(double xBary, double yBary, double dimChar)
142 {
143   _coords[0]=_coords[0]*dimChar+xBary;
144   _coords[1]=_coords[1]*dimChar+yBary;
145 }
146
147 /*!
148  * Called by QuadraticPolygon::splitAbs method.
149  */
150 void Node::fillGlobalInfoAbs(const std::map<INTERP_KERNEL::Node *,int>& mapThis, const std::map<INTERP_KERNEL::Node *,int>& mapOther, int offset1, int offset2, double fact, double baryX, double baryY,
151                              std::vector<double>& addCoo, std::map<INTERP_KERNEL::Node *,int>& mapAddCoo, int *nodeId) const
152 {
153   std::map<INTERP_KERNEL::Node *,int>::const_iterator it=mapThis.find(const_cast<Node *>(this));
154   if(it!=mapThis.end())
155     {
156       *nodeId=(*it).second;
157       return;
158     }
159   it=mapOther.find(const_cast<Node *>(this));
160   if(it!=mapOther.end())
161     {
162       *nodeId=(*it).second+offset1;
163       return;
164     }
165   it=mapAddCoo.find(const_cast<Node *>(this));
166   if(it!=mapAddCoo.end())
167     {
168       *nodeId=(*it).second;
169       return;
170     }
171   int id=(int)addCoo.size()/2;
172   addCoo.push_back(fact*_coords[0]+baryX);
173   addCoo.push_back(fact*_coords[1]+baryY);
174   *nodeId=offset2+id;
175   mapAddCoo[const_cast<Node *>(this)]=offset2+id;
176 }
177
178 /*!
179  * Called by QuadraticPolygon::splitAbs method.
180  */
181 void Node::fillGlobalInfoAbs2(const std::map<INTERP_KERNEL::Node *,int>& mapThis, const std::map<INTERP_KERNEL::Node *,int>& mapOther, int offset1, int offset2, double fact, double baryX, double baryY,
182                               std::vector<double>& addCoo, std::map<INTERP_KERNEL::Node *,int>& mapAddCoo, std::vector<int>& pointsOther) const
183 {
184   int tmp;
185   std::size_t sz1=addCoo.size();
186   fillGlobalInfoAbs(mapThis,mapOther,offset1,offset2,fact,baryX,baryY,addCoo,mapAddCoo,&tmp);
187   if(sz1!=addCoo.size())
188     {
189       pointsOther.push_back(tmp);
190       return ;
191     }
192   std::vector<int>::const_iterator it=std::find(pointsOther.begin(),pointsOther.end(),tmp);
193   if(it!=pointsOther.end())
194     return ;
195   if(tmp<offset1)
196     pointsOther.push_back(tmp);
197 }