#ifndef PASTELGEOMETRY_SPHERE_AREA_HPP
#define PASTELGEOMETRY_SPHERE_AREA_HPP
#include "pastel/geometry/area/sphere_area.h"
#include "pastel/geometry/volume/sphere_volume.h"
#include <cmath>
namespace Pastel
{
template <typename Real>
Real lnAreaUnitSphere(integer n)
{
PENSURE_OP(n, >, 0);
// See areaUnitSphere() for the derivations.
// log(area(S))
// = log(n * volume(S))
// = log(n) + log(volume(S))
if (n == 1)
{
// log(0) = -infinity
return -Infinity();
}
return std::log((Real)n) + lnVolumeUnitSphere<Real>(n);
}
template <typename Real>
Real areaUnitSphere(integer n)
{
PENSURE_OP(n, >, 0);
if (n == 1)
{
// The surface area of the 1-dimensional
// disk is zero. This must be taken as
// a special case, since the general
// formula below does not return 0 for
// dimension 1.
return 0;
}
// The volume of an R-radius n-ball is of the form
//
// V_n(R) = C_n R^n
//
// The area of the n-ball is related to its volume by
//
// A_n(R) = (d/dR) V_n(R)
// = n C_n R^{n - 1},
//
// except when n = 1.
return n * volumeUnitSphere<Real>(n);
}
template <typename Real, integer N>
Real area(const Sphere<Real, N>& sphere)
{
return areaUnitSphere<Real>(sphere.n()) *
std::pow(sphere.radius(), (Real)(sphere.n() - 1));
}
}
#endif