1 // Copyright (C) 2007-2019 CEA/DEN, EDF R&D
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, or (at your option) any later version.
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.
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
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 // Author : Anthony Geay (CEA/DEN)
21 #include "InterpKernelGeo2DNode.hxx"
22 #include "InterpKernelGeo2DEdgeArcCircle.hxx"
24 using namespace INTERP_KERNEL;
26 Node::Node(double x, double y):_cnt(1),_loc(UNKNOWN)
28 _coords[0]=x; _coords[1]=y;
31 Node::Node(const double *coords):_cnt(1),_loc(UNKNOWN)
37 Node::Node(std::istream& stream):_cnt(1),_loc(UNKNOWN)
41 _coords[0]=((double) tmp)/1e4;
43 _coords[1]=((double) tmp)/1e4;
58 bool Node::isEqual(const Node& other) const
60 const unsigned SPACEDIM=2;
62 for(unsigned i=0;i<SPACEDIM;i++)
63 ret&=areDoubleEquals((*this)[i],other[i]);
67 double Node::getSlope(const Node& other) const
69 return computeSlope(*this, other);
73 * Convenient method. Equivalent to isEqual method. In case of true is returned, '&other' is
74 * added in 'track' container.
76 bool Node::isEqualAndKeepTrack(const Node& other, std::vector<Node *>& track) const
78 bool ret=isEqual(other);
80 track.push_back(const_cast<Node *>(&other));
84 void Node::dumpInXfigFile(std::ostream& stream, int resolution, const Bounds& box) const
86 stream << box.fitXForXFig(_coords[0],resolution) << " " << box.fitYForXFig(_coords[1],resolution) << " ";
89 double Node::distanceWithSq(const Node& other) const
91 return (_coords[0]-other._coords[0])*(_coords[0]-other._coords[0])+(_coords[1]-other._coords[1])*(_coords[1]-other._coords[1]);
95 * WARNING different from 'computeAngle' method ! The returned value are not in the same interval !
96 * Here in [0; Pi). Typically this method returns the same value by exchanging pt1 and pt2.
97 * Use in process of detection of a point in or not in polygon.
99 double Node::computeSlope(const double *pt1, const double *pt2)
101 double x=pt2[0]-pt1[0];
102 double y=pt2[1]-pt1[1];
103 double norm=sqrt(x*x+y*y);
104 double ret=EdgeArcCircle::SafeAcos(fabs(x)/norm);
105 if( (x>=0. && y>=0.) || (x<0. && y<0.) )
112 * WARNING different from 'computeSlope' method. Here angle in -Pi;Pi is returned.
113 * This method is anti-symetric.
115 double Node::computeAngle(const double *pt1, const double *pt2)
117 double x=pt2[0]-pt1[0];
118 double y=pt2[1]-pt1[1];
119 double norm=sqrt(x*x+y*y);
120 return EdgeArcCircle::GetAbsoluteAngleOfNormalizedVect(x/norm,y/norm);
124 * apply a Similarity transformation on this.
125 * @param xBary is the opposite of the X translation to do.
126 * @param yBary is the opposite of the Y translation to do.
127 * @param dimChar is the reduction factor.
129 void Node::applySimilarity(double xBary, double yBary, double dimChar)
131 _coords[0]=(_coords[0]-xBary)/dimChar;
132 _coords[1]=(_coords[1]-yBary)/dimChar;
136 * apply the reverse Similarity transformation on this.
137 * This method is the opposite of Node::applySimilarity method to retrieve the initial state.
138 * @param xBary is the opposite of the X translation to do.
139 * @param yBary is the opposite of the Y translation to do.
140 * @param dimChar is the reduction factor.
142 void Node::unApplySimilarity(double xBary, double yBary, double dimChar)
144 _coords[0]=_coords[0]*dimChar+xBary;
145 _coords[1]=_coords[1]*dimChar+yBary;
149 * Called by QuadraticPolygon::splitAbs method.
151 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,
152 std::vector<double>& addCoo, std::map<INTERP_KERNEL::Node *,int>& mapAddCoo, int *nodeId) const
154 std::map<INTERP_KERNEL::Node *,int>::const_iterator it=mapOther.find(const_cast<Node *>(this));
155 if(it!=mapOther.end()) // order matters, try in mapOther first.
157 *nodeId=(*it).second+offset1;
160 it=mapThis.find(const_cast<Node *>(this));
161 if(it!=mapThis.end())
163 *nodeId=(*it).second;
166 it=mapAddCoo.find(const_cast<Node *>(this));
167 if(it!=mapAddCoo.end())
169 *nodeId=(*it).second;
172 int id=(int)addCoo.size()/2;
173 addCoo.push_back(fact*_coords[0]+baryX);
174 addCoo.push_back(fact*_coords[1]+baryY);
176 mapAddCoo[const_cast<Node *>(this)]=offset2+id;
180 * Called by QuadraticPolygon::splitAbs method.
182 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,
183 std::vector<double>& addCoo, std::map<INTERP_KERNEL::Node *,int>& mapAddCoo, std::vector<int>& pointsOther) const
186 std::size_t sz1=addCoo.size();
187 fillGlobalInfoAbs(mapThis,mapOther,offset1,offset2,fact,baryX,baryY,addCoo,mapAddCoo,&tmp);
188 if(sz1!=addCoo.size() // newly created point
189 || (tmp >= offset2 // or previously created point merged with a neighbour
190 && (pointsOther.size() == 0 || pointsOther.back() != tmp)))
192 pointsOther.push_back(tmp);
195 std::vector<int>::const_iterator it=std::find(pointsOther.begin(),pointsOther.end(),tmp);
196 if(it!=pointsOther.end())
198 pointsOther.push_back(tmp);