X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fgeometry%2Fhalfspace.h;h=9fdcdadfbd02b0dec41ef88c3e97539013cf2cbd;hb=44bd1d1ab256d397be4e2169c4ca5efdd0569d31;hp=5fdea34c885eaf2dbf17296b07d4677984589fef;hpb=7353dc087872cdb93bd57cbaf2b6f0dcc21f9a03;p=libs%2Fmath.git diff --git a/source/geometry/halfspace.h b/source/geometry/halfspace.h index 5fdea34..9fdcdad 100644 --- a/source/geometry/halfspace.h +++ b/source/geometry/halfspace.h @@ -7,8 +7,8 @@ namespace Msp { namespace Geometry { /** -An infinite shape consisting of the space on one side of a plane. Mostly -useful when composited with other shapes. +An unbounded shape consisting of the space on one side of a plane. Mostly +useful when intersected with other shapes. */ template class HalfSpace: public Shape @@ -24,16 +24,17 @@ public: const LinAl::Vector &get_normal() const { return normal; } - virtual BoundingBox get_axis_aligned_bounding_box() const; + virtual BoundingBox get_axis_aligned_bounding_box(unsigned = 0) const; virtual bool contains(const LinAl::Vector &) const; virtual unsigned get_max_ray_intersections() const { return 1; } virtual unsigned get_intersections(const Ray &, SurfacePoint *, unsigned) const; + virtual Coverage get_coverage(const BoundingBox &) const; }; template inline HalfSpace::HalfSpace() { - normal[0] = 1; + normal[0] = T(1); } template @@ -48,7 +49,7 @@ inline HalfSpace *HalfSpace::clone() const } template -inline BoundingBox HalfSpace::get_axis_aligned_bounding_box() const +inline BoundingBox HalfSpace::get_axis_aligned_bounding_box(unsigned) const { // XXX If the normal is aligned to an axis, should the bounding box reflect that? return ~BoundingBox(); @@ -57,13 +58,18 @@ inline BoundingBox HalfSpace::get_axis_aligned_bounding_box() const template inline bool HalfSpace::contains(const LinAl::Vector &point) const { - return inner_product(point, normal)<=0; + return inner_product(point, normal)<=T(0); } template inline unsigned HalfSpace::get_intersections(const Ray &ray, SurfacePoint *points, unsigned size) const { - T x = -inner_product(ray.get_start(), normal)/inner_product(ray.get_direction(), normal); + T d = inner_product(ray.get_start(), normal); + T c = inner_product(ray.get_direction(), normal); + if(c==T(0)) + return 0; + + T x = -d/c; if(ray.check_limits(x)) { if(points && size>0) @@ -71,6 +77,7 @@ inline unsigned HalfSpace::get_intersections(const Ray &ray, Surface points[0].position = ray.get_start()+ray.get_direction()*x; points[0].normal = normal; points[0].distance = x; + points[0].entry = (c::get_intersections(const Ray &ray, Surface return 0; } +template +inline Coverage HalfSpace::get_coverage(const BoundingBox &bbox) const +{ + LinAl::Vector low_point; + LinAl::Vector high_point; + for(unsigned i=0; i=T(0) ? bbox.get_minimum_coordinate(i) : bbox.get_maximum_coordinate(i)); + high_point[i] = (normal[i]>=T(0) ? bbox.get_maximum_coordinate(i) : bbox.get_minimum_coordinate(i)); + } + + if(contains(high_point)) + return FULL_COVERAGE; + else if(contains(low_point)) + return PARTIAL_COVERAGE; + else + return NO_COVERAGE; +} + } // namespace Geometry } // namespace Msp