00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "bounding-box.hh"
00025 using namespace std;
00026
00027
00028 static TCoordinate BB_EPS = 0;
00029
00030 CBoundingBox::CBoundingBox()
00031 : FMin(CVertex(0, 0, 0)), FMax(CVertex(0, 0, 0)), FIsEmpty(true)
00032 {
00033 }
00034
00035 CBoundingBox::CBoundingBox(const CVertex & APoint)
00036 : FMin(APoint), FMax(APoint), FIsEmpty(false)
00037 {
00038 }
00039
00040 CBoundingBox::CBoundingBox(const CVertex & APoint1, const CVertex & APoint2)
00041 : FIsEmpty(false)
00042 {
00043 if (APoint1.getX() < APoint2.getX()) {
00044 FMin.setX(APoint1.getX());
00045 FMax.setX(APoint2.getX());
00046 }
00047 else {
00048 FMin.setX(APoint2.getX());
00049 FMax.setX(APoint1.getX());
00050 }
00051
00052 if (APoint1.getY() < APoint2.getY()) {
00053 FMin.setY(APoint1.getY());
00054 FMax.setY(APoint2.getY());
00055 }
00056 else {
00057 FMin.setY(APoint2.getY());
00058 FMax.setY(APoint1.getY());
00059 }
00060
00061 if (APoint1.getZ() < APoint2.getZ()) {
00062 FMin.setZ(APoint1.getZ());
00063 FMax.setZ(APoint2.getZ());
00064 }
00065 else {
00066 FMin.setZ(APoint2.getZ());
00067 FMax.setZ(APoint1.getZ());
00068 }
00069 }
00070
00071 TCoordinate CBoundingBox::getEpsilon()
00072 {
00073 return BB_EPS;
00074 }
00075
00076 void CBoundingBox::setEpsilon(TCoordinate AEpsilon)
00077 {
00078 BB_EPS = AEpsilon;
00079 }
00080
00081 void CBoundingBox::addPoint(const CVertex & APoint)
00082 {
00083 if (FIsEmpty)
00084 FMin = FMax = APoint;
00085 else {
00086 if (APoint.getX() < FMin.getX())
00087 FMin.setX(APoint.getX());
00088 if (APoint.getY() < FMin.getY())
00089 FMin.setY(APoint.getY());
00090 if (APoint.getZ() < FMin.getZ())
00091 FMin.setZ(APoint.getZ());
00092 if (APoint.getX() > FMax.getX())
00093 FMax.setX(APoint.getX());
00094 if (APoint.getY() > FMax.getY())
00095 FMax.setY(APoint.getY());
00096 if (APoint.getZ() > FMax.getZ())
00097 FMax.setZ(APoint.getZ());
00098 }
00099 FIsEmpty = false;
00100 }
00101
00102 void CBoundingBox::clear()
00103 {
00104 FMin = FMax = CVertex(0, 0, 0);
00105 FIsEmpty = true;
00106 }
00107
00108 bool CBoundingBox::isEmpty() const
00109 {
00110 return FIsEmpty;
00111 }
00112
00113 bool CBoundingBox::isInBox(const CVertex & APoint) const
00114 {
00115 if (FIsEmpty)
00116 return false;
00117 else
00118 return (APoint.getX() >= FMin.getX() - BB_EPS &&
00119 APoint.getX() <= FMax.getX() + BB_EPS &&
00120 APoint.getY() >= FMin.getY() - BB_EPS &&
00121 APoint.getY() <= FMax.getY() + BB_EPS &&
00122 APoint.getZ() >= FMin.getZ() - BB_EPS &&
00123 APoint.getZ() <= FMax.getZ() + BB_EPS);
00124 }
00125
00126 bool CBoundingBox::isInIntersectionWith(const CBoundingBox & ABB) const
00127 {
00128 if (FIsEmpty || ABB.FIsEmpty)
00129 return false;
00130 else
00131 return (FMin.getX() - BB_EPS <= ABB.FMax.getX() + BB_EPS &&
00132 FMin.getY() - BB_EPS <= ABB.FMax.getY() + BB_EPS &&
00133 FMin.getZ() - BB_EPS <= ABB.FMax.getZ() + BB_EPS &&
00134 FMax.getX() + BB_EPS >= ABB.FMin.getX() - BB_EPS &&
00135 FMax.getY() + BB_EPS >= ABB.FMin.getY() - BB_EPS &&
00136 FMax.getZ() + BB_EPS >= ABB.FMin.getZ() - BB_EPS);
00137 }
00138
00139 TCoordinate CBoundingBox::getVolume() const
00140 {
00141 CVertex vol = FMax - FMin;
00142
00143 return vol.getX() * vol.getY() * vol.getZ();
00144 }
00145
00146 TCoordinate CBoundingBox::getSurface() const
00147 {
00148 CVertex vol = FMax - FMin;
00149 TCoordinate surf;
00150
00151 surf = vol.getX() * vol.getY();
00152 surf += vol.getX() * vol.getZ();
00153 surf += vol.getY() * vol.getZ();
00154
00155 return surf * 2.0;
00156 }
00157
00158 const CVertex & CBoundingBox::getMinBound() const
00159 {
00160 return FMin;
00161 }
00162
00163 const CVertex & CBoundingBox::getMaxBound() const
00164 {
00165 return FMax;
00166 }
00167
00168 CVertex CBoundingBox::getEpsMinBound() const
00169 {
00170 return FMin - CVertex(BB_EPS, BB_EPS, BB_EPS);
00171 }
00172
00173 CVertex CBoundingBox::getEpsMaxBound() const
00174 {
00175 return FMax + CVertex(BB_EPS, BB_EPS, BB_EPS);
00176 }
00177
00178 CVertex CBoundingBox::getCenter() const
00179 {
00180 return (FMin + FMax) / 2.0;
00181 }
00182
00183 bool CBoundingBox::operator * (const CBoundingBox & AOther) const
00184 {
00185 return isInIntersectionWith(AOther);
00186 }
00187
00188 CBoundingBox CBoundingBox::operator + (const CBoundingBox & AOther) const
00189 {
00190 CBoundingBox box = *this;
00191 box.addPoint(AOther.getMinBound());
00192 box.addPoint(AOther.getMaxBound());
00193 return box;
00194 }
00195
00196 ostream & operator << (ostream & AStream, const CBoundingBox & ABB)
00197 {
00198 if (ABB.isEmpty())
00199 AStream << "[empty]";
00200 else
00201 AStream << "[" << ABB.getMinBound() << "|" << ABB.getMaxBound() << "]";
00202
00203 return AStream;
00204 }
00205