#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