Implement ray-cylinder intersection
This commit is contained in:
parent
e0312b66b1
commit
12b6b3169c
1 changed files with 33 additions and 0 deletions
|
|
@ -6,6 +6,7 @@
|
||||||
#include <psemek/geom/ray.hpp>
|
#include <psemek/geom/ray.hpp>
|
||||||
#include <psemek/geom/box.hpp>
|
#include <psemek/geom/box.hpp>
|
||||||
#include <psemek/geom/sphere.hpp>
|
#include <psemek/geom/sphere.hpp>
|
||||||
|
#include <psemek/geom/cylinder.hpp>
|
||||||
#include <psemek/geom/orientation.hpp>
|
#include <psemek/geom/orientation.hpp>
|
||||||
#include <psemek/geom/contains.hpp>
|
#include <psemek/geom/contains.hpp>
|
||||||
#include <psemek/geom/gauss.hpp>
|
#include <psemek/geom/gauss.hpp>
|
||||||
|
|
@ -222,10 +223,42 @@ namespace psemek::geom
|
||||||
return {ir->first, ir->second};
|
return {ir->first, ir->second};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T, std::size_t N>
|
||||||
|
interval<T> intersection(ray<T, N> const & r, cylinder<T, N> const & c)
|
||||||
|
{
|
||||||
|
auto Z2 = length_sqr(c.axis);
|
||||||
|
auto CZ = dot(c.center - r.origin, c.axis);
|
||||||
|
auto DZ = dot(r.direction, c.axis);
|
||||||
|
if (DZ == 0)
|
||||||
|
return {};
|
||||||
|
|
||||||
|
auto prmin = (-Z2 + CZ) / DZ;
|
||||||
|
auto prmax = ( Z2 + CZ) / DZ;
|
||||||
|
if (DZ < 0)
|
||||||
|
std::swap(prmin, prmax);
|
||||||
|
|
||||||
|
auto n = normalized(c.axis);
|
||||||
|
auto q = r.origin - c.center;
|
||||||
|
auto ir = solve_quadratic(length_sqr(r.direction) - sqr(dot(r.direction, n)),
|
||||||
|
2 * dot(q, r.direction) - 2 * dot(q, n) * dot(r.direction, n),
|
||||||
|
length_sqr(q) - sqr(dot(q, n)) - sqr(c.radius));
|
||||||
|
|
||||||
|
if (!ir)
|
||||||
|
return {};
|
||||||
|
|
||||||
|
return {std::max(ir->first, prmin), std::min(ir->second, prmax)};
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T, std::size_t N>
|
template <typename T, std::size_t N>
|
||||||
bool intersect(ray<T, N> const & r, sphere<T, N> const & s)
|
bool intersect(ray<T, N> const & r, sphere<T, N> const & s)
|
||||||
{
|
{
|
||||||
return intersection(r, s).empty();
|
return intersection(r, s).empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T, std::size_t N>
|
||||||
|
bool intersect(ray<T, N> const & r, cylinder<T, N> const & c)
|
||||||
|
{
|
||||||
|
return intersection(r, c).empty();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue