1 // File: LineConn2d_Object.cpp
2 // Created: 03.08.05 21:28:05
3 // Author: Alexander GRIGORIEV
4 // Copyright: Open Cascade 2005
7 #include <LineConn2dAfx.h>
9 #include <LineConn2d_Object.h>
10 #include <LineConn2d.h>
11 #include <Precision.hxx>
13 //=======================================================================
16 //=======================================================================
18 void LineConn2d_Object::Update ()
20 // Create the bounding box of the polyline
23 PointIterator anIter (myPoints);
24 for (; anIter.More(); anIter.Next()) {
25 myBox.Add (anIter.Value());
31 //=======================================================================
34 //=======================================================================
36 Standard_Boolean LineConn2d_Object::IsOut (const gp_XY& thePoint,
37 const Standard_Real theTol) const
39 const Standard_Real aConfusion = Precision::Confusion();
40 const Standard_Real aUniConf = 1. + aConfusion;
41 const Standard_Real aSqConfusion = aConfusion * aConfusion;
42 Standard_Real anYprev (1e+100);
43 const gp_XY * aPnt[2] = { 0L, 0L };
45 Standard_Integer aNIntersect (0);
46 PointIterator anIter (myPoints);
48 aPnt[1] = &myPoints.Last();
49 for (; anIter.More(); anIter.Next()) {
51 aPnt[1] = &anIter.Value();
52 const gp_XY& aPntLow = * (aPnt[0]->X() < aPnt[1]->X() ? aPnt[0]: aPnt[1]);
53 const gp_XY& aPntUp = * (aPnt[0]->X() < aPnt[1]->X() ? aPnt[1]: aPnt[0]);
54 const gp_XY aVec (aPntUp - aPntLow);
56 // Check the distance (condition ON)
57 Standard_Real aDist (-1.);
58 const Standard_Real aSegLen = aVec.Modulus();
59 if (aSegLen < aConfusion)
61 aDist = (thePoint - (aPntLow + aPntUp) * 0.5).Modulus();
64 const gp_XY aVecN = aVec / aSegLen;
66 // Obtain the coordinate of the projection on the segment
67 const gp_XY aVecP = thePoint - aPntLow;
68 const Standard_Real aCoord = aVecN * aVecP;
70 // Check if it projects before the 1st point => distance to 1st point
71 if (aCoord < aConfusion)
72 aDist = aVecP.Modulus();
73 // Check if it projects before the 2nd point => distance to 2nd point
74 else if (aCoord > aSegLen - aConfusion)
75 aDist = (thePoint - aPntUp).Modulus();
76 // Otherwise retrieve the projection point inside the segment
78 aDist = LineConn2d_FABS (aVecN ^ aVecP);
81 // ON detected, we stop the analysis
82 return Standard_False;
85 if (thePoint.X() > aPntUp.X() + aConfusion || thePoint.X() < aPntLow.X())
88 // Treatment of a vertical contour segment
89 if (aVec.X() < gp::Resolution() &&
90 aVec.X() > -gp::Resolution())
92 if (LineConn2d::IsSmall (anYprev - aPntLow.Y()))
94 else if (LineConn2d::IsSmall (anYprev - aPntUp.Y()))
95 anYprev = aPntLow.Y();
99 // Evaluate the intersection
100 const Standard_Real anAlpha = (thePoint.X() - aPntLow.X()) / aVec.X();
101 if (anAlpha < aUniConf) {
102 const Standard_Real anYint = aPntLow.Y() + anAlpha * aVec.Y();
103 if (anYint > thePoint.Y()) {
104 const Standard_Real aD2 = anYint - anYprev;
105 if (aD2 * aD2 > aSqConfusion) {
113 return ((aNIntersect & 0x01) == 0);