#pragma region CPL License /* Nuclex Native Framework Copyright (C) 2002-2015 Nuclex Development Labs This library is free software; you can redistribute it and/or modify it under the terms of the IBM Common Public License as published by the IBM Corporation; either version 1.0 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the IBM Common Public License for more details. You should have received a copy of the IBM Common Public License along with this library */ #pragma endregion // CPL License #ifndef NUCLEX_GEOMETRY_VOLUMES_BOX3_H #define NUCLEX_GEOMETRY_VOLUMES_BOX3_H #include "Nuclex/Geometry/Config.h" #include "Nuclex/Geometry/Point3.h" #include "Nuclex/Geometry/Vector3.h" namespace Nuclex { namespace Geometry { namespace Volumes { // ------------------------------------------------------------------------------------------- // /// 3D box defined through minimum and a maximum corner coordinates template struct Box3 { /// Builds a box from given minimum and maximum cordinates /// X coordinate of the box's left side /// Y coordinate of the box's top side /// Z coordinate of the box's back side /// X coordinate of the box's right side /// Y coordinate of the box's bottom side /// Z coordinate of the box's front side /// A new box using the specified coordinates public: static Box3 FromMinAndMax( TScalar left, TScalar top, TScalar back, TScalar right, TScalar bottom, TScalar front ) { return Box3( Point3(left, top, back), Point3(right, bottom, front) ); } /// Builds a box from a given location and size /// X coordinate of the box's left side /// Y coordinate of the box's top side /// Z coordinate of the box's back side /// Width of the box on the X axis /// Height of the box on the Y axis /// Length of the box on the Z axis /// A new box using the specified coordinates public: static Box3 FromPointAndSize( TScalar left, TScalar top, TScalar back, TScalar width, TScalar height, TScalar length ) { return Box3( Point3(left, top, back), Vector3(width, height, length) ); } #if WANT_CONFUSING_CONSTRUCTOR /// Initializes a box using the specified position and size /// Position of the box's upper left corner /// Size of the box public: Box3(const Point3 &position, const Vector3 &size) : Min(position), Max(position + size) {} #endif /// Constructs an uninitialized box public: Box3() {} /// Initializes a box using the specified corner coordinates /// Position of the box's upper left corner /// Position of the box's lower right corner public: Box3(const Point3 &min, const Point3 &max) : Min(min), Max(max) {} /// Returns the width of the box /// The box' width public: TScalar GetWidth() const { return this->Max.X - this->Min.X; } /// Returns the length of the box /// The box' length public: TScalar GetLength() const { return this->Max.Y - this->Min.Y; } /// Returns the height of the box /// The box' height public: TScalar GetHeight() const { return this->Max.Z - this->Min.Z; } /// Calculates the center of the box /// The center of the box public: Point3 GetCenter() const { return Point3( (this->Min.X + this->Max.X) / 2, (this->Min.Y + this->Max.Y) / 2, (this->Min.Z + this->Max.Z) / 2 ); } /// Ensures that the box is not flipped on any axis public: void Unflip() { if(this->Min.X > this->Max.X) { std::swap(this->Min.X, this->Max.X); } if(this->Min.Y > this->Max.Y) { std::swap(this->Min.Y, this->Max.Y); } if(this->Min.Z > this->Max.Z) { std::swap(this->Min.Z, this->Max.Z); } } /// Offsets the entire box by the specified amount /// Amount the box will be offset on the X axis /// Amount the box will be offset on the Y axis /// Amount the box will be offset on the Z axis public: void ShiftBy(TScalar offsetX, TScalar offsetY, TScalar offsetZ) { this->Min.X += offsetX; this->Min.Y += offsetY; this->Min.Z += offsetZ; this->Max.X += offsetX; this->Max.Y += offsetY; this->Max.Z += offsetZ; } /// Offsets the entire box by the specified amount /// Amount the box will be offset public: void ShiftBy(const Vector3 &offset) { this->Min += offset; this->Max += offset; } /// Triggers an assertion if the box is flipped on any axis public: void EnforceNotFlipped() const { using namespace std; assert((this->Min.X <= this->Max.X) && "Box must not be flipped on the X axis"); assert((this->Min.Y <= this->Max.Y) && "Box must not be flipped on the Y axis"); assert((this->Min.Z <= this->Max.Z) && "Box must not be flipped on the Z axis"); } /// Coordinates of the box's near lower left corner public: Point3 Min; /// Coordinates of the box's far upper right corner public: Point3 Max; }; // ------------------------------------------------------------------------------------------- // }}} // namespace Nuclex::Geometry::Volumes #endif // NUCLEX_GEOMETRY_VOLUMES_BOX3_H