#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_GENERATORS_DISC2GENERATOR_H #define NUCLEX_GEOMETRY_AREAS_GENERATORS_DISC2GENERATOR_H #include "Nuclex/Geometry/Config.h" #include "Nuclex/Geometry/Areas/Disc2.h" #include "Nuclex/Geometry/Areas/Rectangle2.h" namespace Nuclex { namespace Geometry { namespace Areas { namespace Generators { // ------------------------------------------------------------------------------------------- // /// Point and area generation methods for 2D discs template class Disc2Generator { /// Returns a random point within the disc /// Disc in which a random point will be generated /// Random number generator that will be used /// A random point inside the disc public: template static Point2 GetRandomPointInside( const Disc2 &disc, TRandomNumberEngine &random ) { TScalar randomAngle = Math::Random(random, Math::Perigon()); TScalar radius = Math::SquareRoot( Math::Random(random, 1) ) * disc.Radius; return new Point2( radius * Math::Cosine(randomAngle) + disc.Center.X, radius * Math::Sine(randomAngle) + disc.Center.Y ); } /// Returns a random point on the outline of the disc /// Disc on whose outline a random point will be generated /// Random number generator that will be used /// A random point on the disc's outline public: template static Point2 GetRandomPointOnOutline( const Disc2 &disc, TRandomNumberEngine &random ) { TScalar randomAngle = Math::Random(random, Math::Perigon()); return new Point2( disc.Radius * Math::Cosine(randomAngle) + disc.Center.X, disc.Radius * Math::Sine(randomAngle) + disc.Center.Y ); } /// Determines the closest point to another point inside the disc /// Disc in which the closest point will be found /// Point to which the closest point will be determined /// The closest point to the specified point inside the disc public: static Point2 GetClosestPointInside( const Disc2 &disc, const Point2 &point ) { TScalar offsetX = point.X - disc.Center.X; TScalar offsetY = point.Y - disc.Center.Y; TScalar squaredDistance = (offsetX * offsetX) + (offsetY * offsetY); if(squaredDistance <= (disc.Radius * disc.Radius)) { return point; } else { float distanceFactor = disc.Radius / Math::SquareRoot(squaredDistance); return Point2( disc.Center.X + (offsetX * distanceFactor), disc.Center.Y + (offsetY * distanceFactor) ); } } /// Determines the closest point to another point on the disc's outline /// Disc on whose outline the closest point will be found /// Point to which the closest point will be determined /// The closest point to the specified point on the disc's outline public: static Point2 GetClosestPointOnOutline( const Disc2 &disc, const Point2 &point ) { TScalar offsetX = point.X - disc.Center.X; TScalar offsetY = point.Y - disc.Center.Y; TScalar squaredDistance = (offsetX * offsetX) + (offsetY * offsetY); if(squaredDistance == 0) { return Point2(disc.Center.X + disc.Radius, disc.Center.Y); } else { float distanceFactor = disc.Radius / Math::SquareRoot(squaredDistance); return Point2( disc.Center.X + (offsetX * distanceFactor), disc.Center.Y + (offsetY * distanceFactor) ); } } /// Calculates the bounding rectangle of a disc /// Disc of which the bounding rectangle will be calculated /// The disc's bounding rectangle public: static Rectangle2 GetBoundingRectangle(const Disc2 &disc) { return Rectangle2::FromMinAndMax( disc.Center.X - disc.Radius, disc.Center.Y - disc.Radius, disc.Center.X + disc.Radius, disc.Center.Y + disc.Radius ); } /// Calculates the bounding disc of a disc /// Disc of which the bounding disc will be calculated /// The disc's bounding disc /// /// This is a no-op, but provided for completeness so templated algorithms /// can assume this member to be there in any generator type. /// public: static Disc2 GetBoundingDisc(const Disc2 &disc) { return disc; } }; // ------------------------------------------------------------------------------------------- // }}}} // namespace Nuclex::Geometry::Areas::Generators #endif // NUCLEX_GEOMETRY_AREAS_GENERATORS_DISC2GENERATOR_H