1 // File: LineConn2d_Box.cpp
2 // Created: 03.08.05 20:20:53
3 // Author: Alexander GRIGORIEV
4 // Copyright: Open Cascade 2005
7 #include <LineConn2dAfx.h>
9 #include <LineConn2d_Box.h>
10 #include <LineConn2d_SegmentIterator.h>
11 #include <LineConn2d_Object.h>
12 #include <LineConn2d.h>
14 inline Standard_Boolean compareDist (const gp_XY& aHSize, const gp_XY& aDist)
16 return (LineConn2d_FABS(aDist.X()) > aHSize.X() ||
17 LineConn2d_FABS(aDist.Y()) > aHSize.Y());
20 //=======================================================================
23 //=======================================================================
25 void LineConn2d_Box::Enlarge (const Standard_Real aDiff)
27 const Standard_Real aD = LineConn2d_FABS(aDiff);
28 myHSize = myHSize + gp_XY (aD, aD);
31 //=======================================================================
33 //purpose : limit the current box with the internals of theBox
34 //=======================================================================
36 void LineConn2d_Box::Limit (const LineConn2d_Box& theBox)
38 const gp_XY diffC = theBox.Center() - myCenter;
39 // check the condition IsOut
40 if (::compareDist (myHSize + theBox.HSize(), diffC) == Standard_False) {
41 const gp_XY diffH = theBox.HSize() - myHSize;
42 if (diffC.X() - diffH.X() > 0.) {
43 const Standard_Real aShift = 0.5 * (diffC.X() - diffH.X()); // positive
44 myCenter.SetX (myCenter.X() + aShift);
45 myHSize .SetX (myHSize.X() - aShift);
46 } else if (diffC.X() + diffH.X() < 0.) {
47 const Standard_Real aShift = 0.5 * (diffC.X() + diffH.X()); // negative
48 myCenter.SetX (myCenter.X() + aShift);
49 myHSize .SetX (myHSize.X() + aShift);
51 if (diffC.Y() - diffH.Y() > 0.) {
52 const Standard_Real aShift = 0.5 * (diffC.Y() - diffH.Y()); // positive
53 myCenter.SetY (myCenter.Y() + aShift);
54 myHSize .SetY (myHSize.Y() - aShift);
55 } else if (diffC.Y() + diffH.Y() < 0.) {
56 const Standard_Real aShift = 0.5 * (diffC.Y() + diffH.Y()); // negative
57 myCenter.SetY (myCenter.Y() + aShift);
58 myHSize .SetY (myHSize.Y() + aShift);
63 //=======================================================================
65 //purpose : Update the box by a point
66 //=======================================================================
68 void LineConn2d_Box::Add (const gp_XY& thePnt) {
69 if (myHSize.X() < -1e-5) {
71 myHSize.SetCoord (0., 0.);
73 const gp_XY aDiff = thePnt - myCenter;
74 if (aDiff.X() > myHSize.X()) {
75 const Standard_Real aShift = (aDiff.X() - myHSize.X()) * 0.5;
76 myCenter.SetX (myCenter.X() + aShift);
77 myHSize.SetX (myHSize.X() + aShift);
78 } else if (aDiff.X() < -myHSize.X()) {
79 const Standard_Real aShift = (aDiff.X() + myHSize.X()) * 0.5;
80 myCenter.SetX (myCenter.X() + aShift);
81 myHSize.SetX (myHSize.X() - aShift);
83 if (aDiff.Y() > myHSize.Y()) {
84 const Standard_Real aShift = (aDiff.Y() - myHSize.Y()) * 0.5;
85 myCenter.SetY (myCenter.Y() + aShift);
86 myHSize.SetY (myHSize.Y() + aShift);
87 } else if (aDiff.Y() < -myHSize.Y()) {
88 const Standard_Real aShift = (aDiff.Y() + myHSize.Y()) * 0.5;
89 myCenter.SetY (myCenter.Y() + aShift);
90 myHSize.SetY (myHSize.Y() - aShift);
95 //=======================================================================
97 //purpose : Intersection Box - Point
98 //=======================================================================
100 Standard_Boolean LineConn2d_Box::IsOut (const gp_XY& thePnt) const
102 return ::compareDist (myHSize, thePnt - myCenter);
105 //=======================================================================
107 //purpose : Intersection Box - Box
108 //=======================================================================
110 Standard_Boolean LineConn2d_Box::IsOut (const LineConn2d_Box& theBox) const
112 return ::compareDist (myHSize + theBox.HSize(), theBox.Center() - myCenter);
115 //=======================================================================
117 //purpose : Intersection Box - Object
118 //=======================================================================
120 Standard_Boolean LineConn2d_Box::IsOut (const LineConn2d_Object& theObj) const
122 Standard_Boolean aResult (Standard_True);
123 LineConn2d_SegmentIterator anIter (theObj);
124 for (; anIter.More(); anIter.Next())
125 if (IsOut (anIter.Value()) == Standard_False) {
126 aResult = Standard_False;
132 //=======================================================================
134 //purpose : Intersection Box - Segment
135 //=======================================================================
137 Standard_Boolean LineConn2d_Box::IsOut (const LineConn2d_Segment& theSeg) const
139 Standard_Boolean aResult (Standard_True);
140 // Intersect the line containing the segment.
141 const Standard_Real aProd[3] = {
142 theSeg.Delta() ^ (myCenter - theSeg.Origin()),
143 theSeg.Delta().X() * myHSize.Y(),
144 theSeg.Delta().Y() * myHSize.X()
146 if (LineConn2d_FABS(aProd[0]) < (LineConn2d_FABS(aProd[1]) +
147 LineConn2d_FABS(aProd[2])))
149 // Intersection with line detected; check the segment as bounding box
150 const gp_XY aHSeg (0.5 * theSeg.Delta().X(),
151 0.5 * theSeg.Delta().Y());
152 const gp_XY aHSegAbs (LineConn2d_FABS(aHSeg.X()),
153 LineConn2d_FABS(aHSeg.Y()));
154 aResult = ::compareDist (myHSize + aHSegAbs,
155 theSeg.Origin() + aHSeg - myCenter);
160 //=======================================================================
161 //function : Intersect
163 //=======================================================================
165 Standard_Integer LineConn2d_Box::Intersect
166 (Standard_Real outInter[2],
167 const LineConn2d_Segment& theSeg) const
169 Standard_Integer nInter (0);
170 Standard_Real anAlpha[2];
171 // Four sides of the box rectangle
172 const gp_XY aSegDelta[4] = {
173 gp_XY (-2 * myHSize.X(), 0.),
174 gp_XY (0., -2 * myHSize.Y()),
175 gp_XY (2 * myHSize.X(), 0.),
176 gp_XY (0., 2 * myHSize.Y())
178 LineConn2d_Segment aSeg (gp_XY(0., 0.), myCenter + myHSize);
180 // Intersect aSeg with all four sides of the box
181 for (Standard_Integer i = 0; i < 4; i++) {
182 aSeg.SetOrigin (aSeg.Extremity());
183 aSeg.SetDelta (aSegDelta[i]);
184 if (theSeg.IsIntersect (aSeg, anAlpha)) {
185 outInter[nInter] = anAlpha[0];
187 // Check to exclude coincident intersection points
188 if (LineConn2d::IsSmall (outInter[0] - outInter[1]))
191 if (outInter[0] > outInter[1]) {
192 const Standard_Real aTmp = outInter[0];
193 outInter[0] = outInter[1];