OCC22322 Improvement of Extrema performance
[occt.git] / src / Bnd / Bnd_Sphere.cxx
1 #include <Bnd_Sphere.hxx>
2
3 Bnd_Sphere::Bnd_Sphere()
4   : myCenter (0., 0., 0.),
5     myRadius (0.),
6     myIsValid (Standard_False),
7     myU (0),
8     myV (0)
9 {}
10
11 Bnd_Sphere::Bnd_Sphere( const gp_XYZ& theCenter, const Standard_Real theRadius,
12                         const Standard_Integer theU, const Standard_Integer theV )
13   : myCenter (theCenter),
14     myRadius (theRadius),
15     myIsValid (Standard_False),
16     myU (theU),
17     myV (theV)
18 {}
19
20 void Bnd_Sphere::SquareDistances( const gp_XYZ& theXYZ,
21                                   Standard_Real& theMin, Standard_Real& theMax ) const
22 {
23   theMax = ( theXYZ - myCenter ).SquareModulus();
24   theMin = ( theMax - myRadius <0 ? 0.0 : theMax - myRadius * myRadius );
25   theMax += myRadius * myRadius;
26 }
27
28 void Bnd_Sphere::Distances( const gp_XYZ& theXYZ,
29                             Standard_Real& theMin, Standard_Real& theMax ) const
30 {
31   theMax = ( theXYZ - myCenter ).Modulus();
32   theMin = ( theMax - myRadius <0 ? 0.0 : theMax - myRadius );
33   theMax += myRadius;
34 }
35
36 Standard_Boolean Bnd_Sphere::Project(const gp_XYZ& theNode, gp_XYZ& theProjNode, Standard_Real& theDist, Standard_Boolean& theInside) const
37
38   theProjNode = myCenter;
39   theDist = ( theNode - theProjNode ).Modulus();
40   theInside = Standard_True;
41   return Standard_True;
42 }
43
44 Standard_Real Bnd_Sphere::Distance(const gp_XYZ& theNode) const
45 {
46   return ( theNode - myCenter ).Modulus();
47 }
48
49 Standard_Real Bnd_Sphere::SquareDistance(const gp_XYZ& theNode) const
50 {
51   return ( theNode - myCenter ).SquareModulus();
52 }
53
54 void Bnd_Sphere::Add( const Bnd_Sphere& theOther)
55 {
56   if ( myRadius < 0.0 )
57   {
58     // not initialised yet
59     *this = theOther;
60     return;
61   }
62
63   const Standard_Real aDist = (myCenter - theOther.myCenter).Modulus();
64   if ( myRadius + aDist <= theOther.myRadius )
65   {
66     // the other sphere is larger and encloses this
67     *this = theOther;
68     return;
69   }
70
71   if ( theOther.myRadius + aDist <= myRadius )
72     return; // this sphere encloses other
73
74   // expansion
75   const Standard_Real dfR = ( aDist + myRadius + theOther.myRadius ) * 0.5;
76   const Standard_Real aParamOnDiam = ( dfR - myRadius ) / aDist;
77   myCenter = myCenter * ( 1.0 - aParamOnDiam ) + theOther.myCenter * aParamOnDiam;
78   myRadius = dfR;
79   myIsValid = Standard_False;
80 }
81
82 Standard_Boolean Bnd_Sphere::IsOut( const Bnd_Sphere& theOther ) const
83
84   return (myCenter - theOther.myCenter).SquareModulus() > (myRadius + theOther.myRadius) * (myRadius + theOther.myRadius); 
85 }
86
87 Standard_Boolean Bnd_Sphere::IsOut( const gp_XYZ& theXYZ,
88                                     Standard_Real& theMaxDist) const
89 {
90   Standard_Real aCurMinDist, aCurMaxDist;
91   Distances( theXYZ, aCurMinDist, aCurMaxDist );
92   if ( aCurMinDist > theMaxDist )
93     return Standard_True;
94   if( myIsValid && aCurMaxDist < theMaxDist )
95     theMaxDist = aCurMaxDist;
96   return Standard_False;
97 }
98
99 Standard_Real Bnd_Sphere::SquareExtent() const
100
101   return 4 * myRadius * myRadius; 
102 }