From: Mikko Rasa Date: Tue, 18 Apr 2017 06:37:35 +0000 (+0300) Subject: Add some comments to shape.h X-Git-Url: http://git.tdb.fi/?a=commitdiff_plain;h=99ad80a76d53d090ddf602c085d80b675609b8ba;p=libs%2Fmath.git Add some comments to shape.h --- diff --git a/source/geometry/shape.h b/source/geometry/shape.h index 074c11b..8eb3157 100644 --- a/source/geometry/shape.h +++ b/source/geometry/shape.h @@ -40,15 +40,27 @@ public: virtual Shape *clone() const = 0; + /** Returns the bounding box of the shape. The detail parameter controls + the tightness of the box. Higher detail will take more time to compute. */ virtual BoundingBox get_axis_aligned_bounding_box(unsigned detail = 0) const = 0; protected: BoundingBox bisect_axis_aligned_bounding_box(unsigned) const; + public: + /** Checks if a point is contained within the shape. */ virtual bool contains(const LinAl::Vector &) const = 0; + bool check_intersection(const Ray &) const; virtual unsigned get_max_ray_intersections() const = 0; + + /** Determines intersection points between the shape and a ray. */ virtual unsigned get_intersections(const Ray &, SurfacePoint *, unsigned) const = 0; + + /** Returns a vector with all of the intersections between the shape and a + ray. */ std::vector > get_intersections(const Ray &) const; + + /** Determines whether the shape covers a bounding box. */ virtual Coverage get_coverage(const BoundingBox &) const = 0; }; @@ -58,18 +70,23 @@ inline BoundingBox Shape::bisect_axis_aligned_bounding_box(unsigned if(!detail) throw std::invalid_argument("Shape::bisect_axis_aligned_bounding_box"); + // Form the root cell from the loosest approximation of a bounding box. std::list queue; queue.push_back(CoverageCell()); CoverageCell &root = queue.front(); root.level = 0; root.bounding_box = get_axis_aligned_bounding_box(); + // There's no point bisecting if the bounding box fills the entire space. if(root.bounding_box.is_space()) return root.bounding_box; root.coverage = get_coverage(root.bounding_box); + // If the bounding box is fully covered it's already tight. if(root.coverage==FULL_COVERAGE) return root.bounding_box; + /* Initialize bounds to the opposite edges because we don't yet know which + part of the bounding box the shape occupies. */ LinAl::Vector tight_min_pt = root.bounding_box.get_maximum_point(); LinAl::Vector tight_max_pt = root.bounding_box.get_minimum_point(); @@ -81,6 +98,7 @@ inline BoundingBox Shape::bisect_axis_aligned_bounding_box(unsigned const LinAl::Vector &max_pt = cell.bounding_box.get_maximum_point(); LinAl::Vector center = (min_pt+max_pt)/T(2); + // Bisect each dimension. for(unsigned i=0; i<(1< Shape::bisect_axis_aligned_bounding_box(unsigned child.coverage = get_coverage(child.bounding_box); if(child.coverage==FULL_COVERAGE || (child.level==detail && child.coverage!=NO_COVERAGE)) { + /* Adjust the bounds when we are certain that it's covered by at + least part of the shape. Also adjust for uncertain results if + we're on the last level. */ for(unsigned j=0; j