virtual bool contains(const LinAl::Vector<T, D> &) const;
virtual unsigned get_max_ray_intersections() const { return max_isect; }
virtual unsigned get_intersections(const Ray<T, D> &, SurfacePoint<T, D> *, unsigned) const;
+ virtual Coverage get_coverage(const BoundingBox<T, D> &) const;
};
template<typename T, unsigned D, typename O>
return n;
}
+template<typename T, unsigned D, typename O>
+inline Coverage CompositeShape<T, D, O>::get_coverage(const BoundingBox<T, D> &bbox) const
+{
+ Coverage coverage = NO_COVERAGE;
+ for(typename ShapeArray::const_iterator i=shapes.begin(); i!=shapes.end(); ++i)
+ {
+ Coverage c = (*i)->get_coverage(bbox);
+ if(i==shapes.begin() || Ops::shortcircuit(c>coverage))
+ coverage = c;
+
+ if(coverage!=PARTIAL_COVERAGE && Ops::shortcircuit(coverage==FULL_COVERAGE))
+ break;
+ }
+
+ return coverage;
+}
+
} // namespace Geometry
} // namespace Msp
virtual bool contains(const LinAl::Vector<T, D> &) const;
virtual unsigned get_max_ray_intersections() const;
virtual unsigned get_intersections(const Ray<T, D> &, SurfacePoint<T, D> *, unsigned) const;
+ virtual Coverage get_coverage(const BoundingBox<T, D> &) const;
};
template<typename T, unsigned D>
return n;
}
+template<typename T, unsigned D>
+inline Coverage ExtrudedShape<T, D>::get_coverage(const BoundingBox<T, D> &bbox) const
+{
+ T half_length = length/T(2);
+ if(bbox.get_maximum_coordinate(D-1)<-half_length || bbox.get_minimum_coordinate(D-1)>half_length)
+ return NO_COVERAGE;
+
+ BoundingBox<T, D-1> base_bbox(bbox.get_minimum_point().template slice<D-1>(0), bbox.get_maximum_point().template slice<D-1>(0));
+ Coverage coverage = base->get_coverage(base_bbox);
+ if(coverage==NO_COVERAGE)
+ return NO_COVERAGE;
+
+ if(bbox.get_minimum_coordinate(D-1)<-half_length || bbox.get_maximum_coordinate(D-1)>half_length)
+ return PARTIAL_COVERAGE;
+ else
+ return coverage;
+}
+
} // namespace Geometry
} // namespace Msp
virtual bool contains(const LinAl::Vector<T, D> &) const;
virtual unsigned get_max_ray_intersections() const { return 1; }
virtual unsigned get_intersections(const Ray<T, D> &, SurfacePoint<T, D> *, unsigned) const;
+ virtual Coverage get_coverage(const BoundingBox<T, D> &) const;
};
template<typename T, unsigned D>
return 0;
}
+template<typename T, unsigned D>
+inline Coverage HalfSpace<T, D>::get_coverage(const BoundingBox<T, D> &bbox) const
+{
+ LinAl::Vector<T, D> low_point;
+ LinAl::Vector<T, D> high_point;
+ for(unsigned i=0; i<D; ++i)
+ {
+ low_point[i] = (normal[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
virtual bool contains(const LinAl::Vector<T, D> &) const;
virtual unsigned get_max_ray_intersections() const { return 2; }
virtual unsigned get_intersections(const Ray<T, D> &, SurfacePoint<T, D> *, unsigned) const;
+ virtual Coverage get_coverage(const BoundingBox<T, D> &) const;
};
template<typename T, unsigned D>
return n;
}
+template<typename T, unsigned D>
+inline Coverage HyperBox<T, D>::get_coverage(const BoundingBox<T, D> &bbox) const
+{
+ const LinAl::Vector<T, D> &min_pt = bbox.get_minimum_point();
+ const LinAl::Vector<T, D> &max_pt = bbox.get_maximum_point();
+ LinAl::Vector<T, D> half_dim = dimensions/T(2);
+
+ Coverage coverage = FULL_COVERAGE;
+ for(unsigned i=0; i<D; ++i)
+ {
+ if(max_pt[i]<-half_dim[i] || min_pt[i]>half_dim[i])
+ return NO_COVERAGE;
+ if(min_pt[i]<-half_dim[i] || max_pt[i]>half_dim[i])
+ coverage = PARTIAL_COVERAGE;
+ }
+
+ return coverage;
+}
+
} // namespace Geometry
} // namespace Msp
virtual bool contains(const LinAl::Vector<T, D> &) const;
virtual unsigned get_max_ray_intersections() const { return 2; }
virtual unsigned get_intersections(const Ray<T, D> &, SurfacePoint<T, D> *, unsigned) const;
+ virtual Coverage get_coverage(const BoundingBox<T, D> &) const;
};
template<typename T, unsigned D>
return n;
}
+template<typename T, unsigned D>
+inline Coverage HyperSphere<T, D>::get_coverage(const BoundingBox<T, D> &bbox) const
+{
+ const LinAl::Vector<T, D> &min_pt = bbox.get_minimum_point();
+ const LinAl::Vector<T, D> &max_pt = bbox.get_maximum_point();
+
+ LinAl::Vector<T, D> far_point;
+ for(unsigned i=0; i<D; ++i)
+ far_point[i] = std::max(std::abs(min_pt[i]), std::abs(max_pt[i]));
+
+ if(contains(far_point))
+ return FULL_COVERAGE;
+
+ unsigned spanned_dimensions = 0;
+ for(unsigned i=0; i<D; ++i)
+ if(min_pt[i]<T(0) && max_pt[i]>T(0))
+ spanned_dimensions |= 1<<i;
+
+ for(unsigned i=0; i<(1<<D); ++i)
+ {
+ if(i&spanned_dimensions)
+ continue;
+
+ LinAl::Vector<T, D> point;
+ for(unsigned j=0; j<D; ++j)
+ if(!((spanned_dimensions>>j)&1))
+ point[j] = ((i>>j)&1 ? max_pt[j] : min_pt[j]);
+
+ if(contains(point))
+ return PARTIAL_COVERAGE;
+ }
+
+ return NO_COVERAGE;
+}
+
} // namespace Geometry
} // namespace Msp
virtual bool contains(const LinAl::Vector<T, D> &) const;
virtual unsigned get_max_ray_intersections() const { return shape->get_max_ray_intersections(); }
virtual unsigned get_intersections(const Ray<T, D> &, SurfacePoint<T, D> *, unsigned) const;
+ virtual Coverage get_coverage(const BoundingBox<T, D> &) const;
};
template<typename T, unsigned D>
return count;
}
+template<typename T, unsigned D>
+inline Coverage Negation<T, D>::get_coverage(const BoundingBox<T, D> &bbox) const
+{
+ Coverage coverage = shape->get_coverage(bbox);
+ if(coverage==FULL_COVERAGE)
+ return NO_COVERAGE;
+ else if(coverage==NO_COVERAGE)
+ return FULL_COVERAGE;
+ else
+ return PARTIAL_COVERAGE;
+}
+
} // namespace Geometry
} // namespace Msp
namespace Msp {
namespace Geometry {
+enum Coverage
+{
+ NO_COVERAGE,
+ PARTIAL_COVERAGE,
+ FULL_COVERAGE
+};
+
/**
Base class and interface for geometric shapes. Shapes may be bounded or
unbounded. They are always considered to be solid, i.e. have a distinct inside
virtual unsigned get_max_ray_intersections() const = 0;
virtual unsigned get_intersections(const Ray<T, D> &, SurfacePoint<T, D> *, unsigned) const = 0;
std::vector<SurfacePoint<T, D> > get_intersections(const Ray<T, D> &) const;
+ virtual Coverage get_coverage(const BoundingBox<T, D> &) const = 0;
};
template<typename T, unsigned D>
virtual bool contains(const LinAl::Vector<T, D> &) const;
virtual unsigned get_max_ray_intersections() const { return shape->get_max_ray_intersections(); }
virtual unsigned get_intersections(const Ray<T, D> &, SurfacePoint<T, D> *, unsigned) const;
+ virtual Coverage get_coverage(const BoundingBox<T, D> &) const;
};
template<typename T, unsigned D>
return count;
}
+template<typename T, unsigned D>
+inline Coverage TransformedShape<T, D>::get_coverage(const BoundingBox<T, D> &bbox) const
+{
+ return shape->get_coverage(inverse_trans.transform(bbox));
+}
+
} // namespace Geometry
} // namespace Msp