| 1 | // Created on: 1995-03-08 |
| 2 | // Created by: Laurent BUCHARD |
| 3 | // Copyright (c) 1995-1999 Matra Datavision |
| 4 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
| 5 | // |
| 6 | // This file is part of Open CASCADE Technology software library. |
| 7 | // |
| 8 | // This library is free software; you can redistribute it and/or modify it under |
| 9 | // the terms of the GNU Lesser General Public License version 2.1 as published |
| 10 | // by the Free Software Foundation, with special exception defined in the file |
| 11 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT |
| 12 | // distribution for complete text of the license and disclaimer of any warranty. |
| 13 | // |
| 14 | // Alternatively, this file may be used under the terms of Open CASCADE |
| 15 | // commercial license or contractual agreement. |
| 16 | |
| 17 | //#define No_Standard_OutOfRange |
| 18 | |
| 19 | #include <CSLib_Class2d.hxx> |
| 20 | #include <gp_Pnt2d.hxx> |
| 21 | #include <Standard_ConstructionError.hxx> |
| 22 | |
| 23 | static inline |
| 24 | Standard_Real Transform2d(const Standard_Real u, |
| 25 | const Standard_Real umin, |
| 26 | const Standard_Real umaxmumin); |
| 27 | |
| 28 | //======================================================================= |
| 29 | //function : Init |
| 30 | //purpose : |
| 31 | //======================================================================= |
| 32 | template <class TCol_Containers2d> |
| 33 | void CSLib_Class2d::Init(const TCol_Containers2d& TP2d, |
| 34 | const Standard_Real aTolu, |
| 35 | const Standard_Real aTolv, |
| 36 | const Standard_Real umin, |
| 37 | const Standard_Real vmin, |
| 38 | const Standard_Real umax, |
| 39 | const Standard_Real vmax) |
| 40 | { |
| 41 | Umin = umin; |
| 42 | Vmin = vmin; |
| 43 | Umax = umax; |
| 44 | Vmax = vmax; |
| 45 | // |
| 46 | if ((umax <= umin) || (vmax <= vmin) || (TP2d.Length() < 3)) |
| 47 | { |
| 48 | MyPnts2dX.Nullify(); |
| 49 | MyPnts2dY.Nullify(); |
| 50 | N = 0; |
| 51 | } |
| 52 | // |
| 53 | else |
| 54 | { |
| 55 | Standard_Integer i, iLower; |
| 56 | Standard_Real du, dv, aPrc; |
| 57 | // |
| 58 | aPrc = 1.e-10; |
| 59 | N = TP2d.Length(); |
| 60 | Tolu = aTolu; |
| 61 | Tolv = aTolv; |
| 62 | MyPnts2dX = new TColStd_Array1OfReal(0, N); |
| 63 | MyPnts2dY = new TColStd_Array1OfReal(0, N); |
| 64 | du = umax - umin; |
| 65 | dv = vmax - vmin; |
| 66 | // |
| 67 | iLower = TP2d.Lower(); |
| 68 | for (i = 0; i<N; ++i) |
| 69 | { |
| 70 | const gp_Pnt2d& aP2D = TP2d(i + iLower); |
| 71 | MyPnts2dX->ChangeValue(i) = Transform2d(aP2D.X(), umin, du); |
| 72 | MyPnts2dY->ChangeValue(i) = Transform2d(aP2D.Y(), vmin, dv); |
| 73 | } |
| 74 | MyPnts2dX->ChangeLast() = MyPnts2dX->First(); |
| 75 | MyPnts2dY->ChangeLast() = MyPnts2dY->First(); |
| 76 | // |
| 77 | if (du>aPrc) |
| 78 | { |
| 79 | Tolu /= du; |
| 80 | } |
| 81 | if (dv>aPrc) |
| 82 | { |
| 83 | Tolv /= dv; |
| 84 | } |
| 85 | } |
| 86 | } |
| 87 | |
| 88 | //======================================================================= |
| 89 | //function : CSLib_Class2d |
| 90 | //purpose : |
| 91 | //======================================================================= |
| 92 | CSLib_Class2d::CSLib_Class2d(const TColgp_Array1OfPnt2d& thePnts2d, |
| 93 | const Standard_Real theTolU, |
| 94 | const Standard_Real theTolV, |
| 95 | const Standard_Real theUMin, |
| 96 | const Standard_Real theVMin, |
| 97 | const Standard_Real theUMax, |
| 98 | const Standard_Real theVMax) |
| 99 | { |
| 100 | Init(thePnts2d, theTolU, theTolV, theUMin, |
| 101 | theVMin, theUMax, theVMax); |
| 102 | } |
| 103 | |
| 104 | //======================================================================= |
| 105 | //function : CSLib_Class2d |
| 106 | //purpose : |
| 107 | //======================================================================= |
| 108 | CSLib_Class2d::CSLib_Class2d(const TColgp_SequenceOfPnt2d& thePnts2d, |
| 109 | const Standard_Real theTolU, |
| 110 | const Standard_Real theTolV, |
| 111 | const Standard_Real theUMin, |
| 112 | const Standard_Real theVMin, |
| 113 | const Standard_Real theUMax, |
| 114 | const Standard_Real theVMax) |
| 115 | { |
| 116 | Init(thePnts2d, theTolU, theTolV, theUMin, |
| 117 | theVMin, theUMax, theVMax); |
| 118 | } |
| 119 | |
| 120 | //======================================================================= |
| 121 | //function : SiDans |
| 122 | //purpose : |
| 123 | //======================================================================= |
| 124 | Standard_Integer CSLib_Class2d::SiDans(const gp_Pnt2d& P) const |
| 125 | { |
| 126 | if(!N) { |
| 127 | return 0; |
| 128 | } |
| 129 | // |
| 130 | Standard_Real x,y, aTolu, aTolv; |
| 131 | // |
| 132 | x = P.X(); y = P.Y(); |
| 133 | aTolu=Tolu*(Umax-Umin); |
| 134 | aTolv=Tolv*(Vmax-Vmin); |
| 135 | // |
| 136 | if(Umin<Umax && Vmin<Vmax) { |
| 137 | if( ( x<(Umin-aTolu) ) || |
| 138 | ( x>(Umax+aTolu) ) || |
| 139 | ( y<(Vmin-aTolv) ) || |
| 140 | ( y>(Vmax+aTolv) ) ) { |
| 141 | return -1; |
| 142 | } |
| 143 | x=Transform2d(x,Umin,Umax-Umin); |
| 144 | y=Transform2d(y,Vmin,Vmax-Vmin); |
| 145 | } |
| 146 | |
| 147 | |
| 148 | Standard_Integer res = InternalSiDansOuOn(x,y); |
| 149 | if(res==-1) { |
| 150 | return 0; |
| 151 | } |
| 152 | if(Tolu || Tolv) { |
| 153 | if(res != InternalSiDans(x-Tolu,y-Tolv)) return 0; |
| 154 | if(res != InternalSiDans(x+Tolu,y-Tolv)) return 0; |
| 155 | if(res != InternalSiDans(x-Tolu,y+Tolv)) return 0; |
| 156 | if(res != InternalSiDans(x+Tolu,y+Tolv)) return 0; |
| 157 | } |
| 158 | // |
| 159 | return((res)? 1: -1); |
| 160 | } |
| 161 | //======================================================================= |
| 162 | //function : SiDans_OnMode |
| 163 | //purpose : |
| 164 | //======================================================================= |
| 165 | Standard_Integer CSLib_Class2d::SiDans_OnMode(const gp_Pnt2d& P, |
| 166 | const Standard_Real Tol) const |
| 167 | { |
| 168 | if(!N){ |
| 169 | return 0; |
| 170 | } |
| 171 | // |
| 172 | Standard_Real x,y, aTolu, aTolv; |
| 173 | // |
| 174 | x = P.X(); y = P.Y(); |
| 175 | aTolu=Tol; |
| 176 | aTolv=Tol; |
| 177 | |
| 178 | //-- ****** TO DO LATER, ESTIMATE AT EACH POINT Tol2d depending on Tol3d ***** |
| 179 | if(Umin<Umax && Vmin<Vmax) { |
| 180 | if(x<(Umin-aTolu) || (x>Umax+aTolu) || |
| 181 | (y<Vmin-aTolv) || (y>Vmax+aTolv)) { |
| 182 | return -1; |
| 183 | } |
| 184 | x=Transform2d(x,Umin,Umax-Umin); |
| 185 | y=Transform2d(y,Vmin,Vmax-Vmin); |
| 186 | } |
| 187 | // |
| 188 | Standard_Integer res = InternalSiDansOuOn(x,y); |
| 189 | if(aTolu || aTolv) { |
| 190 | if(res != InternalSiDans(x-aTolu,y-aTolv)) return 0; |
| 191 | if(res != InternalSiDans(x+aTolu,y-aTolv)) return 0; |
| 192 | if(res != InternalSiDans(x-aTolu,y+aTolv)) return 0; |
| 193 | if(res != InternalSiDans(x+aTolu,y+aTolv)) return 0; |
| 194 | } |
| 195 | return((res)? 1: -1); |
| 196 | } |
| 197 | //======================================================================= |
| 198 | //function : InternalSiDans |
| 199 | //purpose : |
| 200 | //======================================================================= |
| 201 | Standard_Integer CSLib_Class2d::InternalSiDans(const Standard_Real Px, |
| 202 | const Standard_Real Py) const |
| 203 | { |
| 204 | Standard_Integer nbc, i, ip1, SH, NH; |
| 205 | Standard_Real x, y, nx, ny; |
| 206 | // |
| 207 | nbc = 0; |
| 208 | i = 0; |
| 209 | ip1 = 1; |
| 210 | x = (MyPnts2dX->Value(i)-Px); |
| 211 | y = (MyPnts2dY->Value(i)-Py); |
| 212 | SH = (y<0.)? -1 : 1; |
| 213 | // |
| 214 | for(i=0; i<N ; i++,ip1++) { |
| 215 | nx = MyPnts2dX->Value(ip1) - Px; |
| 216 | ny = MyPnts2dY->Value(ip1) - Py; |
| 217 | |
| 218 | NH = (ny<0.)? -1 : 1; |
| 219 | if(NH!=SH) { |
| 220 | if(x>0. && nx>0.) { |
| 221 | nbc++; |
| 222 | } |
| 223 | else { |
| 224 | if(x>0.0 || nx>0.) { |
| 225 | if((x-y*(nx-x)/(ny-y))>0.) { |
| 226 | nbc++; |
| 227 | } |
| 228 | } |
| 229 | } |
| 230 | SH = NH; |
| 231 | } |
| 232 | x = nx; y = ny; |
| 233 | } |
| 234 | return(nbc&1); |
| 235 | } |
| 236 | //modified by NIZNHY-PKV Fri Jan 15 09:03:48 2010f |
| 237 | //======================================================================= |
| 238 | //function : InternalSiDansOuOn |
| 239 | //purpose : same code as above + test on ON (return(-1) in this case |
| 240 | //======================================================================= |
| 241 | Standard_Integer CSLib_Class2d::InternalSiDansOuOn(const Standard_Real Px, |
| 242 | const Standard_Real Py) const |
| 243 | { |
| 244 | Standard_Integer nbc, i, ip1, SH, NH, iRet; |
| 245 | Standard_Real x, y, nx, ny, aX; |
| 246 | Standard_Real aYmin; |
| 247 | // |
| 248 | nbc = 0; |
| 249 | i = 0; |
| 250 | ip1 = 1; |
| 251 | x = (MyPnts2dX->Value(i)-Px); |
| 252 | y = (MyPnts2dY->Value(i)-Py); |
| 253 | aYmin=y; |
| 254 | SH = (y<0.)? -1 : 1; |
| 255 | for(i=0; i<N ; i++, ip1++) { |
| 256 | |
| 257 | nx = MyPnts2dX->Value(ip1) - Px; |
| 258 | ny = MyPnts2dY->Value(ip1) - Py; |
| 259 | //-- le 14 oct 97 |
| 260 | if(nx<Tolu && nx>-Tolu && ny<Tolv && ny>-Tolv) { |
| 261 | iRet=-1; |
| 262 | return iRet; |
| 263 | } |
| 264 | //find Y coordinate of polyline for current X gka |
| 265 | //in order to detect possible status ON |
| 266 | Standard_Real aDx = (MyPnts2dX->Value(ip1) - MyPnts2dX->Value(ip1-1)); |
| 267 | if( (MyPnts2dX->Value(ip1-1) - Px) * nx < 0.) |
| 268 | { |
| 269 | |
| 270 | Standard_Real aCurPY = MyPnts2dY->Value(ip1) - (MyPnts2dY->Value(ip1) - MyPnts2dY->Value(ip1-1))/aDx *nx; |
| 271 | Standard_Real aDeltaY = aCurPY - Py; |
| 272 | if(aDeltaY >= -Tolv && aDeltaY <= Tolv) |
| 273 | { |
| 274 | iRet=-1; |
| 275 | return iRet; |
| 276 | } |
| 277 | } |
| 278 | // |
| 279 | |
| 280 | NH = (ny<0.)? -1 : 1; |
| 281 | if(NH!=SH) { |
| 282 | if(x>0. && nx>0.) { |
| 283 | nbc++; |
| 284 | } |
| 285 | else { |
| 286 | if(x>0. || nx>0.) { |
| 287 | aX=x-y*(nx-x)/(ny-y); |
| 288 | if(aX>0.){ |
| 289 | nbc++; |
| 290 | } |
| 291 | } |
| 292 | } |
| 293 | SH = NH; |
| 294 | } |
| 295 | else {// y has same sign as ny |
| 296 | if (ny<aYmin) { |
| 297 | aYmin=ny; |
| 298 | } |
| 299 | } |
| 300 | x = nx; y = ny; |
| 301 | }// for(i=0; i<N ; i++,ip1++) { |
| 302 | |
| 303 | iRet=nbc&1; |
| 304 | return iRet; |
| 305 | } |
| 306 | //modified by NIZNHY-PKV Fri Jan 15 09:03:55 2010t |
| 307 | //======================================================================= |
| 308 | //function : Transform2d |
| 309 | //purpose : |
| 310 | //======================================================================= |
| 311 | Standard_Real Transform2d(const Standard_Real u, |
| 312 | const Standard_Real umin, |
| 313 | const Standard_Real umaxmumin) |
| 314 | { |
| 315 | if(umaxmumin>1e-10) { |
| 316 | Standard_Real U = (u-umin)/umaxmumin; |
| 317 | return U; |
| 318 | } |
| 319 | else { |
| 320 | return u; |
| 321 | } |
| 322 | } |