ellipse: add ray distance query

This commit is contained in:
Danny Robson 2018-04-16 15:57:35 +10:00
parent 63fb76c24c
commit ce246f8aa2
2 changed files with 52 additions and 3 deletions

View File

@ -14,10 +14,15 @@
* Copyright 2015-2017 Danny Robson <danny@nerdcruft.net>
*/
#include "./ellipse.hpp"
#include "ellipse.hpp"
#include "./ops.hpp"
#include "./aabb.hpp"
#include "ops.hpp"
#include "aabb.hpp"
#include "ray.hpp"
#include "sphere.hpp"
#include "point.hpp"
#include "../matrix.hpp"
using util::geom::ellipse;
@ -46,6 +51,29 @@ template bool util::geom::intersects (ellipse<2,float>, util::point<2,float>);
template bool util::geom::intersects (ellipse<3,float>, util::point<3,float>);
///////////////////////////////////////////////////////////////////////////////
// query a ray-ellipse distance by transforming spaces such that the ellipse is
// a sphere
template <>
float
util::geom::distance (ray<3,float> r, ellipse<3,float> e)
{
// find a transform that puts the ellipse at origin and scales it to a
// unit sphere.
auto const from_scaled = util::scale (e.radius) *
util::look_at (e.origin, {0,0,-1}, e.up);
auto const to_scaled = inverse (from_scaled);
// transform the ray into this new space and query against a unit sphere
auto const scaled_r = to_scaled * r;
auto const scaled_d = distance (scaled_r, sphere3f {0, 1.f});
auto const scaled_p = scaled_r.at (scaled_d);
// transform the result back into the original space
return distance (r.origin, (from_scaled * scaled_p.homog<4> ()).redim<3> ());
}
///////////////////////////////////////////////////////////////////////////////
template <size_t S, typename T>
static util::geom::aabb<S,T>

View File

@ -19,6 +19,8 @@
#include <cstdlib>
#include "fwd.hpp"
#include "../point.hpp"
#include "../vector.hpp"
@ -26,9 +28,28 @@ namespace util::geom {
///////////////////////////////////////////////////////////////////////////
template <size_t S, typename ValueT>
struct ellipse {
// the centre point of the ellipsoid
util::point<S,ValueT> origin;
// the distance from the centre along each axis to the shape's edge
util::vector<S,ValueT> radius;
// the orientation of up for the shape
util::vector<S,ValueT> up;
};
/// returns the distance along a ray to the surface of an ellipse.
///
/// returns infinity if there is no intersection
template <size_t DimensionV, typename ValueT>
ValueT
distance (
ray<DimensionV,ValueT>,
ellipse<DimensionV,ValueT>
);
using ellipse3f = ellipse<3,float>;
}