Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-04-09 07:48:54

0001 #pragma once
0002 
0003 /**
0004 intersect_leaf_halfspace
0005 --------------------------
0006 
0007 Define CSG_HALFSPACE with a unit normal *n* and a distance *w* from the origin
0008 in the normal direction. Hence points *p* that are within the plane fulfil::
0009 
0010    p.n = w
0011 
0012    \  *
0013    +\  *
0014    ++\  *
0015    +++\  *
0016    ++++\  *
0017    +++++\  *
0018    ++++++\  *               n     outwards pointing normal, away from halfspace
0019    +++++++\  *           .
0020    ++++++++\  *       .
0021    +++++++++\  *   .
0022    ++++++++++\  .
0023    +++++++++++O  *
0024    ++++++++++++\  *
0025    +++++++++++++\  *
0026    ++ inside ++++\  *     outside
0027    +++++++++++++++\  *
0028    ++++++++++++++++\  *             +->
0029    +++++++++++++++++\  *            d.n > 0 : direction with normal : heading away from halfspace
0030    ++++++++++++++++++\  *           o.n > w : origin outside halfspace
0031    +++++++++++++++++++\  *          [no isect, dn*(on-w) > 0]
0032    ++++++++++++++++++++\  *
0033    +++++++++++++++++++++\  *        <-+
0034    ++++++++++++++++++++++\  *       d.n < 0 : direction against normal : heading towards halfspace
0035    +++++++++++++++++++++++\  *      o.n > w : origin outside halfspace
0036    ++++++++++++++++++++++++\  *     [poss isect, dn*(on-w) < 0]
0037                             \  *
0038    +->                       \  *
0039    d.n > 0                    \  *
0040    o.n < w                     \  *
0041    [poss isect, dn*(on-w) < 0]  \  *
0042                                  \  *           +
0043    <-+                            \  *           \   d.n = 0     : direction parallel to plane, perpendicular to normal
0044    d.n < 0                         \  *           \  o.n - w > 0 : origin outside halfspace
0045    o.n < w                          \  *             [no isect, no exit at infinity as not inside]
0046    [no isect, dn*(on-w) > 0]         \  *
0047    [exit at infinity]                 \  *
0048                                        \  +
0049                                         \  \      d.n = 0          : d perp to n
0050        +                                 \  \     o.n - w = 0      : o within plane
0051         \                                 \  *    [infinite isects, exit at infinity]
0052          \                                 \  *
0053         d.n = 0     : d perp to n
0054         o.n - w < 0 : o inside
0055         [no isect, exit at infinity]
0056 
0057 
0058 Parametric ray::
0059 
0060      p = o + d t
0061 
0062 
0063 
0064 Intersects of ray with plane::
0065 
0066      p.n = w
0067 
0068      (o + d t).n = w
0069 
0070 
0071                    ( w - o.n )
0072      =>       t =  -------------
0073                       d.n
0074 
0075 
0076 Rays with origin inside the halfspace that are headed
0077 away from the plane cannot intersect with it.
0078 But the CSG intersection algorithm needs to:
0079 
0080 1. classify every ray constituent trial into ENTER/EXIT/MISS
0081 2. every shape needs an "other" side
0082 
0083 This these rays can be regarded to EXIT the halfspace at infinity.
0084 This is an UNBOUNDED_EXIT.
0085 
0086       o.n < w  ,  (on-w) < 0   origin inside halfspace
0087       d.n < 0                  d into halfspace [no isect, exit at infinity]
0088       d.n = 0                  d parallel to plane [no isect, exit at infinity]
0089 
0090       o.n = w  ,  (on-w) = 0   origin on plane
0091       d.n < 0                  d into halfspace [invalid t=0 isect, exit at infinity]
0092       d.n = 0                  d within plane, perp to normal [infinite isect, exit at infinity]
0093 
0094 Can select both the above situations with "<="::
0095 
0096      ( on-w ) <= 0 && dn <= 0
0097 
0098 
0099 
0100 Consider a test halfspace, defined by n [1/sqrt(2), 1/sqrt(2), 0, 0]
0101 The normal points away from the halfspace, so intersecting a cylinder
0102 with axis in z-direction with this expect to get half a cylinder::
0103 
0104            Y
0105    + .     |      n
0106    + + .   |    .
0107    + + + . | .
0108    + + + + 0------X
0109    + + + + +.
0110    + + + + + +.
0111    + + + + + + +.
0112    + + + + + + + +.
0113 
0114 Set GEOM to "LocalPolyconeWithPhiCut" and do the conversion::
0115 
0116     ~/o/g4cx/tests/G4CX_U4TreeCreateCSGFoundryTest.sh
0117 
0118 Viewing that from different positions::
0119 
0120     NOXGEOM=1 EYE=4,0,10 UP=0,1,0 cxr_min.sh                                   # expected half cylinder, with cut side pointing to +x+
0121 
0122     NOXGEOM=1 EYE=0,0,10 EXTENT_FUDGE=2 CAM=orthographic UP=0,1,0 cxr_min.sh   # UNEXPECTED FULL CYLINDER
0123     NOXGEOM=1 EYE=1e-50,0,10 EXTENT_FUDGE=2 CAM=orthographic UP=0,1,0 cxr_min.sh  # UNEXPECTED FULL CYLINDER
0124     NOXGEOM=1 EYE=1e-40,0,10 EXTENT_FUDGE=2 CAM=orthographic UP=0,1,0 cxr_min.sh  # UNEXPECTED FULL CYLINDER
0125     NOXGEOM=1 EYE=1e-37,0,10 EXTENT_FUDGE=2 CAM=orthographic UP=0,1,0 cxr_min.sh  # UNEXPECTED FULL CYLINDER
0126 
0127     NOXGEOM=1 EYE=1e-36,0,10 EXTENT_FUDGE=2 CAM=orthographic UP=0,1,0 cxr_min.sh  # expected half cylinder
0128     NOXGEOM=1 EYE=1e-35,0,10 EXTENT_FUDGE=2 CAM=orthographic UP=0,1,0 cxr_min.sh  # expected half cylinder
0129     NOXGEOM=1 EYE=1e-30,0,10 EXTENT_FUDGE=2 CAM=orthographic UP=0,1,0 cxr_min.sh  # expected half cylinder
0130     NOXGEOM=1 EYE=0.001,0,10 EXTENT_FUDGE=2 CAM=orthographic UP=0,1,0 cxr_min.sh # expected half cylinder
0131     NOXGEOM=1 EYE=0.01,0,10 EXTENT_FUDGE=2 CAM=orthographic UP=0,1,0 cxr_min.sh # expected half cylinder
0132     NOXGEOM=1 EYE=0.1,0,10 EXTENT_FUDGE=2 CAM=orthographic UP=0,1,0 cxr_min.sh # expected half cylinder
0133     NOXGEOM=1 EYE=0.2,0,10 EXTENT_FUDGE=2 CAM=orthographic UP=0,1,0 cxr_min.sh # expected half cylinder
0134     NOXGEOM=1 EYE=0.5,0,10 EXTENT_FUDGE=2 CAM=orthographic UP=0,1,0 cxr_min.sh # expected half cylinder
0135     NOXGEOM=1 EYE=1,0,10 EXTENT_FUDGE=2 CAM=orthographic UP=0,1,0 cxr_min.sh   # expected half cylinder
0136     NOXGEOM=1 EYE=4,0,10 EXTENT_FUDGE=2 CAM=orthographic UP=0,1,0 cxr_min.sh   # expected half cylinder
0137     NOXGEOM=1 EYE=20,0,10 EXTENT_FUDGE=2 CAM=orthographic UP=0,1,0 cxr_min.sh  # still expected
0138 
0139 
0140 After using eps 1e-7 gets worse::
0141 
0142     NOXGEOM=1 EYE=1e-6,0,10 EXTENT_FUDGE=2 CAM=orthographic UP=0,1,0 cxr_min.sh   # UNEXPECTED FULL CYLINDER
0143     NOXGEOM=1 EYE=1e-5,0,10 EXTENT_FUDGE=2 CAM=orthographic UP=0,1,0 cxr_min.sh   # expected half cylinder
0144 
0145 Tweaking, not much diff::
0146 
0147     NOXGEOM=1 EYE=1e-8,0,10 EXTENT_FUDGE=2 CAM=orthographic UP=0,1,0 cxr_min.sh   # UNEXPECTED FULL CYLINDER
0148     NOXGEOM=1 EYE=1,0,10 EXTENT_FUDGE=2 CAM=orthographic UP=0,1,0 cxr_min.sh   # expected half cylinder
0149 
0150 Proceed to CSG/tests/csg_intersect_prim_test.sh which so far has not reproduced the issue.
0151 
0152 **/
0153 
0154 
0155 LEAF_FUNC
0156 void intersect_leaf_halfspace( bool& valid_isect, float4& isect, const quad& q0, const float t_min, const float3& o, const float3& d )
0157 {
0158     float3 n = make_float3(q0.f.x, q0.f.y, q0.f.z);
0159     float w = q0.f.w;
0160 
0161     float on = dot(o,n);
0162     float dn = dot(d,n);
0163     float on_w = on - w;
0164     float adn = fabsf(dn);
0165 
0166     float eps = 1e-9f;
0167     bool inside = on_w < -eps ;
0168 
0169     float t = adn > 0.f ? -on_w / dn : t_min ;
0170     valid_isect = t > t_min ;
0171 
0172     if (valid_isect)
0173     {
0174         isect.x = n.x ;
0175         isect.y = n.y ;
0176         isect.z = n.z ;
0177         isect.w = t ;
0178     }
0179     else
0180     {
0181         if (inside)
0182         {
0183             isect.y = -0.f;
0184         }
0185     }
0186 
0187 #ifdef DEBUG_HALFSPACE
0188     bool yflip = valid_isect == false && isect.y == -0.f ;
0189     printf("//intersect_leaf_halfspace n [%8.3f,%8.3f,%8.3f,%8.3f] o [%8.3f,%8.3f,%8.3f] d[%8.3f,%8.3f,%8.3f] on/dn/on_w/adn [%8.3f,%8.3f,%8.3f,%8.3f] t %8.3f valid_isect %d inside %d yflip %d \n",
0190           n.x, n.y, n.z, w, o.x, o.y, o.z, d.x, d.y, d.z, on,dn,on_w,adn,eps,t, valid_isect, inside, yflip);
0191 #endif
0192 
0193 }
0194