Integration of OCCT 6.5.0 from SVN
[occt.git] / src / Bnd / Bnd_B2x.gxx
CommitLineData
7fd59977 1// File: Bnd_B2x.gxx
2// Created: 08.09.05 19:37:06
3// Author: Alexander GRIGORIEV
4// Copyright: Open Cascade 2005
5
6inline Standard_Boolean _compareDist (const RealType aHSize[2],
7 const RealType aDist[2])
8{
9 return (Abs(aDist[0]) > aHSize[0] || Abs(aDist[1]) > aHSize[1]);
10}
11
12inline Standard_Boolean _compareDistD (const gp_XY& aHSize, const gp_XY& aDist)
13{
14 return (Abs(aDist.X()) > aHSize.X() || Abs(aDist.Y()) > aHSize.Y());
15}
16
17//=======================================================================
18//function : Add
19//purpose : Update the box by a point
20//=======================================================================
21
22void Bnd_B2x::Add (const gp_XY& thePnt) {
23 if (IsVoid()) {
24 myCenter[0] = RealType(thePnt.X());
25 myCenter[1] = RealType(thePnt.Y());
26 myHSize [0] = 0.;
27 myHSize [1] = 0.;
28 } else {
29 const RealType aDiff[2] = {
30 RealType(thePnt.X()) - myCenter[0],
31 RealType(thePnt.Y()) - myCenter[1]
32 };
33 if (aDiff[0] > myHSize[0]) {
34 const RealType aShift = (aDiff[0] - myHSize[0]) / 2;
35 myCenter[0] += aShift;
36 myHSize [0] += aShift;
37 } else if (aDiff[0] < -myHSize[0]) {
38 const RealType aShift = (aDiff[0] + myHSize[0]) / 2;
39 myCenter[0] += aShift;
40 myHSize [0] -= aShift;
41 }
42 if (aDiff[1] > myHSize[1]) {
43 const RealType aShift = (aDiff[1] - myHSize[1]) / 2;
44 myCenter[1] += aShift;
45 myHSize [1] += aShift;
46 } else if (aDiff[1] < -myHSize[1]) {
47 const RealType aShift = (aDiff[1] + myHSize[1]) / 2;
48 myCenter[1] += aShift;
49 myHSize [1] -= aShift;
50 }
51 }
52}
53
54//=======================================================================
55//function : Limit
56//purpose : limit the current box with the internals of theBox
57//=======================================================================
58
59Standard_Boolean Bnd_B2x::Limit (const Bnd_B2x& theBox)
60{
61 Standard_Boolean aResult (Standard_False);
62 const RealType diffC[2] = {
63 theBox.myCenter[0] - myCenter[0],
64 theBox.myCenter[1] - myCenter[1]
65 };
66 const RealType sumH[2] = {
67 theBox.myHSize[0] + myHSize[0],
68 theBox.myHSize[1] + myHSize[1]
69 };
70 // check the condition IsOut
71 if (_compareDist (sumH, diffC) == Standard_False) {
72 const RealType diffH[2] = {
73 theBox.myHSize[0] - myHSize[0],
74 theBox.myHSize[1] - myHSize[1]
75 };
76 if (diffC[0] - diffH[0] > 0.) {
77 const RealType aShift = (diffC[0] - diffH[0]) / 2; // positive
78 myCenter[0] += aShift;
79 myHSize [0] -= aShift;
80 } else if (diffC[0] + diffH[0] < 0.) {
81 const RealType aShift = (diffC[0] + diffH[0]) / 2; // negative
82 myCenter[0] += aShift;
83 myHSize [0] += aShift;
84 }
85 if (diffC[1] - diffH[1] > 0.) {
86 const RealType aShift = (diffC[1] - diffH[1]) / 2; // positive
87 myCenter[1] += aShift;
88 myHSize [1] -= aShift;
89 } else if (diffC[1] + diffH[1] < 0.) {
90 const RealType aShift = (diffC[1] + diffH[1]) / 2; // negative
91 myCenter[1] += aShift;
92 myHSize [1] += aShift;
93 }
94 aResult = Standard_True;
95 }
96 return aResult;
97}
98
99//=======================================================================
100//function : Transformed
101//purpose :
102//=======================================================================
103
104Bnd_B2x Bnd_B2x::Transformed (const gp_Trsf2d& theTrsf) const
105{
106 Bnd_B2x aResult;
107 const gp_TrsfForm aForm = theTrsf.Form();
108 const Standard_Real aScale = theTrsf.ScaleFactor();
109 const Standard_Real aScaleAbs = Abs(aScale);
110 if (aForm == gp_Identity)
111 aResult = * this;
112 else if (aForm== gp_Translation || aForm== gp_PntMirror || aForm== gp_Scale)
113 {
114 aResult.myCenter[0] =
115 (RealType)(myCenter[0] * aScale + theTrsf.TranslationPart().X());
116 aResult.myCenter[1] =
117 (RealType)(myCenter[1] * aScale + theTrsf.TranslationPart().Y());
118 aResult.myHSize[0] = (RealType)(myHSize[0] * aScaleAbs);
119 aResult.myHSize[1] = (RealType)(myHSize[1] * aScaleAbs);
120 } else {
121 gp_XY aCenter ((Standard_Real)myCenter[0],
122 (Standard_Real)myCenter[1]);
123 theTrsf.Transforms (aCenter);
124 aResult.myCenter[0] = (RealType)aCenter.X();
125 aResult.myCenter[1] = (RealType)aCenter.Y();
126
127 const Standard_Real * aMat = &theTrsf.HVectorialPart().Value(1,1);
128 aResult.myHSize[0] = (RealType)(aScaleAbs * (Abs(aMat[0]) * myHSize[0]+
129 Abs(aMat[1]) * myHSize[1]));
130 aResult.myHSize[1] = (RealType)(aScaleAbs * (Abs(aMat[2]) * myHSize[0]+
131 Abs(aMat[3]) * myHSize[1]));
132 }
133 return aResult;
134}
135
136//=======================================================================
137//function : IsOut
138//purpose : Intersection Box - Circle
139//=======================================================================
140
141Standard_Boolean Bnd_B2x::IsOut (const gp_XY& theCenter,
142 const Standard_Real theRadius,
143 const Standard_Boolean isCircleHollow) const
144{
145 Standard_Boolean aResult (Standard_True);
146 if (isCircleHollow == Standard_False) {
147 // vector from the center of the circle to the nearest box face
148 const Standard_Real aDist[2] = {
149 Abs(theCenter.X()-Standard_Real(myCenter[0])) - Standard_Real(myHSize[0]),
150 Abs(theCenter.Y()-Standard_Real(myCenter[1])) - Standard_Real(myHSize[1])
151 };
152 Standard_Real aD (0.);
153 if (aDist[0] > 0.)
154 aD = aDist[0]*aDist[0];
155 if (aDist[1] > 0.)
156 aD += aDist[1]*aDist[1];
157 aResult = (aD > theRadius*theRadius);
158 } else {
159 const Standard_Real aDistC[2] = {
160 Abs(theCenter.X()-Standard_Real(myCenter[0])),
161 Abs(theCenter.Y()-Standard_Real(myCenter[1]))
162 };
163 // vector from the center of the circle to the nearest box face
164 Standard_Real aDist[2] = {
165 aDistC[0] - Standard_Real(myHSize[0]),
166 aDistC[1] - Standard_Real(myHSize[1])
167 };
168 Standard_Real aD (0.);
169 if (aDist[0] > 0.)
170 aD = aDist[0]*aDist[0];
171 if (aDist[1] > 0.)
172 aD += aDist[1]*aDist[1];
173 if (aD < theRadius*theRadius) {
174 // the box intersects the solid circle; check if it is completely
175 // inside the circle (in such case return isOut==True)
176 aDist[0] = aDistC[0] + Standard_Real(myHSize[0]);
177 aDist[1] = aDistC[1] + Standard_Real(myHSize[1]);
178 if (aDist[0]*aDist[0]+aDist[1]*aDist[1] > theRadius*theRadius)
179 aResult = Standard_False;
180 }
181 }
182 return aResult;
183}
184
185//=======================================================================
186//function : IsOut
187//purpose : Intersection Box - transformed Box
188//=======================================================================
189
190Standard_Boolean Bnd_B2x::IsOut (const Bnd_B2x& theBox,
191 const gp_Trsf2d& theTrsf) const
192{
193 Standard_Boolean aResult (Standard_False);
194 const gp_TrsfForm aForm = theTrsf.Form();
195 const Standard_Real aScale = theTrsf.ScaleFactor();
196 const Standard_Real aScaleAbs = Abs(aScale);
197 if (aForm == gp_Translation || aForm == gp_Identity ||
198 aForm == gp_PntMirror || aForm == gp_Scale)
199 {
200 aResult =
201 (Abs (RealType(theBox.myCenter[0]*aScale + theTrsf.TranslationPart().X())
202 - myCenter[0])
203 > RealType (theBox.myHSize[0]*aScaleAbs) + myHSize[0] ||
204 Abs (RealType(theBox.myCenter[1]*aScale + theTrsf.TranslationPart().Y())
205 - myCenter[1])
206 > RealType (theBox.myHSize[1]*aScaleAbs) + myHSize[1]);
207
208 }
209 else {
210 // theBox is transformed and we check the resulting (enlarged) box against
211 // 'this' box.
212 const Standard_Real * aMat = &theTrsf.HVectorialPart().Value(1,1);
213
214 gp_XY aCenter ((Standard_Real)theBox.myCenter[0],
215 (Standard_Real)theBox.myCenter[1]);
216 theTrsf.Transforms (aCenter);
217 const Standard_Real aDist[2] = {
218 aCenter.X() - (Standard_Real)myCenter[0],
219 aCenter.Y() - (Standard_Real)myCenter[1]
220 };
221 const Standard_Real aMatAbs[4] = {
222 Abs(aMat[0]), Abs(aMat[1]), Abs(aMat[2]), Abs(aMat[3])
223 };
224 if (Abs(aDist[0]) > (aScaleAbs * (aMatAbs[0]*theBox.myHSize[0]+
225 aMatAbs[1]*theBox.myHSize[1]) +
226 (Standard_Real)myHSize[0]) ||
227 Abs(aDist[1]) > (aScaleAbs * (aMatAbs[2]*theBox.myHSize[0]+
228 aMatAbs[3]*theBox.myHSize[1]) +
229 (Standard_Real)myHSize[1]))
230 aResult = Standard_True;
231
232 else {
233 // theBox is rotated, scaled and translated. We apply the reverse
234 // translation and scaling then check against the rotated box 'this'
235 if ((Abs(aMat[0]*aDist[0]+aMat[2]*aDist[1])
236 > theBox.myHSize[0]*aScaleAbs + (aMatAbs[0]*myHSize[0] +
237 aMatAbs[2]*myHSize[1])) ||
238 (Abs(aMat[1]*aDist[0]+aMat[3]*aDist[1])
239 > theBox.myHSize[1]*aScaleAbs + (aMatAbs[1]*myHSize[0] +
240 aMatAbs[3]*myHSize[1])))
241 aResult = Standard_True;
242 }
243 }
244 return aResult;
245}
246
247//=======================================================================
248//function : IsOut
249//purpose : Intersection Box - Line
250//=======================================================================
251
252Standard_Boolean Bnd_B2x::IsOut (const gp_Ax2d& theLine) const
253{
254 if (IsVoid())
255 return Standard_True;
256 // Intersect the line containing the segment.
257 const Standard_Real aProd[3] = {
258 theLine.Direction().XY() ^ (gp_XY (myCenter[0] - theLine.Location().X(),
259 myCenter[1] - theLine.Location().Y())),
260 theLine.Direction().X() * Standard_Real(myHSize[1]),
261 theLine.Direction().Y() * Standard_Real(myHSize[0])
262 };
263 return (Abs(aProd[0]) > (Abs(aProd[1]) + Abs(aProd[2])));
264}
265
266//=======================================================================
267//function : IsOut
268//purpose : Intersection Box - Segment
269//=======================================================================
270
271Standard_Boolean Bnd_B2x::IsOut (const gp_XY& theP0, const gp_XY& theP1) const
272{
273 Standard_Boolean aResult (Standard_True);
274 if (IsVoid() == Standard_False)
275 {
276 // Intersect the line containing the segment.
277 const gp_XY aSegDelta (theP1 - theP0);
278 const Standard_Real aProd[3] = {
279 aSegDelta ^ (gp_XY (myCenter[0], myCenter[1]) - theP0),
280 aSegDelta.X() * Standard_Real(myHSize[1]),
281 aSegDelta.Y() * Standard_Real(myHSize[0])
282 };
283 if (Abs(aProd[0]) < (Abs(aProd[1]) + Abs(aProd[2])))
284 {
285 // Intersection with line detected; check the segment as bounding box
286 const gp_XY aHSeg (0.5 * aSegDelta.X(), 0.5 * aSegDelta.Y());
287 const gp_XY aHSegAbs (Abs(aHSeg.X()), Abs(aHSeg.Y()));
288 aResult = _compareDistD (gp_XY((Standard_Real)myHSize[0],
289 (Standard_Real)myHSize[1]) + aHSegAbs,
290 theP0 + aHSeg-gp_XY((Standard_Real)myCenter[0],
291 (Standard_Real)myCenter[1]));
292 }
293 }
294 return aResult;
295}
296
297//=======================================================================
298//function : IsIn
299//purpose : Test the complete inclusion of this box in transformed theOtherBox
300//=======================================================================
301
302Standard_Boolean Bnd_B2x::IsIn (const Bnd_B2x& theBox,
303 const gp_Trsf2d& theTrsf) const
304{
305 Standard_Boolean aResult (Standard_False);
306 const gp_TrsfForm aForm = theTrsf.Form();
307 const Standard_Real aScale = theTrsf.ScaleFactor();
308 const Standard_Real aScaleAbs = Abs(aScale);
309 if (aForm == gp_Translation || aForm == gp_Identity ||
310 aForm == gp_PntMirror || aForm == gp_Scale)
311 {
312 aResult =
313 (Abs (RealType(theBox.myCenter[0]*aScale + theTrsf.TranslationPart().X())
314 - myCenter[0])
315 < RealType (theBox.myHSize[0]*aScaleAbs) - myHSize[0] &&
316 Abs (RealType(theBox.myCenter[1]*aScale + theTrsf.TranslationPart().Y())
317 - myCenter[1])
318 < RealType (theBox.myHSize[1]*aScaleAbs) - myHSize[1]);
319
320 } else {
321 // theBox is rotated, scaled and translated. We apply the reverse
322 // translation and scaling then check against the rotated box 'this'
323 const Standard_Real * aMat = &theTrsf.HVectorialPart().Value(1,1);
324 gp_XY aCenter ((Standard_Real)theBox.myCenter[0],
325 (Standard_Real)theBox.myCenter[1]);
326 theTrsf.Transforms (aCenter);
327 const Standard_Real aDist[2] = {
328 aCenter.X() - (Standard_Real)myCenter[0],
329 aCenter.Y() - (Standard_Real)myCenter[1]
330 };
331 if ((Abs(aMat[0]*aDist[0]+aMat[2]*aDist[1])
332 < theBox.myHSize[0]*aScaleAbs - (Abs(aMat[0])*myHSize[0] +
333 Abs(aMat[2])*myHSize[1])) &&
334 (Abs(aMat[1]*aDist[0]+aMat[3]*aDist[1])
335 < theBox.myHSize[1]*aScaleAbs - (Abs(aMat[1])*myHSize[0] +
336 Abs(aMat[3])*myHSize[1])))
337 aResult = Standard_True;
338 }
339 return aResult;
340}