#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