#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_POINT3_H #define NUCLEX_GEOMETRY_POINT3_H #include "Nuclex/Geometry/Config.h" #include "Nuclex/Geometry/Vector3.h" namespace Nuclex { namespace Geometry { // ------------------------------------------------------------------------------------------- // /// Point in 3D space using cartesian coordinates /// /// /// Most math libraries combine the concepts of a "point" and /// a "vector" because they both store a pair of scalars and have many /// equivalent operations. There is however a semantic meaning associated with a point: /// it is a location, not a size and not a direction. /// /// /// This library attempts to keep up this distinction to provide meaning without /// additional documentation and to guard against errors from mistaken identity. /// /// template struct Point3 { /// A point located at the center of the coordinate system public: static const Point3 Zero; /// Initializes a new point at the center of the coordinate frame public: Point3() {} /// Initializes a new point with the given coordinates /// X coordinate of the point /// Y coordinate of the point /// Z coordinate of the point public: Point3(TScalar x, TScalar y, TScalar z) : X(x), Y(y), Z(z) {} /// Calculates the squared distance to another point /// Other point to which the distance will be calculated /// The squared distance from this point to the other points public: TScalar SquaredDistanceTo(const Point3 &other) const { float offsetX = other.X - this->X; float offsetY = other.Y - this->Y; float offsetZ = other.Z - this->Z; return (offsetX * offsetX) + (offsetY * offsetY) + (offsetZ * offsetZ); } /// Calculates the squared distance to another point /// X coordinate to which the distance will be calculated /// Y coordinate to which the distance will be calculated /// Z coordinate to which the distance will be calculated /// The squared distance from this point to the other points public: TScalar SquaredDistanceTo(TScalar x, TScalar y, TScalar z) const { float offsetX = x - this->X; float offsetY = y - this->Y; float offsetZ = z - this->Z; return (offsetX * offsetX) + (offsetY * offsetY) + (offsetZ * offsetZ); } /// Calculates the distance to another point /// Other point to which the distance will be calculated /// The distance from this point to the other points public: TScalar DistanceTo(const Point3 &other) const { return Math::SquareRoot(SquaredDistanceTo(other)); } /// Calculates the distance to another point /// X coordinate to which the distance will be calculated /// Y coordinate to which the distance will be calculated /// Z coordinate to which the distance will be calculated /// The distance from this point to the other points public: TScalar DistanceTo(TScalar x, TScalar y, TScalar z) const { return Math::SquareRoot(SquaredDistanceTo(x, y, z)); } /// Calculates the squared distance between two points /// First point for the distance calculation /// Second point for the distance calculation /// The squared distance between the two points public: static TScalar SquaredDistanceBetween(const Point3 &first, const Point3 &second) { float offsetX = first.X - second.X; float offsetY = first.Y - second.Y; float offsetZ = first.Z - second.Z; return (offsetX * offsetX) + (offsetY * offsetY) + (offsetZ * offsetZ); } /// Calculates the distance between two points /// First point for the distance calculation /// Second point for the distance calculation /// The distance between the two points public: static TScalar DistanceBetween(const Point3 &first, const Point3 &second) { return Math::SquareRoot(Point3::DistanceBetween(first, second)); } /// Linearly interpolates between two points /// Point from which the interpolation begins /// Point to which the interpolation leds /// Interpolation point between the two points /// The interpolated point at public: Point3 Lerp(Point3 left, Point3 right, TScalar t) { TScalar inverseT = 1 - t; return Point3( (left.X * inverseT) + (right.X * t), (left.Y * inverseT) + (right.Y * t), (left.Z * inverseT) + (right.Z * t) ); } /// Moves the point by the specified offset /// Offset by which the point will be moved /// The point moved by the specified offset public: Point3 operator +(const Vector3 &offset) const { return Point3(this->X + offset.X, this->Y + offset.Y, this->Z + offset.Z); } /// Moves the point against the specified offset /// Offset against which the point will be moved /// The point moved against the specified offset public: Point3 operator -(const Vector3 &offset) const { return Point3(this->X - offset.X, this->Y - offset.Y, this->Z - offset.Z); } /// Calculates the offset from this point to another /// Other point to which the offset is calculated /// The offset to the other point public: Vector3 operator -(const Point3 &other) const { return Vector3(this->X - other.X, this->Y - other.Y, this->Z - other.Z); } /// Moves the point by a specified offset /// Offset by which the point will be moved /// The point after being moved by the specified offset public: Point3 operator +=(const Vector3 &vector) { this->X += vector.X; this->Y += vector.Y; this->Z += vector.Z; return *this; } /// Moves the point against the specified offset /// Offset against which the point will be move /// The point after being moved against the specified offset public: Point3 operator -=(const Vector3 &vector) { this->X -= vector.X; this->Y -= vector.Y; this->Z -= vector.Z; return *this; } /// Checks whether another point is equal to this one /// Other point that will be checked for equality /// True if the other point is equal to this one public: bool operator ==(const Point3 &other) const { return (this->X == other.X) && (this->Y == other.Y) && (this->Z == other.Z); } /// Checks whether another point is different from this one /// Other point that will be checked for inequality /// True if the other point is different to this one public: bool operator !=(const Point3 &other) const { return (this->X != other.X) || (this->Y != other.Y) || (this->Z != other.Z); } /// Location of the point on the X axis public: TScalar X; /// Location of the point on the Y axis public: TScalar Y; /// Location of the point on the Z axis public: TScalar Z; }; // ------------------------------------------------------------------------------------------- // template const Point3 Point3::Zero(0, 0, 0); // ------------------------------------------------------------------------------------------- // }} // namespace Nuclex::Geometry #endif // NUCLEX_GEOMETRY_POINT3_H