#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_LINES_SEGMENT2_H #define NUCLEX_GEOMETRY_LINES_SEGMENT2_H #include "Nuclex/Geometry/Config.h" #include "Nuclex/Geometry/Point2.h" #include "Nuclex/Geometry/Vector2.h" #include "Nuclex/Geometry/Side2.h" #include #include namespace Nuclex { namespace Geometry { namespace Lines { // ------------------------------------------------------------------------------------------- // /// 2D line segment defined by a start and an end point template struct Segment2 { /// Initializes a line segment using the specified coordinates /// Position at which the line segment begins /// Position at which the line segment ends public: Segment2(const Point2 &start, const Point2 &end) : Start(start), End(end) {} /// Returns the squared length of the line segment /// The squared length of the line segment public: TScalar GetSquaredLength() const { TScalar distanceX = this->End.X - this->Start.X; TScalar distanceY = this->End.Y - this->Start.Y; return (distanceX * distanceX) + (distanceY * distanceY); } /// Returns the length of the line segment /// The length of the line segment public: TScalar GetLength() const { return Math::SquareRoot(GetSquaredLength()); } /// Offsets the entire line segment by the specified amount /// Amount the line segment will be offset on the X axis /// Amount the line segment will be offset on the Y axis public: void ShiftBy(TScalar offsetX, TScalar offsetY) { this->Start.X += offsetX; this->Start.Y += offsetY; this->End.X += offsetX; this->End.Y += offsetY; } /// Offsets the entire line segment by the specified amount /// Amount the line segment will be offset public: void ShiftBy(const Vector2 &offset) { this->Start += offset; this->End += offset; } /// Determines which side of the line segment a point is on /// Point that will be checked /// The side of the line the point is on /// /// There is no colinear / dead center case. Lines are infinitely thin and any check /// for hitting the center would be prone to the same problems as comparing a floating /// point variable to an exact value. Thus the point is either left or right or the /// line, removing silly special handling code and increasing robustness. /// public: Side2::Enum GetSide(const Point2 &point) { return GetSide(point.X, point.Y); } /// Determines which side of the line segment a point is on /// X coordinate of the point that will be checked /// Y coordinate of the point that will be checked /// The side of the line the point is on /// /// There is no colinear / dead center case. Lines are infinitely thin and any check /// for hitting the center would be prone to the same problems as comparing a floating /// point variable to an exact value. Thus the point is either left or right or the /// line, removing silly special handling code and increasing robustness. /// public: Side2::Enum GetSide(TScalar pointX, TScalar pointY) { TScalar determinant = (this->End.X - this->Start.X) * (pointY - this->Start.Y) - (pointX - this->Start.X) * (this->End.Y - this->Start.Y); if(determinant >= 0) { return Side2::LeftHandSide; } else { return Side2::RightHandSide; } } /// Coordinates at which the line segment begins public: Point2 Start; /// Coordinates at which the line segment ends public: Point2 End; }; // ------------------------------------------------------------------------------------------- // }}} // namespace Nuclex::Geometry::Lines #endif // NUCLEX_GEOMETRY_LINES_SEGMENT2_H