mirror of https://github.com/CGAL/cgal
1140 lines
29 KiB
Plaintext
1140 lines
29 KiB
Plaintext
@! $RCSfile$
|
|
@! $Revision$
|
|
@! $Date$
|
|
|
|
@! Author: Geert-Jan Giezeman (geert@cs.uu.nl)
|
|
|
|
@i cgal_util.fwi
|
|
|
|
|
|
@A@<Three dimensional intersection routines@>
|
|
|
|
Because there are a lot of intersection routines (quadratic in the number of
|
|
object types), those routines are split in several classes.
|
|
|
|
@B@<Class 1 intersection routines@>
|
|
|
|
@C@<Line Plane intersection@>
|
|
|
|
@$@<3D Line Plane intersection declarations@>==@{
|
|
|
|
CGAL_BEGIN_NAMESPACE
|
|
|
|
template <class R>
|
|
Object
|
|
intersection(const Plane_3<R> &plane, const Line_3<R>&line);
|
|
|
|
template <class R>
|
|
inline
|
|
Object
|
|
intersection(const Line_3<R>&line, const Plane_3<R> &plane)
|
|
{
|
|
return intersection(plane,line);
|
|
}
|
|
|
|
template <class R>
|
|
bool
|
|
do_intersect(const Plane_3<R> &p2, const Line_3<R> &p1);
|
|
|
|
|
|
template <class R>
|
|
inline bool
|
|
do_intersect(
|
|
const Line_3<R> &p1,
|
|
const Plane_3<R> &p2)
|
|
{
|
|
return do_intersect(p2,p1);
|
|
}
|
|
|
|
CGAL_END_NAMESPACE
|
|
|
|
@}
|
|
|
|
@$@<3D Line Plane intersection implementation@>==@{
|
|
|
|
CGAL_BEGIN_NAMESPACE
|
|
|
|
template <class R>
|
|
Object
|
|
intersection(const Plane_3<R> &plane, const Line_3<R>&line)
|
|
{
|
|
typedef typename R::RT RT;
|
|
const Point_3<R> &line_pt = line.point();
|
|
const Direction_3<R> &line_dir = line.direction();
|
|
RT num, den;
|
|
num = plane.a()*line_pt.hx() + plane.b()*line_pt.hy()
|
|
+ plane.c()*line_pt.hz() + wmult((R*)0, plane.d(), line_pt.hw());
|
|
den = plane.a()*line_dir.dx() + plane.b()*line_dir.dy()
|
|
+ plane.c()*line_dir.dz();
|
|
if (den == RT(0)) {
|
|
if (num == RT(0)) {
|
|
// all line
|
|
return make_object(line);
|
|
} else {
|
|
// no intersection
|
|
return Object();
|
|
}
|
|
}
|
|
return make_object(Point_3<R>(
|
|
den*line_pt.hx()-num*line_dir.dx(),
|
|
den*line_pt.hy()-num*line_dir.dy(),
|
|
den*line_pt.hz()-num*line_dir.dz(),
|
|
wmult((R*)0, den, line_pt.hw())));
|
|
}
|
|
|
|
template <class R>
|
|
bool
|
|
do_intersect(const Plane_3<R> &plane, const Line_3<R>&line)
|
|
{
|
|
typedef typename R::RT RT;
|
|
const Point_3<R> &line_pt = line.point();
|
|
const Direction_3<R> &line_dir = line.direction();
|
|
RT num, den;
|
|
den = plane.a()*line_dir.dx() + plane.b()*line_dir.dy()
|
|
+ plane.c()*line_dir.dz();
|
|
if (den != RT(0))
|
|
return true;
|
|
num = plane.a()*line_pt.hx() + plane.b()*line_pt.hy()
|
|
+ plane.c()*line_pt.hz() + wmult((R*)0, plane.d(), line_pt.hw());
|
|
if (num == RT(0)) {
|
|
// all line
|
|
return true;
|
|
} else {
|
|
// no intersection
|
|
return false;
|
|
}
|
|
}
|
|
CGAL_END_NAMESPACE
|
|
|
|
@}
|
|
|
|
@C@<Segment Plane intersection@>
|
|
|
|
@$@<3D Segment Plane intersection declarations@>==@{
|
|
|
|
CGAL_BEGIN_NAMESPACE
|
|
|
|
template <class R>
|
|
Object
|
|
intersection(const Plane_3<R> &plane, const Segment_3<R>&seg);
|
|
|
|
template <class R>
|
|
inline
|
|
Object
|
|
intersection(const Segment_3<R>&seg, const Plane_3<R> &plane)
|
|
{
|
|
return intersection(plane,seg);
|
|
}
|
|
|
|
template <class R>
|
|
bool
|
|
do_intersect(const Plane_3<R> &p1, const Segment_3<R> &p2);
|
|
|
|
|
|
template <class R>
|
|
inline bool
|
|
do_intersect(
|
|
const Segment_3<R> &p1,
|
|
const Plane_3<R> &p2)
|
|
{
|
|
return do_intersect(p2,p1);
|
|
}
|
|
|
|
CGAL_END_NAMESPACE
|
|
|
|
@}
|
|
|
|
@$@<3D Segment Plane intersection implementation@>==@{
|
|
|
|
CGAL_BEGIN_NAMESPACE
|
|
|
|
template <class R>
|
|
Object
|
|
intersection(const Plane_3<R> &plane, const Segment_3<R>&seg)
|
|
{
|
|
const Point_3<R> &source = seg.source();
|
|
const Point_3<R> &target = seg.target();
|
|
Oriented_side source_side,target_side;
|
|
source_side = plane.oriented_side(source);
|
|
target_side = plane.oriented_side(target);
|
|
switch (source_side) {
|
|
case ON_ORIENTED_BOUNDARY:
|
|
if (target_side == ON_ORIENTED_BOUNDARY)
|
|
return make_object(seg);
|
|
else
|
|
return make_object(source);
|
|
case ON_POSITIVE_SIDE:
|
|
switch (target_side) {
|
|
case ON_ORIENTED_BOUNDARY:
|
|
return make_object(target);
|
|
case ON_POSITIVE_SIDE:
|
|
return Object();
|
|
case ON_NEGATIVE_SIDE:
|
|
return intersection(plane, seg.supporting_line());
|
|
}
|
|
case ON_NEGATIVE_SIDE:
|
|
switch (target_side) {
|
|
case ON_ORIENTED_BOUNDARY:
|
|
return make_object(target);
|
|
case ON_POSITIVE_SIDE:
|
|
return intersection(plane, seg.supporting_line());
|
|
case ON_NEGATIVE_SIDE:
|
|
return Object();
|
|
}
|
|
}
|
|
CGAL_kernel_assertion_msg(false, "Supposedly unreachable code.");
|
|
return Object();
|
|
}
|
|
|
|
template <class R>
|
|
bool
|
|
do_intersect(const Plane_3<R> &plane, const Segment_3<R>&seg)
|
|
{
|
|
const Point_3<R> &source = seg.source();
|
|
const Point_3<R> &target = seg.target();
|
|
Oriented_side source_side,target_side;
|
|
source_side = plane.oriented_side(source);
|
|
target_side = plane.oriented_side(target);
|
|
if ( source_side == target_side
|
|
&& target_side != ON_ORIENTED_BOUNDARY) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
CGAL_END_NAMESPACE
|
|
@}
|
|
|
|
@C@<Ray Plane intersection@>
|
|
|
|
@$@<3D Ray Plane intersection declarations@>==@{
|
|
|
|
CGAL_BEGIN_NAMESPACE
|
|
|
|
template <class R>
|
|
Object
|
|
intersection(const Plane_3<R> &plane, const Ray_3<R>&ray);
|
|
|
|
template <class R>
|
|
inline
|
|
Object
|
|
intersection(const Ray_3<R>&ray, const Plane_3<R> &plane)
|
|
{
|
|
return intersection(plane,ray);
|
|
}
|
|
|
|
template <class R>
|
|
bool
|
|
do_intersect(const Plane_3<R> &p1, const Ray_3<R> &p2);
|
|
|
|
|
|
template <class R>
|
|
inline bool
|
|
do_intersect(
|
|
const Ray_3<R> &p1,
|
|
const Plane_3<R> &p2)
|
|
{
|
|
return do_intersect(p2,p1);
|
|
}
|
|
CGAL_END_NAMESPACE
|
|
@}
|
|
|
|
First we compute the intersection of the supporting line of the ray with
|
|
the plane.
|
|
|
|
@$@<3D Ray Plane intersection implementation@>==@{
|
|
|
|
CGAL_BEGIN_NAMESPACE
|
|
|
|
template <class R>
|
|
Object
|
|
intersection(const Plane_3<R> &plane, const Ray_3<R>&ray)
|
|
{
|
|
const Object line_intersection =
|
|
intersection(plane, ray.supporting_line());
|
|
Point_3<R> isp;
|
|
if (assign(isp, line_intersection)) {
|
|
if (ray.collinear_has_on(isp))
|
|
return line_intersection;
|
|
else
|
|
return Object();
|
|
}
|
|
if (line_intersection.is_empty())
|
|
return line_intersection;
|
|
return make_object(ray);
|
|
}
|
|
|
|
template <class R>
|
|
bool
|
|
do_intersect(const Plane_3<R> &plane, const Ray_3<R>&ray)
|
|
{
|
|
const Object line_intersection =
|
|
intersection(plane, ray.supporting_line());
|
|
if (line_intersection.is_empty())
|
|
return false;
|
|
Point_3<R> isp;
|
|
if (assign(isp, line_intersection)) {
|
|
if (ray.collinear_has_on(isp))
|
|
return true;
|
|
else
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
CGAL_END_NAMESPACE
|
|
|
|
@}
|
|
|
|
@C@<Plane Plane intersection@>
|
|
|
|
@$@<3D Plane Plane intersection declarations@>==@{
|
|
|
|
CGAL_BEGIN_NAMESPACE
|
|
|
|
template <class R>
|
|
Object
|
|
intersection(const Plane_3<R> &plane1, const Plane_3<R>&plane2);
|
|
|
|
template <class R>
|
|
inline bool
|
|
do_intersect(const Plane_3<R> &plane1, const Plane_3<R>&plane2)
|
|
{
|
|
return ! intersection(plane1, plane2).is_empty();
|
|
}
|
|
CGAL_END_NAMESPACE
|
|
|
|
@}
|
|
|
|
|
|
@$@<3D Plane Plane intersection implementation@>==@{
|
|
|
|
CGAL_BEGIN_NAMESPACE
|
|
|
|
template <class R>
|
|
Object
|
|
intersection(const Plane_3<R> &plane1, const Plane_3<R>&plane2)
|
|
{
|
|
typedef typename R::RT RT;
|
|
const RT &a = plane1.a();
|
|
const RT &b = plane1.b();
|
|
const RT &c = plane1.c();
|
|
const RT &d = plane1.d();
|
|
const RT &p = plane2.a();
|
|
const RT &q = plane2.b();
|
|
const RT &r = plane2.c();
|
|
const RT &s = plane2.d();
|
|
const RT zero = RT(0);
|
|
RT det;
|
|
Point_3<R> is_pt;
|
|
Direction_3<R> is_dir;
|
|
|
|
det = a*q-p*b;
|
|
if (det != zero) {
|
|
is_pt = Point_3<R>(b*s-d*q, p*d-a*s, zero, det);
|
|
is_dir = Direction_3<R>(b*r-c*q, p*c-a*r, det);
|
|
return make_object(Line_3<R>(is_pt, is_dir));
|
|
}
|
|
det = a*r-p*c;
|
|
if (det != zero) {
|
|
is_pt = Point_3<R>(c*s-d*r, zero, p*d-a*s, det);
|
|
is_dir = Direction_3<R>(c*q-b*r, det, p*b-a*q);
|
|
return make_object(Line_3<R>(is_pt, is_dir));
|
|
}
|
|
det = b*r-c*q;
|
|
if (det != zero) {
|
|
is_pt = Point_3<R>(zero, c*s-d*r, d*q-b*s, det);
|
|
is_dir = Direction_3<R>(det, c*p-a*r, a*q-b*p);
|
|
return make_object(Line_3<R>(is_pt, is_dir));
|
|
}
|
|
// degenerate case
|
|
if (a!=zero || p!=zero) {
|
|
if (a*s == p*d)
|
|
return make_object(plane1);
|
|
else
|
|
return Object();
|
|
}
|
|
if (b!=zero || q!=zero) {
|
|
if (b*s == q*d)
|
|
return make_object(plane1);
|
|
else
|
|
return Object();
|
|
}
|
|
if (c!=zero || r!=zero) {
|
|
if (c*s == r*d)
|
|
return make_object(plane1);
|
|
else
|
|
return Object();
|
|
}
|
|
return make_object(plane1);
|
|
}
|
|
|
|
CGAL_END_NAMESPACE
|
|
@}
|
|
|
|
@C@<Line Box intersection@>
|
|
|
|
@$@<3D Line Box intersection declarations@>==@{
|
|
|
|
CGAL_BEGIN_NAMESPACE
|
|
|
|
template <class R>
|
|
Object
|
|
intersection(const Line_3<R> &line,
|
|
const Bbox_3 &box) ;
|
|
|
|
template <class R>
|
|
inline Object
|
|
intersection(const Bbox_3 &box,
|
|
const Line_3<R> &line)
|
|
{
|
|
return intersection(line, box);
|
|
}
|
|
|
|
CGAL_END_NAMESPACE
|
|
@}
|
|
|
|
@$@<3D CD Line Box intersection declarations@>==@{
|
|
|
|
CGAL_BEGIN_NAMESPACE
|
|
|
|
extern Object
|
|
intersection_bl(const Bbox_3 &box,
|
|
double lx1, double ly1, double lz1,
|
|
double lx2, double ly2, double lz2,
|
|
bool min_infinite, bool max_infinite);
|
|
CGAL_END_NAMESPACE
|
|
|
|
@}
|
|
|
|
@D@<Implementation@>
|
|
Lines with a representation other than Cartesian double are transformed to
|
|
Cartesian double representation by transforming the coordinates of a point
|
|
of the line and of the direction.
|
|
|
|
@$@<3D Line Box intersection implementation@>==@{
|
|
|
|
CGAL_BEGIN_NAMESPACE
|
|
|
|
template <class R>
|
|
Object
|
|
intersection(const Line_3<R> &line,
|
|
const Bbox_3 &box)
|
|
{
|
|
const Point_3<R> &linepoint = line.point();
|
|
const Direction_3<R> &linedir = line.direction();
|
|
return intersection_bl(box,
|
|
CGAL::to_double(linepoint.x()),
|
|
CGAL::to_double(linepoint.y()),
|
|
CGAL::to_double(linepoint.z()),
|
|
CGAL::to_double(linedir.dx()),
|
|
CGAL::to_double(linedir.dy()),
|
|
CGAL::to_double(linedir.dz()),
|
|
true, true
|
|
);
|
|
}
|
|
|
|
CGAL_END_NAMESPACE
|
|
@}
|
|
|
|
|
|
|
|
@$@<3D CD Line Box intersection implementation@>==@{
|
|
|
|
CGAL_BEGIN_NAMESPACE
|
|
|
|
Object
|
|
intersection_bl(const Bbox_3 &box,
|
|
double lpx, double lpy, double lpz,
|
|
double ldx, double ldy, double ldz,
|
|
bool min_infinite, bool max_infinite)
|
|
{
|
|
typedef Simple_cartesian<double> R_cd;
|
|
Point_3<R_cd> ref_point(lpx,lpy, lpz);
|
|
Vector_3<R_cd> dir(ldx, ldy, ldz);
|
|
double seg_min = 0.0, seg_max = 1.0;
|
|
// first on x value
|
|
if (dir.x() == 0.0) {
|
|
if (ref_point.x() < box.xmin())
|
|
return Object();
|
|
if (ref_point.x() > box.xmax())
|
|
return Object();
|
|
} else {
|
|
double newmin, newmax;
|
|
if (dir.x() > 0.0) {
|
|
newmin = (box.xmin()-ref_point.x())/dir.x();
|
|
newmax = (box.xmax()-ref_point.x())/dir.x();
|
|
} else {
|
|
newmin = (box.xmax()-ref_point.x())/dir.x();
|
|
newmax = (box.xmin()-ref_point.x())/dir.x();
|
|
}
|
|
if (min_infinite) {
|
|
min_infinite = false;
|
|
seg_min = newmin;
|
|
} else {
|
|
if (newmin > seg_min)
|
|
seg_min = newmin;
|
|
}
|
|
if (max_infinite) {
|
|
max_infinite = false;
|
|
seg_max = newmax;
|
|
} else {
|
|
if (newmax < seg_max)
|
|
seg_max = newmax;
|
|
}
|
|
if (seg_max < seg_min)
|
|
return Object();
|
|
}
|
|
// now on y value
|
|
if (dir.y() == 0.0) {
|
|
if (ref_point.y() < box.ymin())
|
|
return Object();
|
|
if (ref_point.y() > box.ymax())
|
|
return Object();
|
|
} else {
|
|
double newmin, newmax;
|
|
if (dir.y() > 0.0) {
|
|
newmin = (box.ymin()-ref_point.y())/dir.y();
|
|
newmax = (box.ymax()-ref_point.y())/dir.y();
|
|
} else {
|
|
newmin = (box.ymax()-ref_point.y())/dir.y();
|
|
newmax = (box.ymin()-ref_point.y())/dir.y();
|
|
}
|
|
if (min_infinite) {
|
|
min_infinite = false;
|
|
seg_min = newmin;
|
|
} else {
|
|
if (newmin > seg_min)
|
|
seg_min = newmin;
|
|
}
|
|
if (max_infinite) {
|
|
max_infinite = false;
|
|
seg_max = newmax;
|
|
} else {
|
|
if (newmax < seg_max)
|
|
seg_max = newmax;
|
|
}
|
|
if (seg_max < seg_min)
|
|
return Object();
|
|
}
|
|
// now on z value
|
|
if (dir.z() == 0.0) {
|
|
if (ref_point.z() < box.zmin())
|
|
return Object();
|
|
if (ref_point.z() > box.zmax())
|
|
return Object();
|
|
} else {
|
|
double newmin, newmax;
|
|
if (dir.z() > 0.0) {
|
|
newmin = (box.zmin()-ref_point.z())/dir.z();
|
|
newmax = (box.zmax()-ref_point.z())/dir.z();
|
|
} else {
|
|
newmin = (box.zmax()-ref_point.z())/dir.z();
|
|
newmax = (box.zmin()-ref_point.z())/dir.z();
|
|
}
|
|
if (min_infinite) {
|
|
min_infinite = false;
|
|
seg_min = newmin;
|
|
} else {
|
|
if (newmin > seg_min)
|
|
seg_min = newmin;
|
|
}
|
|
if (max_infinite) {
|
|
max_infinite = false;
|
|
seg_max = newmax;
|
|
} else {
|
|
if (newmax < seg_max)
|
|
seg_max = newmax;
|
|
}
|
|
if (seg_max < seg_min)
|
|
return Object();
|
|
}
|
|
if (min_infinite || max_infinite) {
|
|
seg_max = 0.0;
|
|
CGAL_kernel_assertion_msg(true,
|
|
"Zero direction vector of line detected.");
|
|
}
|
|
if (seg_max == seg_min)
|
|
return make_object(ref_point + dir*seg_max);
|
|
return make_object(Segment_3<R_cd>(
|
|
ref_point + dir*seg_min, ref_point + dir*seg_max));
|
|
}
|
|
|
|
CGAL_END_NAMESPACE
|
|
@}
|
|
|
|
@C@<Ray Box intersection@>
|
|
|
|
@$@<3D Ray Box intersection declarations@>==@{
|
|
|
|
CGAL_BEGIN_NAMESPACE
|
|
|
|
template <class R>
|
|
Object
|
|
intersection(const Ray_3<R> &ray,
|
|
const Bbox_3 &box) ;
|
|
|
|
template <class R>
|
|
inline Object
|
|
intersection(const Bbox_3 &box,
|
|
const Ray_3<R> &ray)
|
|
{
|
|
return intersection(ray, box);
|
|
}
|
|
|
|
CGAL_END_NAMESPACE
|
|
@}
|
|
|
|
|
|
@D@<Implementation@>
|
|
Rays with a representation other than Cartesian double are transformed to
|
|
Cartesian double representation by transforming the coordinates of a point
|
|
of the ray and of the direction.
|
|
|
|
@$@<3D Ray Box intersection implementation@>==@{
|
|
|
|
CGAL_BEGIN_NAMESPACE
|
|
|
|
template <class R>
|
|
Object
|
|
intersection(const Ray_3<R> &ray,
|
|
const Bbox_3 &box)
|
|
{
|
|
const Point_3<R> &linepoint = ray.source();
|
|
const Direction_3<R> &linedir = ray.direction();
|
|
return intersection_bl(box,
|
|
CGAL::to_double(linepoint.x()),
|
|
CGAL::to_double(linepoint.y()),
|
|
CGAL::to_double(linepoint.z()),
|
|
CGAL::to_double(linedir.dx()),
|
|
CGAL::to_double(linedir.dy()),
|
|
CGAL::to_double(linedir.dz()),
|
|
false, true
|
|
);
|
|
}
|
|
|
|
CGAL_END_NAMESPACE
|
|
@}
|
|
|
|
@C@<Segment Box intersection@>
|
|
|
|
@$@<3D Segment Box intersection declarations@>==@{
|
|
|
|
CGAL_BEGIN_NAMESPACE
|
|
|
|
template <class R>
|
|
Object
|
|
intersection(const Segment_3<R> &seg,
|
|
const Bbox_3 &box) ;
|
|
|
|
template <class R>
|
|
inline Object
|
|
intersection(const Bbox_3 &box,
|
|
const Segment_3<R> &seg)
|
|
{
|
|
return intersection(seg, box);
|
|
}
|
|
CGAL_END_NAMESPACE
|
|
@}
|
|
|
|
|
|
@D@<Implementation@>
|
|
Segments with a representation other than Cartesian double are transformed to
|
|
Cartesian double representation by transforming the coordinates of a point
|
|
of the segment and of the direction.
|
|
|
|
@$@<3D Segment Box intersection implementation@>==@{
|
|
|
|
CGAL_BEGIN_NAMESPACE
|
|
|
|
template <class R>
|
|
Object
|
|
intersection(const Segment_3<R> &seg,
|
|
const Bbox_3 &box)
|
|
{
|
|
const Point_3<R> &linepoint = seg.source();
|
|
const Vector_3<R> &diffvec = seg.target()-linepoint;
|
|
return intersection_bl(box,
|
|
CGAL::to_double(linepoint.x()),
|
|
CGAL::to_double(linepoint.y()),
|
|
CGAL::to_double(linepoint.z()),
|
|
CGAL::to_double(diffvec.x()),
|
|
CGAL::to_double(diffvec.y()),
|
|
CGAL::to_double(diffvec.z()),
|
|
false, false
|
|
);
|
|
}
|
|
|
|
CGAL_END_NAMESPACE
|
|
@}
|
|
|
|
@C@<Iso_cuboid Line intersection@>
|
|
|
|
@$@<3D Iso_cuboid Line intersection declarations@>@Z==@{
|
|
|
|
CGAL_BEGIN_NAMESPACE
|
|
|
|
template <class R>
|
|
Object
|
|
intersection(const Line_3<R> &line,
|
|
const Iso_cuboid_3<R> &box) ;
|
|
|
|
template <class R>
|
|
inline Object
|
|
intersection(const Iso_cuboid_3<R> &box,
|
|
const Line_3<R> &line)
|
|
{
|
|
return intersection(line, box);
|
|
}
|
|
|
|
CGAL_END_NAMESPACE
|
|
@}
|
|
|
|
|
|
@D@<Implementation@>
|
|
|
|
@$@<3D Iso_cuboid Line intersection implementation@>@Z==@{
|
|
|
|
CGAL_BEGIN_NAMESPACE
|
|
|
|
template <class R>
|
|
Object
|
|
intersection(const Line_3<R> &line,
|
|
const Iso_cuboid_3<R> &box)
|
|
{
|
|
typedef typename R::RT RT;
|
|
typedef typename R::FT FT;
|
|
bool all_values = true;
|
|
FT _min, _max;
|
|
Point_3<R> const & _ref_point=line.point();
|
|
Vector_3<R> const & _dir=line.direction().vector();
|
|
Point_3<R> const & _iso_min=box.min();
|
|
Point_3<R> const & _iso_max=box.max();
|
|
int i;
|
|
for (i=0; i< _ref_point.dimension(); i++) {
|
|
if (_dir.homogeneous(i) == RT(0)) {
|
|
if (_ref_point.cartesian(i) < _iso_min.cartesian(i)) {
|
|
return Object();
|
|
}
|
|
if (_ref_point.cartesian(i) > _iso_max.cartesian(i)) {
|
|
return Object();
|
|
}
|
|
} else {
|
|
FT newmin, newmax;
|
|
if (_dir.homogeneous(i) > RT(0)) {
|
|
newmin = (_iso_min.cartesian(i) - _ref_point.cartesian(i)) /
|
|
_dir.cartesian(i);
|
|
newmax = (_iso_max.cartesian(i) - _ref_point.cartesian(i)) /
|
|
_dir.cartesian(i);
|
|
} else {
|
|
newmin = (_iso_max.cartesian(i) - _ref_point.cartesian(i)) /
|
|
_dir.cartesian(i);
|
|
newmax = (_iso_min.cartesian(i) - _ref_point.cartesian(i)) /
|
|
_dir.cartesian(i);
|
|
}
|
|
if (all_values) {
|
|
_min = newmin;
|
|
_max = newmax;
|
|
} else {
|
|
if (newmin > _min)
|
|
_min = newmin;
|
|
if (newmax < _max)
|
|
_max = newmax;
|
|
if (_max < _min) {
|
|
return Object();
|
|
}
|
|
}
|
|
all_values = false;
|
|
}
|
|
}
|
|
CGAL_kernel_assertion(!all_values);
|
|
if (_max == _min) {
|
|
return make_object(Point_3<R>(_ref_point + _dir * _min ));
|
|
}
|
|
return make_object(
|
|
Segment_3<R>(_ref_point + _dir*_min, _ref_point + _dir*_max));
|
|
}
|
|
|
|
CGAL_END_NAMESPACE
|
|
@}
|
|
|
|
@C@<Iso_cuboid Ray intersection@>
|
|
|
|
@$@<3D Iso_cuboid Ray intersection declarations@>@Z==@{
|
|
|
|
CGAL_BEGIN_NAMESPACE
|
|
|
|
template <class R>
|
|
Object
|
|
intersection(const Ray_3<R> &ray,
|
|
const Iso_cuboid_3<R> &box) ;
|
|
|
|
template <class R>
|
|
inline Object
|
|
intersection(const Iso_cuboid_3<R> &box,
|
|
const Ray_3<R> &ray)
|
|
{
|
|
return intersection(ray, box);
|
|
}
|
|
|
|
CGAL_END_NAMESPACE
|
|
@}
|
|
|
|
|
|
@D@<Implementation@>
|
|
|
|
@$@<3D Iso_cuboid Ray intersection implementation@>@Z==@{
|
|
|
|
CGAL_BEGIN_NAMESPACE
|
|
|
|
template <class R>
|
|
Object
|
|
intersection(const Ray_3<R> &ray,
|
|
const Iso_cuboid_3<R> &box)
|
|
{
|
|
typedef typename R::RT RT;
|
|
typedef typename R::FT FT;
|
|
bool all_values = true;
|
|
FT _min= FT(0), _max;
|
|
Point_3<R> const & _ref_point=ray.source();
|
|
Vector_3<R> const & _dir=ray.direction().vector();
|
|
Point_3<R> const & _iso_min=box.min();
|
|
Point_3<R> const & _iso_max=box.max();
|
|
int i;
|
|
for (i=0; i< _ref_point.dimension(); i++) {
|
|
if (_dir.homogeneous(i) == RT(0)) {
|
|
if (_ref_point.cartesian(i) < _iso_min.cartesian(i)) {
|
|
return Object();
|
|
}
|
|
if (_ref_point.cartesian(i) > _iso_max.cartesian(i)) {
|
|
return Object();
|
|
}
|
|
} else {
|
|
FT newmin, newmax;
|
|
if (_dir.homogeneous(i) > RT(0)) {
|
|
newmin = (_iso_min.cartesian(i) - _ref_point.cartesian(i)) /
|
|
_dir.cartesian(i);
|
|
newmax = (_iso_max.cartesian(i) - _ref_point.cartesian(i)) /
|
|
_dir.cartesian(i);
|
|
} else {
|
|
newmin = (_iso_max.cartesian(i) - _ref_point.cartesian(i)) /
|
|
_dir.cartesian(i);
|
|
newmax = (_iso_min.cartesian(i) - _ref_point.cartesian(i)) /
|
|
_dir.cartesian(i);
|
|
}
|
|
if (all_values) {
|
|
_max = newmax;
|
|
} else {
|
|
if (newmax < _max)
|
|
_max = newmax;
|
|
}
|
|
if (newmin > _min)
|
|
_min = newmin;
|
|
if (_max < _min)
|
|
return Object();
|
|
all_values = false;
|
|
}
|
|
}
|
|
CGAL_kernel_assertion(!all_values);
|
|
if (_max == _min) {
|
|
return make_object(Point_3<R>(_ref_point + _dir * _min ));
|
|
}
|
|
return make_object(
|
|
Segment_3<R>(_ref_point + _dir*_min, _ref_point + _dir*_max));
|
|
}
|
|
|
|
CGAL_END_NAMESPACE
|
|
@}
|
|
|
|
@C@<Iso_cuboid Segment intersection@>
|
|
|
|
@$@<3D Iso_cuboid Segment intersection declarations@>@Z==@{
|
|
|
|
CGAL_BEGIN_NAMESPACE
|
|
|
|
template <class R>
|
|
Object
|
|
intersection(const Segment_3<R> &seg,
|
|
const Iso_cuboid_3<R> &box) ;
|
|
|
|
template <class R>
|
|
inline Object
|
|
intersection(const Iso_cuboid_3<R> &box,
|
|
const Segment_3<R> &seg)
|
|
{
|
|
return intersection(seg, box);
|
|
}
|
|
|
|
CGAL_END_NAMESPACE
|
|
@}
|
|
|
|
|
|
@D@<Implementation@>
|
|
|
|
@$@<3D Iso_cuboid Segment intersection implementation@>@Z==@{
|
|
|
|
CGAL_BEGIN_NAMESPACE
|
|
|
|
template <class R>
|
|
Object
|
|
intersection(const Segment_3<R> &seg,
|
|
const Iso_cuboid_3<R> &box)
|
|
{
|
|
typedef typename R::RT RT;
|
|
typedef typename R::FT FT;
|
|
FT _min= FT(0), _max;
|
|
|
|
Point_3<R> const & _ref_point=seg.source();
|
|
Vector_3<R> const & _dir=seg.direction().vector();
|
|
Point_3<R> const & _iso_min=box.min();
|
|
Point_3<R> const & _iso_max=box.max();
|
|
int main_dir =
|
|
(CGAL_NTS abs(_dir.x()) > CGAL_NTS abs(_dir.y()) )
|
|
? (CGAL_NTS abs(_dir.x()) > CGAL_NTS abs(_dir.z()) ? 0 : 2)
|
|
: (CGAL_NTS abs(_dir.y()) > CGAL_NTS abs(_dir.z()) ? 1 : 2);
|
|
_max = (seg.target().cartesian(main_dir)-_ref_point.cartesian(main_dir)) /
|
|
_dir.cartesian(main_dir);
|
|
int i;
|
|
for (i=0; i< _ref_point.dimension(); i++) {
|
|
if (_dir.homogeneous(i) == RT(0)) {
|
|
if (_ref_point.cartesian(i) < _iso_min.cartesian(i)) {
|
|
return Object();
|
|
}
|
|
if (_ref_point.cartesian(i) > _iso_max.cartesian(i)) {
|
|
return Object();
|
|
}
|
|
} else {
|
|
FT newmin, newmax;
|
|
if (_dir.homogeneous(i) > RT(0)) {
|
|
newmin = (_iso_min.cartesian(i) - _ref_point.cartesian(i)) /
|
|
_dir.cartesian(i);
|
|
newmax = (_iso_max.cartesian(i) - _ref_point.cartesian(i)) /
|
|
_dir.cartesian(i);
|
|
} else {
|
|
newmin = (_iso_max.cartesian(i) - _ref_point.cartesian(i)) /
|
|
_dir.cartesian(i);
|
|
newmax = (_iso_min.cartesian(i) - _ref_point.cartesian(i)) /
|
|
_dir.cartesian(i);
|
|
}
|
|
if (newmax < _max)
|
|
_max = newmax;
|
|
if (newmin > _min)
|
|
_min = newmin;
|
|
if (_max < _min)
|
|
return Object();
|
|
}
|
|
}
|
|
if (_max == _min) {
|
|
return make_object(Point_3<R>(_ref_point + _dir * _min ));
|
|
}
|
|
return make_object(
|
|
Segment_3<R>(_ref_point + _dir*_min, _ref_point + _dir*_max));
|
|
}
|
|
|
|
CGAL_END_NAMESPACE
|
|
@}
|
|
|
|
@C@<Iso_cuboid Iso_cuboid intersection@>
|
|
|
|
@$@<3D Iso_cuboid Iso_cuboid intersection declarations@>@Z==@{
|
|
|
|
CGAL_BEGIN_NAMESPACE
|
|
|
|
template <class R>
|
|
Object
|
|
intersection(const Iso_cuboid_3<R> &box1,
|
|
const Iso_cuboid_3<R> &box2) ;
|
|
|
|
CGAL_END_NAMESPACE
|
|
@}
|
|
|
|
|
|
@D@<Implementation@>
|
|
|
|
@$@<3D Iso_cuboid Iso_cuboid intersection implementation@>@Z==@{
|
|
|
|
CGAL_BEGIN_NAMESPACE
|
|
|
|
template <class R>
|
|
Object
|
|
intersection(
|
|
const Iso_cuboid_3<R> &icub1,
|
|
const Iso_cuboid_3<R> &icub2)
|
|
{
|
|
Point_3<R> min_points[2];
|
|
Point_3<R> max_points[2];
|
|
min_points[0] = icub1.min();
|
|
min_points[1] = icub2.min();
|
|
max_points[0] = icub1.max();
|
|
max_points[1] = icub2.max();
|
|
typedef typename R::FT FT;
|
|
const int DIM = 3;
|
|
int min_idx[DIM];
|
|
int max_idx[DIM];
|
|
Point_3<R> newmin;
|
|
Point_3<R> newmax;
|
|
for (int dim = 0; dim < DIM; ++dim) {
|
|
min_idx[dim] =
|
|
min_points[0].cartesian(dim) >= min_points[1].cartesian(dim) ? 0 : 1;
|
|
max_idx[dim] =
|
|
max_points[0].cartesian(dim) <= max_points[1].cartesian(dim) ? 0 : 1;
|
|
if (min_idx[dim] != max_idx[dim]
|
|
&& max_points[max_idx[dim]].cartesian(dim)
|
|
< min_points[min_idx[dim]].cartesian(dim))
|
|
return Object();
|
|
}
|
|
if (min_idx[0] == min_idx[1] && min_idx[0] == min_idx[2]) {
|
|
newmin = min_points[min_idx[0]];
|
|
} else {
|
|
newmin = Point_3<R>(
|
|
min_idx[0] == 0
|
|
? wmult((R*)0, min_points[0].hx(), min_points[1].hw())
|
|
: wmult((R*)0, min_points[1].hx(), min_points[0].hw())
|
|
,
|
|
min_idx[1] == 0
|
|
? wmult((R*)0, min_points[0].hy(), min_points[1].hw())
|
|
: wmult((R*)0, min_points[1].hy(), min_points[0].hw())
|
|
,
|
|
min_idx[2] == 0
|
|
? wmult((R*)0, min_points[0].hz(), min_points[1].hw())
|
|
: wmult((R*)0, min_points[1].hz(), min_points[0].hw())
|
|
,
|
|
wmult((R*)0, min_points[0].hw(), min_points[1].hw()) );
|
|
}
|
|
if (max_idx[0] == max_idx[1] && max_idx[0] == max_idx[2]) {
|
|
newmax = max_points[max_idx[0]];
|
|
} else {
|
|
newmax = Point_3<R>(
|
|
max_idx[0] == 0
|
|
? wmult((R*)0, max_points[0].hx(), max_points[1].hw())
|
|
: wmult((R*)0, max_points[1].hx(), max_points[0].hw())
|
|
,
|
|
max_idx[1] == 0
|
|
? wmult((R*)0, max_points[0].hy(), max_points[1].hw())
|
|
: wmult((R*)0, max_points[1].hy(), max_points[0].hw())
|
|
,
|
|
max_idx[2] == 0
|
|
? wmult((R*)0, max_points[0].hz(), max_points[1].hw())
|
|
: wmult((R*)0, max_points[1].hz(), max_points[0].hw())
|
|
,
|
|
wmult((R*)0, max_points[0].hw(), max_points[1].hw()) );
|
|
}
|
|
Object result = make_object(Iso_cuboid_3<R>(newmin, newmax));
|
|
return result;
|
|
}
|
|
|
|
CGAL_END_NAMESPACE
|
|
@}
|
|
|
|
@$@<declarations 1@>==@{
|
|
#include <CGAL/Object.h>
|
|
#include <CGAL/bbox_intersection_3.h>
|
|
@<3D Plane Plane intersection declarations@>
|
|
@<3D Line Plane intersection declarations@>
|
|
@<3D Ray Plane intersection declarations@>
|
|
@<3D Segment Plane intersection declarations@>
|
|
@<3D Line Box intersection declarations@>
|
|
@<3D Ray Box intersection declarations@>
|
|
@<3D Segment Box intersection declarations@>
|
|
@<3D Iso_cuboid Line intersection declarations@>
|
|
@<3D Iso_cuboid Ray intersection declarations@>
|
|
@<3D Iso_cuboid Segment intersection declarations@>
|
|
@<3D Iso_cuboid Iso_cuboid intersection declarations@>
|
|
@}
|
|
|
|
@$@<outline definitions 1@>==@{
|
|
@<3D Plane Plane intersection implementation@>
|
|
@<3D Line Plane intersection implementation@>
|
|
@<3D Ray Plane intersection implementation@>
|
|
@<3D Segment Plane intersection implementation@>
|
|
@<3D Line Box intersection implementation@>
|
|
@<3D Ray Box intersection implementation@>
|
|
@<3D Segment Box intersection implementation@>
|
|
@<3D Iso_cuboid Line intersection implementation@>
|
|
@<3D Iso_cuboid Ray intersection implementation@>
|
|
@<3D Iso_cuboid Segment intersection implementation@>
|
|
@<3D Iso_cuboid Iso_cuboid intersection implementation@>
|
|
@}
|
|
|
|
|
|
@O@<../include/CGAL/bbox_intersection_3.h@>==@{
|
|
@<cgal_heading@>@(include/CGAL/bbox_intersection_3.h@,@-
|
|
web/intersection_3.fw@,@-
|
|
Geert-Jan Giezeman <geert@@cs.uu.nl>@,@-
|
|
Saarbruecken@)
|
|
|
|
#ifndef CGAL_BBOX_INTERSECTION_3_H
|
|
#define CGAL_BBOX_INTERSECTION_3_H
|
|
|
|
#include <CGAL/Bbox_3.h>
|
|
#include <CGAL/Object.h>
|
|
@<3D CD Line Box intersection declarations@>
|
|
#endif // CGAL_BBOX_INTERSECTION_3_H
|
|
@}
|
|
|
|
@O@<../include/CGAL/intersection_3_1.h@>==@{@-
|
|
@<cgal_heading@>@(include/CGAL/intersection_3_1.h@,@-
|
|
web/intersection_3.fw@,@-
|
|
Geert-Jan Giezeman <geert@@cs.uu.nl>@,@-
|
|
Saarbruecken@)
|
|
|
|
#ifndef CGAL_INTERSECTION_3_1_H
|
|
#define CGAL_INTERSECTION_3_1_H
|
|
|
|
|
|
@<declarations 1@>
|
|
|
|
|
|
#ifdef CGAL_CFG_NO_AUTOMATIC_TEMPLATE_INCLUSION
|
|
#include <CGAL/intersection_3_1.C>
|
|
#endif
|
|
|
|
#endif // CGAL_INTERSECTION_3_1_H
|
|
@}
|
|
|
|
@O@<../include/CGAL/intersection_3_1.C@>==@{@-
|
|
@<cgal_heading@>@(include/CGAL/intersection_3_1.C@,@-
|
|
web/intersection_3.fw@,@-
|
|
Geert-Jan Giezeman <geert@@cs.uu.nl>@,@-
|
|
Saarbruecken@)
|
|
|
|
#include <CGAL/wmult.h>
|
|
@<outline definitions 1@>
|
|
@}
|
|
|
|
|
|
|
|
@B@<All intersections@>
|
|
|
|
The following header file includes all other header files that define
|
|
intersections. This is a convenience for people who don't want to
|
|
remember which intersection header file to include and don't mind the extra
|
|
compilation time.
|
|
|
|
|
|
@O@<../include/CGAL/intersection_3.h@>==@{@-
|
|
|
|
@<cgal_heading@>@(include/CGAL/intersection_3.h@,@-
|
|
web/intersection_3.fw@,@-
|
|
Geert-Jan Giezeman <geert@@cs.uu.nl>@,@-
|
|
Saarbruecken@)
|
|
|
|
#ifndef CGAL_INTERSECTION_3_H
|
|
#define CGAL_INTERSECTION_3_H
|
|
|
|
#include <CGAL/intersection_3_1.h>
|
|
|
|
|
|
#endif // CGAL_INTERSECTION_3_H
|
|
@}
|
|
|
|
@O@<../src/Bbox_3_intersections.C@>==@{@-
|
|
@<cgal_heading@>@(src/Bbox_3_intersections.C@,@-
|
|
web/intersection_3.fw@,@-
|
|
Geert-Jan Giezeman <geert@@cs.uu.nl>@,@-
|
|
Saarbruecken@)
|
|
|
|
#include <CGAL/Simple_cartesian.h>
|
|
#include <CGAL/Point_3.h>
|
|
#include <CGAL/bbox_intersection_3.h>
|
|
@<3D CD Line Box intersection implementation@>
|
|
@}
|