bool circle3points( const xy& a, const xy& b, const xy& c, double& eps, circle& res)
{
  if (std::abs(left(a,b,c))<=eps) return false;
  line l1(a, b, false);
  line l2(b, c, false);
  line pl1; pl1.upper = a + (b-a)/2; pl1.lower = pl1.s + l1.normal();
  line pl2; pl2.upper = b + (c-b)/2; pl2.e = pl2.s + l2.normal();
  bool overlap;
  intersect_line(pl2,pl1, eps, res.c, overlap);
  res.r = dist(res.c, a);
  return true;
}
int intersect_polygon(Point *poly1, int n1, Point *poly2, int n2,
		      Point **out){
  Point *newpoly, p; char *used;
  int new_n = n1 + n2 + n1*n2;
  int count, i, j, new_count, n;
  
  newpoly = (Point *)malloc(new_n * sizeof(Point));
  *out    = (Point *)malloc(new_n * sizeof(Point));
  used    =          malloc(new_n * sizeof(Point));
  /* assert(newpoly && *out && used); */

  for (count = i = 0; i < new_n; i++) used[i] = 0;

  for (i = 0; i < n1; i++)
    if (point_in_poly(poly2, n2, poly1[i]))
      newpoly[count++] = poly1[i];
  
  for (i = 0; i < n2; i++) 
    if (point_in_poly(poly1, n1, poly2[i]))
      newpoly[count++] = poly2[i];

  for (i = 0; i < n1; i++) for (j = 0; j < n2; j++)
    if (intersect_line(poly1[i], poly1[(i+1)%n1],
		       poly2[j], poly2[(j+1)%n2], &p) == 1)
      newpoly[count++] = p;
  
  if (count >= 3) {
    n = convex_hull(newpoly, count, *out);
    if (n < 3) {
      free(*out);
      n = 0;
    }
  } else {
    free(*out);
    n = 0;
  }
  
  /* eliminate duplicates */
  for (i = 0; i < n-1; i++)
    for (j = i+1; j < n; j++)
      if ((*out)[i].x == (*out)[j].x &&
	  (*out)[i].y == (*out)[j].y)
        used[j] = 1;
  
  new_count = 0;
  for (i = 0; i < n; i++)
    if (!used[i]) (*out)[new_count++] = (*out)[i];
  n = new_count;
  free(used);
  free(newpoly);
  return n;
}
int main(){
  Point a, b, c, d, p; int res;
  
  while (scanf("%lf %lf %lf %lf %lf %lf %lf %lf",
       &a.x, &a.y, &b.x, &b.y, &c.x, &c.y, &d.x, &d.y) == 8) {
    res = intersect_line(a, b, c, d, &p);
    if (res == 1) {
      printf("Intersect at (%0.2f, %0.2f)\n", p.x, p.y);
    } else if (res == 0) {
      printf("Don't intersect\n");
    } else {
      printf("Infinite number of intersections\n");
    }
  }
  return 0;
}
Exemple #4
0
//
// private method that calculates the intersection points between
// line segments.
//
void 
dxfLineSegment::calculate_connect(dxfLineSegment *next)
{
  if (!(this->flags & FLAG_CONNECT_CALCULATED)) {
    this->calculate_v(); /* make sure these are caluclated */
    next->calculate_v();
    
    dxfdouble angle = this->dir.angle(next->dir);

    //
    // from the dxf specification. If angle > 28, use line
    // intersection even if widths are unequal
    //
    if ((this->w[1] == next->w[0]) || (DXFRAD2DEG(angle) > 28)) {
      // connect where lines intersect. common intersection points      
      dimeVec3f isect;
      intersect_line(this->v[0], this->v[1], 
		     next->v[0], next->v[1],
		     isect);
      this->connect[0] = this->connect[2] = isect;

      intersect_line(this->v[2], this->v[3], 
		     next->v[2], next->v[3],
		     isect);
      this->connect[1] = this->connect[3] = isect;
    }
    else {
      dimeVec3f vec = this->wdir + next->wdir + this->p[1];
      
      dimeVec3f isect;
      intersect_line(this->v[0], this->v[1],
		     this->p[1], vec,
		     isect);
      this->connect[0] = isect;
      
      intersect_line(next->v[0], next->v[1],
		     this->p[1], vec,
		     isect);
      this->connect[2] = isect;

      intersect_line(this->v[2], this->v[3],
		     this->p[1], vec,
		     isect);
      this->connect[1] = isect;

      intersect_line(next->v[2], next->v[3],
		     this->p[1], vec,
		     isect);
      this->connect[3] = isect;
    }
    this->flags |= FLAG_CONNECT_CALCULATED;
  }
}
void find_intersection_tetra(Tetra *tetra, double isovalue,
                             Tetra_point *tetra_point,
                             Head_patch_tetra *head_patch_tetra,
                             Hash_vertex *vertex_hash_table) {
  int i, j, k;
  int num_gt_0, v0_id;
  int tmp_int;
  double point[3], color;
  Hash_vertex *h1, *h2;
  Tetra_point *p1, *p2;
  Patch_tetra *t1, *t2;
  int flag_existing, index_patch, patch[4];
  int v1, v2, v[4], count_minus, count_plus;
  double fp[4][3], n_f[3], n_norm, f_cen_point[3], sign_f, n_c, c_c[3];
  num_gt_0 = 0;
  for (i = 0; i < 4; i++) {
    if (tetra->s_data[i] > isovalue) num_gt_0++;
  }

  if ((num_gt_0 != 0) &&
      (num_gt_0 != 4)) { /* There are patches inside the tetra */

    if ((num_gt_0 == 1) ||
        (num_gt_0 == 3)) { /* There is one patch inside the tetra */
      t1 = (Patch_tetra *)HECMW_malloc(sizeof(Patch_tetra));
      if (t1 == NULL) HECMW_vis_memory_exit("t1");
      t2 = head_patch_tetra->patch_link;
      head_patch_tetra->num_patch++;
      head_patch_tetra->patch_link = t1;
      t1->next_patch               = t2;

      if (num_gt_0 == 1) {
        v0_id = -1;
        for (i = 0; i < 4; i++) {
          if (tetra->s_data[i] > isovalue) v0_id = i;
        }
      } else if (num_gt_0 == 3) {
        v0_id = -1;
        for (i = 0; i < 4; i++) {
          if (tetra->s_data[i] <= isovalue) v0_id = i;
        }
      }
      /* find intersection */
      index_patch = -1;
      for (i = 0; i < 4; i++) {
        if (i != v0_id) {
          color   = intersect_line(v0_id, i, isovalue, tetra, point);
          tmp_int = tetra->local_vid[v0_id] + tetra->local_vid[i];
          /*					if(vertex_hash_table[tmp_int].ident==0)
          {
                  vertex_hash_table[tmp_int].ident++;
                  h1=(Hash_vertex *)HECMW_malloc(sizeof(Hash_vertex));
                  if(h1==NULL)
                          HECMW_vis_memory_exit("h1");
              vertex_hash_table[tmp_int].next_vertex=h1;
                  h1->next_vertex=NULL;
                  h1->ident=tetra_point->ident;
                  for(j=0;j<3;j++)
                          h1->geom[j]=point[j];
                  p1=(Tetra_point *)HECMW_malloc(sizeof(Tetra_point));
                  if(p1==NULL)
                          HECMW_vis_memory_exit("p1");
                  tetra_point->ident++;
                  p2=tetra_point->nextpoint;
                  tetra_point->nextpoint=p1;
                  p1->cdata=color;
                  p1->ident=tetra_point->ident-1;
                  for(j=0;j<3;j++)
                          p1->geom[j]=point[j];
                  p1->nextpoint=p2;
                  index_patch++;
                  t1->patch[index_patch]=p1->ident;
          }
          else if(vertex_hash_table[tmp_int].ident>0) { */
          flag_existing = 0;
          h1            = vertex_hash_table[tmp_int].next_vertex;
          for (j = 0; j < vertex_hash_table[tmp_int].ident; j++) {
            if ((fabs(h1->geom[0] - point[0]) < EPSILON) &&
                (fabs(h1->geom[1] - point[1]) < EPSILON) &&
                (fabs(h1->geom[2] - point[2]) < EPSILON)) {
              flag_existing = 1;
              index_patch++;
              patch[index_patch] = h1->ident;
              for (k = 0; k < 3; k++) fp[index_patch][k] = point[k];
              break;
            }
            h1 = h1->next_vertex;
          }
          if (flag_existing == 0) { /*adding new vertex */
            vertex_hash_table[tmp_int].ident++;
            h1 = (Hash_vertex *)HECMW_malloc(sizeof(Hash_vertex));
            if (h1 == NULL) HECMW_vis_memory_exit("h1");
            h2 = vertex_hash_table[tmp_int].next_vertex;
            vertex_hash_table[tmp_int].next_vertex = h1;
            h1->next_vertex                        = h2;
            h1->ident                              = tetra_point->ident;
            for (j = 0; j < 3; j++) h1->geom[j] = point[j];
            p1 = (Tetra_point *)HECMW_malloc(sizeof(Tetra_point));
            if (p1 == NULL) HECMW_vis_memory_exit("p1");
            tetra_point->ident++;
            p2                     = tetra_point->nextpoint;
            tetra_point->nextpoint = p1;
            p1->cdata              = color;
            p1->ident              = tetra_point->ident - 1;
            for (j = 0; j < 3; j++) p1->geom[j] = point[j];
            p1->nextpoint                       = p2;
            index_patch++;
            patch[index_patch] = p1->ident;
            for (k = 0; k < 3; k++) fp[index_patch][k] = point[k];
          }
                                        /*					}
					 */				}

      } /* end for 0, 4 */
      /*  judge whether the rotation direction pointed out to isosurface */

      n_f[0] = (fp[1][1] - fp[0][1]) * (fp[2][2] - fp[0][2]) -
               (fp[2][1] - fp[0][1]) * (fp[1][2] - fp[0][2]);
      n_f[1] = -(fp[1][0] - fp[0][0]) * (fp[2][2] - fp[0][2]) +
               (fp[2][0] - fp[0][0]) * (fp[1][2] - fp[0][2]);
      n_f[2] = (fp[1][0] - fp[0][0]) * (fp[2][1] - fp[0][1]) -
               (fp[2][0] - fp[0][0]) * (fp[1][1] - fp[0][1]);
      for (j = 0; j < 3; j++) fp[3][j] = tetra->axis[v0_id * 3 + j];
      n_norm = sqrt(n_f[0] * n_f[0] + n_f[1] * n_f[1] + n_f[2] * n_f[2]);
      if (fabs(n_norm) > EPSILON) {
        for (j = 0; j < 3; j++) n_f[j] /= n_norm;
      }
      /*selce the direction point to inside the element */
      for (j           = 0; j < 3; j++)
        f_cen_point[j] = (fp[0][j] + fp[1][j] + fp[2][j]) / 3.0;
      for (j = 0; j < 3; j++) c_c[j] = fp[3][j] - f_cen_point[j];
      n_c = sqrt(c_c[0] * c_c[0] + c_c[1] * c_c[1] + c_c[2] * c_c[2]);
      if (fabs(n_c) > EPSILON) {
        for (j = 0; j < 3; j++) c_c[j] /= n_c;
      }
      sign_f = n_f[0] * c_c[0] + n_f[1] * c_c[1] + n_f[2] * c_c[2];
      if (((tetra->s_data[v0_id] > isovalue) && (sign_f < -EPSILON)) ||
          ((tetra->s_data[v0_id] <= isovalue) && (sign_f > EPSILON))) {
        tmp_int  = patch[1];
        patch[1] = patch[2];
        patch[2] = tmp_int;
      }
      for (j = 0; j < 3; j++) t1->patch[j] = patch[j];

    } /* end if (num_gt_0==1 or 3) */

    else if (num_gt_0 == 2) { /* Two patches inside the tetra */
      index_patch = -1;
      count_minus = 0;
      count_plus  = 0;
      for (i = 0; i < 4; i++) {
        if (tetra->s_data[i] <= isovalue) {
          v[count_minus] = i;
          count_minus++;
        } else {
          v[2 + count_plus] = i;
          count_plus++;
        }
      }
#ifdef old
      /*   judge the tetrahedra whether in the right rotation side */
      for (i = 0; i < 4; i++)
        for (j = 0; j < 3; j++) fp[i][j] = tetra->axis[v[i] * 3 + j];
      n_f[0] = (fp[2][1] - fp[1][1]) * (fp[1][2] - fp[0][2]) -
               (fp[1][1] - fp[0][1]) * (fp[2][2] - fp[1][2]);
      n_f[1] = -(fp[2][0] - fp[1][0]) * (fp[1][2] - fp[0][2]) +
               (fp[1][0] - fp[0][0]) * (fp[2][2] - fp[1][2]);
      n_f[2] = (fp[2][0] - fp[1][0]) * (fp[1][1] - fp[0][1]) -
               (fp[1][0] - fp[0][0]) * (fp[2][1] - fp[1][1]);
      n_norm = sqrt(n_f[0] * n_f[0] + n_f[1] * n_f[1] + n_f[2] * n_f[2]);
      if (fabs(n_norm) > EPSILON) {
        for (j = 0; j < 3; j++) n_f[j] /= n_norm;
      }
      /*selce the direction point to inside the element */
      for (j           = 0; j < 3; j++)
        f_cen_point[j] = (fp[0][j] + fp[1][j] + fp[2][j]) / 3.0;
      for (j = 0; j < 3; j++) c_c[j] = fp[3][j] - f_cen_point[j];
      n_c = sqrt(c_c[0] * c_c[0] + c_c[1] * c_c[1] + c_c[2] * c_c[2]);
      if (fabs(n_c) > EPSILON) {
        for (j = 0; j < 3; j++) c_c[j] /= n_c;
      }
      sign_f = n_f[0] * c_c[0] + n_f[1] * c_c[1] + n_f[2] * c_c[2];
      if (sign_f < -EPSILON) {
        tmp_int = v[2];
        v[2]    = v[3];
        v[3]    = tmp_int;
      }
#endif

      for (i = 0; i < 4; i++) {
        if (i == 0) {
          v1 = v[0];
          v2 = v[2];
        } else if (i == 1) {
          v1 = v[1];
          v2 = v[2];
        } else if (i == 2) {
          v1 = v[1];
          v2 = v[3];
        } else if (i == 3) {
          v1 = v[0];
          v2 = v[3];
        }

        color   = intersect_line(v1, v2, isovalue, tetra, point);
        tmp_int = tetra->local_vid[v1] + tetra->local_vid[v2];
        /*					if(vertex_hash_table[tmp_int].ident==0)
           {
                        vertex_hash_table[tmp_int].ident++;
                        h1=(Hash_vertex *)HECMW_malloc(sizeof(Hash_vertex));
                        if(h1==NULL)
                                HECMW_vis_memory_exit("h1");
                    vertex_hash_table[tmp_int].next_vertex=h1;
                        h1->next_vertex=NULL;
                        h1->ident=tetra_point->ident;
                        for(j=0;j<3;j++)
                                h1->geom[j]=point[j];
                        p1=(Tetra_point *)HECMW_malloc(sizeof(Tetra_point));
                        if(p1==NULL)
                                HECMW_vis_memory_exit("p1");
                        tetra_point->ident++;
                        p2=tetra_point->nextpoint;
                        tetra_point->nextpoint=p1;
                        p1->cdata=color;
                        p1->ident=tetra_point->ident-1;
                        for(j=0;j<3;j++)
                                p1->geom[j]=point[j];
                        p1->nextpoint=p2;
                        index_patch++;
                        patch[index_patch]=p1->ident;
                }
                else if(vertex_hash_table[tmp_int].ident>0) {
         */
        flag_existing = 0;
        h1            = vertex_hash_table[tmp_int].next_vertex;
        for (j = 0; j < vertex_hash_table[tmp_int].ident; j++) {
          if ((fabs(h1->geom[0] - point[0]) < EPSILON) &&
              (fabs(h1->geom[1] - point[1]) < EPSILON) &&
              (fabs(h1->geom[2] - point[2]) < EPSILON)) {
            flag_existing = 1;
            index_patch++;
            patch[index_patch] = h1->ident;
            for (k = 0; k < 3; k++) fp[index_patch][k] = point[k];
            break;
          }
          h1 = h1->next_vertex;
        }
        if (flag_existing == 0) { /*adding new vertex */
          vertex_hash_table[tmp_int].ident++;
          h1 = (Hash_vertex *)HECMW_malloc(sizeof(Hash_vertex));
          if (h1 == NULL) HECMW_vis_memory_exit("h1");
          h2 = vertex_hash_table[tmp_int].next_vertex;
          vertex_hash_table[tmp_int].next_vertex = h1;
          h1->next_vertex                        = h2;
          h1->ident                              = tetra_point->ident;
          for (j = 0; j < 3; j++) h1->geom[j] = point[j];
          p1 = (Tetra_point *)HECMW_malloc(sizeof(Tetra_point));
          if (p1 == NULL) HECMW_vis_memory_exit("p1");
          tetra_point->ident++;
          p2                     = tetra_point->nextpoint;
          tetra_point->nextpoint = p1;
          p1->cdata              = color;
          p1->ident              = tetra_point->ident - 1;
          for (j = 0; j < 3; j++) p1->geom[j] = point[j];
          p1->nextpoint                       = p2;
          index_patch++;
          patch[index_patch] = p1->ident;
          for (k = 0; k < 3; k++) fp[index_patch][k] = point[k];
          /*						}
          }
           */
        }
      } /* end for i*/

      /*  judge whether the rotation direction pointed out to isosurface */

      n_f[0] = (fp[1][1] - fp[0][1]) * (fp[2][2] - fp[0][2]) -
               (fp[2][1] - fp[0][1]) * (fp[1][2] - fp[0][2]);
      n_f[1] = -(fp[1][0] - fp[0][0]) * (fp[2][2] - fp[0][2]) +
               (fp[2][0] - fp[0][0]) * (fp[1][2] - fp[0][2]);
      n_f[2] = (fp[1][0] - fp[0][0]) * (fp[2][1] - fp[0][1]) -
               (fp[2][0] - fp[0][0]) * (fp[1][1] - fp[0][1]);
      for (j = 0; j < 3; j++) fp[3][j] = tetra->axis[0 * 3 + j];
      n_norm = sqrt(n_f[0] * n_f[0] + n_f[1] * n_f[1] + n_f[2] * n_f[2]);
      if (fabs(n_norm) > EPSILON) {
        for (j = 0; j < 3; j++) n_f[j] /= n_norm;
      }
      /*selce the direction point to inside the element */
      for (j           = 0; j < 3; j++)
        f_cen_point[j] = (fp[0][j] + fp[1][j] + fp[2][j]) / 3.0;
      for (j = 0; j < 3; j++) c_c[j] = fp[3][j] - f_cen_point[j];
      n_c = sqrt(c_c[0] * c_c[0] + c_c[1] * c_c[1] + c_c[2] * c_c[2]);
      if (fabs(n_c) > EPSILON) {
        for (j = 0; j < 3; j++) c_c[j] /= n_c;
      }
      sign_f = n_f[0] * c_c[0] + n_f[1] * c_c[1] + n_f[2] * c_c[2];
      if (((tetra->s_data[0] > isovalue) && (sign_f < -EPSILON)) ||
          ((tetra->s_data[0] <= isovalue) && (sign_f > EPSILON))) {
        tmp_int  = patch[1];
        patch[1] = patch[3];
        patch[3] = tmp_int;
      }

      t1 = (Patch_tetra *)HECMW_malloc(sizeof(Patch_tetra));
      if (t1 == NULL) HECMW_vis_memory_exit("t1");
      t2 = head_patch_tetra->patch_link;
      head_patch_tetra->num_patch++;
      head_patch_tetra->patch_link = t1;
      t1->next_patch               = t2;
      for (j = 0; j < 3; j++) t1->patch[j] = patch[j];
      t1 = (Patch_tetra *)HECMW_malloc(sizeof(Patch_tetra));
      if (t1 == NULL) HECMW_vis_memory_exit("t1");
      t2 = head_patch_tetra->patch_link;
      head_patch_tetra->num_patch++;
      head_patch_tetra->patch_link = t1;
      t1->next_patch               = t2;
      t1->patch[0]                 = patch[0];
      t1->patch[1]                 = patch[2];
      t1->patch[2]                 = patch[3];

    } /* end if (num_gt_0==2) */
  }
  return;
}