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;
}
예제 #2
0
void keredgecor (double* h, double* polyx, double* polyy, long int* npoly, double* x, double* y, long int* npoints,
                 long int* Ikernel, long int* rings, long int* denspts, double* edgevec, long int* seed) {

  int i, k, m, ntot;
  double *r, ranoff, theta, ringx, ringy, dpts;

  r    = dvector(*rings);
  dpts = (double) *denspts;
  /* Normal kernel */
  if (*Ikernel==1) for (m=0; m < *rings; m++) r[m] = *h * sqrt(-2* log((m + 0.5)/ *rings));
  /* Quartic kernel */
  if (*Ikernel==2) for (m=0; m < *rings; m++) r[m] = *h * sqrt(8 * ( 1 - exp(log( (m+ 0.5)/ *rings)/ 3 ) ) );

  /* Initialise the random number generator: */
  initran1(*seed);

  for (i=0; i< *npoints; i++) {

    if (!point_in_poly(polyx,polyy,*npoly,x[i],y[i])) edgevec[i]=-1.0; // -1 if point not in polygon
    else {
      edgevec[i]=1.0;
      for (m=0; m<*rings; m++) {  // m=0 is the outermost ring
        ranoff=ran1();
        ntot=0;
        for (k=0; k<*denspts; k++) {
          theta=( ((double) k) - ranoff)/dpts*2.0*PI;
          ringx=x[i]+r[m]*cos(theta);
          ringy=y[i]+r[m]*sin(theta);
          if (point_in_poly(polyx,polyy,*npoly,ringx,ringy)) ntot++;
        }
        if (ntot == *denspts) break;
        else edgevec[i]-=(dpts - ((double) ntot))/((double) ((*denspts)*(*rings)));
      }
    }
  }
  free_dvector(r);
}
예제 #3
0
static void check_collision ( collision_data& coldat )
{
	float radius;

	if ( coldat.BoundingSphere.x == coldat.BoundingSphere.y && coldat.BoundingSphere.x == coldat.BoundingSphere.z )
	{
		radius = coldat.BoundingSphere.x;
	}
	else
	{
		radius = 1.0f;
		
		// scale polygon
		for ( small x = 0; x < cache.count; x++ )
		{
			cache.vertex [ x ].x /= coldat.BoundingSphere.x;
			cache.vertex [ x ].y /= coldat.BoundingSphere.y;
			cache.vertex [ x ].z /= coldat.BoundingSphere.z;
		}

		CalcNormal ( cache.vertex, &cache.normal );
		D3DXVec3Normalize ( &cache.normal, &cache.normal );
	}


    D3DXVECTOR3 r;
    D3DXVECTOR3 pt = cache.vertex [ 0 ];
    D3DXVECTOR3 n  = cache.normal;
    D3DXVECTOR3 s  = coldat.src - n * radius;
	
	float t = D3DXVec3Dot ( &( s - pt ), &n );

    if ( t > coldat.dir_len )
	{
        return;
    }

    if ( t < -2 * radius )
	{
        return;
    }

    if ( t < 0.0f ) 
	{
        if ( !intersect_plane ( s, n * radius, pt, r ) )
			return;
    }
    else 
	{
     	if ( !intersect_plane ( s, coldat.dir, pt, r ) )
			return;
    }

    if ( !point_in_poly ( r ) )
	{
		D3DXVECTOR3 line_dir;
        r = closest_on_poly ( r, &line_dir );
		
		// mj change - sticky collision fix 27/08/02
		D3DXVECTOR3 ndir;
		//D3DXVec3Cross ( &ndir, &coldat.ndir, &line_dir );
		//D3DXVec3Cross ( &ndir, &line_dir, &ndir );
		//D3DXVec3Normalize ( &ndir, &ndir );

		ndir = coldat.ndir;

		t = intersect_sphere ( r, -ndir, coldat.src, radius );
	}
	else
	{
		t = intersect_sphere ( r, -coldat.ndir, coldat.src, radius );
	}

	    if ( t >= 0.0f && t <= coldat.dir_len )
		{
			if ( !coldat.found || t < coldat.dist )
			{
				coldat.found        = true;
				coldat.dist         = t;
				coldat.nearest_poly = r;
        }
    }
}
예제 #4
0
static void
point_in_map_element (char *line, char *return_url, int point_x, int point_y,
                      char *default_url)
{
    char
    **tokens,                       /*  Line split into tokens           */
    *map_type,                      /*  Element type name                */
    *map_url,                       /*  Element URL value                */
    *comma;                         /*  Split x,y at comma               */
    FPOINT
    click_point,                    /*  Request point                    */
    shape_points [MAP_MAX_POINTS];  /*  Array of element point           */
    int
    token_nbr,                      /*  Index into token array           */
    nbr_points;                     /*  Number of points in element      */

    /*  Store selected point in image                                        */
    click_point.x = (double) point_x;
    click_point.y = (double) point_y;

    /*  Now parse the map file line into space-delimited tokens              */
    tokens = tok_split (line);

    /*  Ignore anything which is unparsable                                  */
    if (tokens [0] == NULL || tokens [1] == NULL)
    {
        tok_free (tokens);              /*  Release memory                   */
        return;
    }

    /*  First token is image element type; second is the URL                 */
    map_type = strlwc (tokens [0]);
    map_url  = tokens [1];

    /*  Third to n tokens are x,y pairs...                                   */
    token_nbr = 2;
    for (nbr_points = 0; nbr_points < MAP_MAX_POINTS; nbr_points++)
    {
        if (!tokens [token_nbr])
            break;                      /*  Null token => finished           */
        comma = strchr (tokens [token_nbr], ',');
        if (!comma)
            break;                      /*  Syntax error in line => quit     */
        *comma = '\0';                  /*  Else break into separate x & y   */
        shape_points [nbr_points].x = atof (tokens [token_nbr]);
        shape_points [nbr_points].y = atof (comma + 1);
        token_nbr++;                    /*  Bump to next token               */
    }

    /*  Check element type and test the request point                      */
    if (streq (map_type, "poly"))
    {
        if (point_in_poly (&click_point, shape_points, nbr_points))
            strcpy (return_url, map_url);
    }
    else if (streq (map_type, "circle"))
    {
        if (point_in_circle (&click_point, shape_points))
            strcpy (return_url, map_url);
    }
    else if (streq (map_type, "rect"))
    {
        if (point_in_rect (&click_point, shape_points))
            strcpy (return_url, map_url);
    }
    else if (streq (map_type, "point"))
    {
        double dist;
        dist = ((click_point.x - shape_points [0].x)
                *  (click_point.x - shape_points [0].x))
               + ((click_point.y - shape_points [0].y)
                  *  (click_point.y - shape_points [0].y));
        if (dist < 10)
            strcpy (return_url, map_url);
    }
    else if (streq (map_type, "default"))
        strcpy (default_url, map_url);

    tok_free (tokens);                  /*  Release memory                   */
}