#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_POINT2_H
#define NUCLEX_GEOMETRY_POINT2_H
#include "Nuclex/Geometry/Config.h"
#include "Nuclex/Geometry/Vector2.h"
namespace Nuclex { namespace Geometry {
// ------------------------------------------------------------------------------------------- //
/// Point in 2D 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 Point2 {
/// A point located at the center of the coordinate system
public: static const Point2 Zero;
/// Constructs a new uninitialized point
public: Point2() {}
/// Initializes a new point with the given coordinates
/// X coordinate of the point
/// Y coordinate of the point
public: Point2(TScalar x, TScalar y) : X(x), Y(y) {}
/// 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 point
public: TScalar SquaredDistanceTo(const Point2 &other) const {
float offsetX = other.X - this->X;
float offsetY = other.Y - this->Y;
return (offsetX * offsetX) + (offsetY * offsetY);
}
/// 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
/// The squared distance from this point to the other point
public: TScalar SquaredDistanceTo(TScalar x, TScalar y) const {
float offsetX = x - this->X;
float offsetY = y - this->Y;
return (offsetX * offsetX) + (offsetY * offsetY);
}
/// Calculates the distance to another point
/// Other point to which the distance will be calculated
/// The distance from this point to the other point
public: TScalar DistanceTo(const Point2 &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
/// The distance from this point to the other point
public: TScalar DistanceTo(TScalar x, TScalar y) const {
return Math::SquareRoot(SquaredDistanceTo(x, y));
}
/// 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 Point2 &first, const Point2 &second) {
float offsetX = first.X - second.X;
float offsetY = first.Y - second.Y;
return (offsetX * offsetX) + (offsetY * offsetY);
}
/// 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 Point2 &first, const Point2 &second) {
return Math::SquareRoot(Point2::SquaredDistanceBetween(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: static Point2 Lerp(Point2 left, Point2 right, TScalar t) {
TScalar inverseT = 1 - t;
return Point2(
(left.X * inverseT) + (right.X * t),
(left.Y * inverseT) + (right.Y * t)
);
}
/// Moves the point by a specified offset
/// Offset by which the point will be moved
/// The point offset by the specified offset
public: Point2 operator +(const Vector2 &offset) const {
return Point2(this->X + offset.X, this->Y + offset.Y);
}
/// Moves the point against the specified offset
/// Offset against which the point will be move
/// The point moved against the specified offset
public: Point2 operator -(const Vector2 &offset) const {
return Point2(this->X - offset.X, this->Y - offset.Y);
}
/// Calculates the offset from this point to another
/// Other point to which the offset is calculated
/// The offset to the other point
public: Vector2 operator -(const Point2 &other) const {
return Vector2(this->X - other.X, this->Y - other.Y);
}
/// 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: Point2 operator +=(const Vector2 &vector) {
this->X += vector.X;
this->Y += vector.Y;
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: Point2 operator -=(const Vector2 &vector) {
this->X -= vector.X;
this->Y -= vector.Y;
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 Point2 &other) const {
return (this->X == other.X) && (this->Y == other.Y);
}
/// 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 Point2 &other) const {
return (this->X != other.X) || (this->Y != other.Y);
}
/// Location of the point on the X axis
public: TScalar X;
/// Location of the point on the Y axis
public: TScalar Y;
};
// ------------------------------------------------------------------------------------------- //
template
const Point2 Point2::Zero(0, 0);
// ------------------------------------------------------------------------------------------- //
}} // namespace Nuclex::Geometry
#endif // NUCLEX_GEOMETRY_POINT2_H