sandbox/tavares/geometrical_tools.h

    Miscalleneous functions

    2D Intersection routine – this function tells if two segments intersect with their coordinates

    int IntersectB(coord A1, coord A2, coord B1, coord B2){
    	coord t1, t2, t3; 
    	foreach_dimension(){
    		t1.x = B2.x-B1.x;
    		t2.x = B1.x-A1.x;
    		t3.x = B1.x-A2.x;
    	}
      double det = ( t2.x*t1.y-t2.y*t1.x ) * ( t3.x*t1.y-t3.y*t1.x );
      int intersection = (det<=0.); //B1B2 cut the segment A1A2
    
      foreach_dimension(){
        t1.x=A2.x-A1.x;
        t2.x=A1.x-B1.x;
        t3.x=A1.x-B2.x;
      }	
      det=( t2.x*t1.y-t2.y*t1.x ) * ( t3.x*t1.y-t3.y*t1.x );
      return intersection = (intersection && (det<=0.) );// A1A2 cut the segment B1B2
    }
    
    
    static inline int Intersect(coord A, coord B, coord C, coord D, coord * I){
      coord t1, t2, t3; 
      foreach_dimension(){
        t1.x = D.x-C.x;
        t2.x = C.x-A.x;
        t3.x = C.x-B.x;
      }
      double det = ( t2.x*t1.y-t2.y*t1.x ) * ( t3.x*t1.y-t3.y*t1.x );
      int intersection = (det<=0.); //B1B2 cut the segment A1A2
    
      foreach_dimension(){
        t1.x=B.x-A.x;
        t2.x=A.x-C.x;
        t3.x=A.x-D.x;
      } 
      det=( t2.x*t1.y-t2.y*t1.x ) * ( t3.x*t1.y-t3.y*t1.x );
      intersection = (intersection && (det<=0.) );// A1A2 cut the segment B1B2
      if (intersection){ // We calculate the intersection between the two segments
      //fprintf(stdout, "in %g %g\n", I.x, I.y );
        foreach_dimension() 
          t2.x = D.x-C.x;
        det = t2.y*t1.x  - t2.x*t1.y; //We use the Cramer method
        double detAB = B.x*A.y - A.x*B.y;
        double detCD = D.x*C.y - C.x*D.y;
        //fprintf(stdout, "in %g %g %g %g %g\n", I.x, I.y, det, detAB, detCD );
        foreach_dimension() 
          I->x = detAB * t2.x - detCD * t1.x / det;
        //fprintf(stdout, "in %g %g\n", I->x, I->y );
        }
      return intersection;
    }

    3D Intersection routine – this function tells if a ray intersects a bounded box (see[http://www.basilisk.fr/sandbox/Antoonvh/bwatch.h#intersections]).

    // A ray class
    typedef struct ray {
      coord O;
      coord dir;
      int   depth;   // for recasted rays
    } ray;
    
    // static inline int ray_box (ray r, coord bb[2]) { //bb is the extent of the box
    //   double in, out;
    //   int intersection;
    //   in = -HUGE; out = HUGE;
    //   foreach_dimension() {
    //     if (r.dir.x > 0) {
    //       in  = max(in,  (bb[0].x - r.O.x)/r.dir.x);
    //       out = min(out, (bb[1].x - r.O.x)/r.dir.x);
    //     } else if (r.dir.x < 0) {
    //       in  = max(in,  (bb[1].x - r.O.x)/r.dir.x);
    //       out = min(out, (bb[0].x - r.O.x)/r.dir.x);
    //     }
    //   }
    //   if (in >= out || out < 0) intersection = 0;
    //     //return HUGE;
    //   //in = in < 0 ? 0 : in; //The origin is in the box.
    //   //return in;
    //   intersection = (in>0);
    //   return intersection;
    // }
    
    
    //static inline double ray_box (ray r, coord bb[2]) { //bb is the extent of the box
    static inline double ray_box (ray r, coord bb[2]) { //bb is the extent of the box
      
      double in, out;
      in = -HUGE; out = HUGE;
      foreach_dimension() {
        if (r.dir.x > 0) {
          in  = max(in,  (bb[0].x - r.O.x)/r.dir.x);
          out = min(out, (bb[1].x - r.O.x)/r.dir.x);
        } else if (r.dir.x < 0) {
          in  = max(in,  (bb[1].x - r.O.x)/r.dir.x);
          out = min(out, (bb[0].x - r.O.x)/r.dir.x);
        }
      }
      if (in >= out || out < 0);
        return HUGE;
      in = in < 0 ? 0 : in; //The origin is in the box.
      //fprintf(fout, "%g\n",in);
      return in;
    }

    This function returns true if there is an intersection between a segment and a facet

    //static inline bool facet_embed_intersect (scalar c, face vector s, scalar f, coord I[2], coord n, coord m, Point point) { 
    //static inline bool facet_embed_intersect (double c, double f, coord n, coord  m, coord I0, Point point) { 
    
    //bool facet_embed_intersect (double c, double f, coord n, coord  m, coord I0, Point point) {   
      int face_embed_intersect (double c, double f, coord n, coord  m, coord It, Point point) {
      coord cc = {x, y, z}; 
      coord a[2];
      double alphan = plane_alpha (f, n);
      double alpham = plane_alpha (c, m);
      //fprintf(stdout, "in %g %g\n", It.x, It.y);
      if (facets (m, alpham, a) >=2) {
        double ALP = 0, ALP2 = 0;
        foreach_dimension() {
          ALP  += n.x*(a[0].x - cc.x)/Delta;
          ALP2 += n.x*(a[1].x - cc.x)/Delta;
        }
        fprintf(stdout, "in %g \n", (ALP2 - alphan)/(ALP - alphan));
        if ((ALP2 - alphan)/(ALP - alphan) > 0.05) // 3% gap filling
          return 0;
        double w = fabs((ALP2 - alphan)) / (fabs(ALP - alphan) + fabs(ALP2 - alphan));
        foreach_dimension() {
          It.x = w*a[0].x + (1 - w)*a[1].x;
        }
        fprintf(stdout, "out %g %g\n", It.x, It.y);
        return 1;
      }
      else 
        return 0;
    }