#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_AREAS_CONVEXPOLYGON2_H #define NUCLEX_GEOMETRY_AREAS_CONVEXPOLYGON2_H #include "Nuclex/Geometry/Config.h" #include "Nuclex/Geometry/Math.h" #include "Nuclex/Geometry/Point2.h" #include "Nuclex/Geometry/Vector2.h" #include namespace Nuclex { namespace Geometry { namespace Areas { // ------------------------------------------------------------------------------------------- // #if WANT_WEIRD_SPECIALIZED_POLYGON_CLASS /// 2D polygon connecting a set of ordered vertices in a loop template struct ConvexPolygon2 { /// Initializes a polygon using the specified vertices /// Array containing the polygon's vertices /// Number of vertices in the array public: ConvexPolygon2(const Point2 *vertices, std::size_t count) : Vertices(vertices, count) {} /// Calculates the area of the polygon /// The area of the polygon /// /// Formula taken from http://stackoverflow.com/questions/451426 /// http://softsurfer.com/Archive/algorithm_0101/algorithm_0101.htm /// public: TScalar GetArea() const { std::size_t vertexCount = this->Vertices.size(); if(vertexCount < 3) { return 0; } // TODO: I'm pretty sure this is broken TScalar area = this->Vertices[0].X * ( this->Vertices[1].Y - this->Vertices[vertexCount - 1].Y ); area += this->Vertices[vertexCount - 1].X * ( this->Vertices[0].Y - this->Vertices[vertexCount - 2].Y ); for(std::size_t index = 0; index < vertexCount - 2; ++index) { area += this->Vertices[index + 1].X * ( this->Vertices[index + 2].Y - this->Vertices[index].Y ); } return area / 2; } /// Calculates the perimeter of the polygon /// The polygon's perimeter public: TScalar GetPerimeter() const { std::size_t vertexCount = this->Vertices.size(); if(vertexCount < 2) { return 0; } TScalar length = distance(this->Vertices[vertexCount - 1], this->Vertices[0]); for(std::size_t index = 0; index < vertexCount - 1; ++index) { length += distance(this->Vertices[index], this->Vertices[index + 1]); } return length; } /// Offsets the entire polygon by the specified amount /// Amount the polygon will be offset on the X axis /// Amount the polygon will be offset on the Y axis public: void ShiftBy(TScalar amountX, TScalar amountY) { for(std::size_t index = 0; index < this->count; ++index) { this->vertices[index].X += amountX; this->vertices[index].Y += amountY; } } /// Offsets the entire polygon by the specified amount /// Amount the polygon will be offset public: void ShiftBy(const Vector2 &amount) { for(std::size_t index = 0; index < this->count; ++index) { this->vertices[index] += amount; } } /// Calculates the distance between two points /// First point for the distance calculation /// Second point for the distance calculation /// The distance between the two points private: static TScalar distance( const Point2 &first, const Point2 &second ) { TScalar x = second.X - first.X; TScalar y = second.Y - first.Y; return Math::SquareRoot((x * x) + (y * y)); } /// The polygon's vertices public: std::vector< Point2 > Vertices; }; #endif // WANT_WEIRD_SPECIALIZED_POLYGON_CLASS // ------------------------------------------------------------------------------------------- // }}} // namespace Nuclex::Geometry::Areas #endif // NUCLEX_GEOMETRY_AREAS_CONVEXPOLYGON2_H