csg_intersect_primitive.h : Intersections with ~10 different primitives

//env/presentation/tboolean_parade_sep2017.png

csg_intersect_primitive.h : csg_bounds_convexpolyhedron

Bounds of convex polyhedron defined by a set of planes.

csg_intersect_primitive.h : csg_intersect_convexpolyhedron

Intersect with convex polyhedron defined by a set of planes.

csg_intersect_primitive.h : csg_intersect_zsphere

Plane eqn in general frame:

point_in_plane.plane_normal = plane_dist_to_origin

Ray-Plane intersection:

( ray_origin + t ray_direction ).plane_normal = plane_dist_to_origin

 t = plane_dist_to_origin - ray_origin.plane_normal
    -------------------------------------------------
            ray_direction.plane_normal

Now consider plane normal to be +z axis and:

t = plane_dist_to_origin - ray_origin.z
   --------------------------------------
         ray_direction.z

plane_dist_to_orign = zmin or zmax

Intersect with sphere:

O = ray_origin - center
D = ray_direction

(O + t D).(O + t D) = rr

t^2 D.D + 2 t O.D + O.O - rr  = 0

d = D.D
b = O.D
c = O.O - rr

csg_intersect_primitive.h : _csg_intersect_box

Just because the ray intersects the box doesnt mean its a usable intersect, there are 3 possibilities

        t_near       t_far

          |           |
-----1----|----2------|------3---------->
          |           |

csg_intersect_primitive.h : csg_intersect_disc

RTCD p197 (Real Time Collision Detection)

CSG_DISC was implemented to avoid degeneracy/speckle problems when using CSG_CYLINDER to describe very flat cylinders such as Daya Bays ESR mirror surface. Note that the simplicity of disc intersects compared to cylinder has allowed inner radius handling (in param.f.z) for easy annulus definition without using CSG subtraction.

NB ray-plane intersects are performed with the center disc only at: z = zc = (z1+z2)/2 The t_center obtained is then deltared up and down depending on (z2-z1)/2

This approach appears to avoid the numerical instability speckling problems encountered with csg_intersect_cylinder when dealing with very flat disc like cylinders.

Note that intersects with the edge of the disk are not implemented, if such intersects are relevant you need to use CSG_CYLINDER not CSG_DISC.

For testing see tboolean-esr and tboolean-disc.:

       r(t) = O + t n

                      ^ /         ^
                      |/          | d
----------------------+-----------|-------------------------------- z2
                     /            |
- - - - - - - - - - * - - - - - - C- - -  - - - - - - - - - - - - - zc
                   /
------------------+------------------------------------------------ z1
                 /|
                / V
               /
              O

 m = O - C

To work as a CSG sub-object MUST have a different intersect on the other side and normals must be rigidly attached to geometry (must not depend on ray direction)

Intersect of ray and plane:

r(t) = ray_origin + t * ray_direction

(r(t) - center).d  = ( m + t * n ).d  = 0    <-- at intersections of ray and plane thru center with normal d

t = -m.d / n.d

Consider wiggling center up to z2 and down to z1 (in direction of normal d) n.d is unchanged:

(r(t) - (center+ delta d )).d = 0

(m - delta d ).d + t * n.d = 0

m.d - delta + t* nd = 0

t =  -(m.d + delta) / n.d

  = -m.d/n.d  +- delta/n.d

Intersect is inside disc radius when:

rsq =   (r(t) - center).(r(t) - center) < radius*radius

(m + t n).(m + t n)  <  rr

t*t nn + 2 t nm + mm  <  rr

t ( 2 nm + t nn ) + mm   <  rr

rsq < rr    checkr(from cylinder) is: rsq - rr

Determine whether the t_cand intersect hit after delta-ing is on the upside (normal +Z) or downside (normal -Z) of disc from the sign of the below dot product, allowing determination of the rigid outward normal direction.:

r(t) = ray_origin + t * ray_direction

(r(t_cand) - center).d  = m.d + t_cand n.d

csg_intersect_primitive.h : csg_intersect_cylinder

Hmm supporting cylinder with inner radius directly will add a boatload of cases…:

                 /    /        /
                /    /        /
    +------+   /  . /    +---*--+
    |      |  /   ./     |  /   |
----*------*------/------*-/----*------
    |      |/    /.      |/     |
    |      *    / .      *      |
    |     /|   /  .     /|      |
    |    / |  /   .    / |      |
    +---*--+ /    .   /  +------+
       /    /        /
      /    /        /
     /    /        /

Unless could implement by doing internal to the primitive boolean combination intersects with the full cylinder and inner cylinder. Hmm this just duplicates what CSG difference or intersect with complement would do though… so no point.