Пример #1
0
static int intersect_poylgon(RAY *Ray, POLYGON *Polyg, DBL *Depth)
{
  DBL x, y, len;
  VECTOR p, d;

  /* Don't test degenerate polygons. */

  if (Test_Flag(Polyg, DEGENERATE_FLAG))
  {
    return(false);
  }

  Increase_Counter(stats[Ray_Polygon_Tests]);

  /* Transform the ray into the polygon space. */

  MInvTransPoint(p, Ray->Initial, Polyg->Trans);

  MInvTransDirection(d, Ray->Direction, Polyg->Trans);

  VLength(len, d);

  VInverseScaleEq(d, len);

  /* Intersect ray with the plane in which the polygon lies. */

  if (fabs(d[Z]) < ZERO_TOLERANCE)
  {
    return(false);
  }

  *Depth = -p[Z] / d[Z];

  if ((*Depth < DEPTH_TOLERANCE) || (*Depth > Max_Distance))
  {
    return(false);
  }

  /* Does the intersection point lie inside the polygon? */

  x = p[X] + *Depth * d[X];
  y = p[Y] + *Depth * d[Y];

  if (in_polygon(Polyg->Data->Number, Polyg->Data->Points, x, y))
  {
    Increase_Counter(stats[Ray_Polygon_Tests_Succeeded]);

    *Depth /= len;

    return (true);
  }
  else
  {
    return (false);
  }
}
Пример #2
0
polygon poly_intersect(polygon &P, polygon &Q){
	int m = Q.size(), n = P.size();
	int a = 0, b = 0, aa = 0, ba = 0, inflag = 0;
	polygon R;
	while( (aa < n || ba < m) && aa < 2*n && ba < 2*m){
		Point p1 = P[a], p2 = P[(a+1) % n], q1 = Q[b], q2 = Q[(b+1) % m];
		Point A = p2 - p1, B = q2 - q1;
		int cross = cmp(A ^ B), ha = turn(p2, q2, p1), hb = turn(q2, p2, q1);
		if(cross == 0 && turn(p1, q1, p2) == 0 && cmp(A * B) < 0){
			if(between(p1, q1, p2)) R.push_back(q1);
			if(between(p1, q2, p2)) R.push_back(q2);
			if(between(q1, p1, q2)) R.push_back(p1);
			if(between(q1, p2, q2)) R.push_back(p2);
			if(R.size() < 2) return polygon();
			inflag = 1; break;
		}else if(cross != 0 && seg_intersect(p1, p2, q1, q2)) {
			if(inflag == 0) aa = ba = 0;
			R.push_back(intersection(p1, p2, q1, q2));
			inflag = (hb > 0) ? 1 : -1;
		}
		if(cross == 0 && hb < 0 && ha < 0) return R;
		bool t = cross == 0 && hb == 0 && ha == 0;
		if(t ? (inflag == 1) : (cross >= 0) ? (ha <= 0) : (hb > 0)){
			if(inflag == -1) R.push_back(q2);
			ba++; b++; b %= m;
		}else{
			if(inflag == 1) R.push_back(p2);
			aa++; a++; a %= n;
		}
	}

	if(inflag == 0){
		if (in_polygon(P[0], Q)) return P;
		if (in_polygon(Q[0], P)) return Q;
	}
	R.erase(unique(R.begin(), R.end()), R.end());
	if(R.size() > 1 && R.front() == R.back()) R.pop_back();
	return R;
}
Пример #3
0
bool Polygon::Intersect(const BasicRay& ray, DBL *Depth, TraceThreadData *Thread) const
{
    DBL x, y, len;
    Vector3d p, d;

    /* Don't test degenerate polygons. */

    if (Test_Flag(this, DEGENERATE_FLAG))
        return(false);

    Thread->Stats()[Ray_Polygon_Tests]++;

    /* Transform the ray into the polygon space. */

    MInvTransPoint(p, ray.Origin, Trans);

    MInvTransDirection(d, ray.Direction, Trans);

    len = d.length();

    d /= len;

    /* Intersect ray with the plane in which the polygon lies. */

    if (fabs(d[Z]) < ZERO_TOLERANCE)
        return(false);

    *Depth = -p[Z] / d[Z];

    if ((*Depth < DEPTH_TOLERANCE) || (*Depth > MAX_DISTANCE))
        return(false);

    /* Does the intersection point lie inside the polygon? */

    x = p[X] + *Depth * d[X];
    y = p[Y] + *Depth * d[Y];

    if (in_polygon(Data->Number, Data->Points, x, y))
    {
        Thread->Stats()[Ray_Polygon_Tests_Succeeded]++;

        *Depth /= len;

        return (true);
    }
    else
        return (false);
}
Пример #4
0
int main(int argc, char *argv[])
{
	srand(time(NULL));
	if (argc != 6)
	{
		std::cout << usage << std::endl;
		return -1;
	}

	int count = atoi(argv[1]);
	double min = atof(argv[2]);
	double max = atof(argv[3]);
	std::ofstream file(argv[4], std::ofstream::out);
	bool integer = false;
	if (strcmp(argv[5], "double") == 0)
		integer = false;
	else if (strcmp(argv[5], "int") == 0)
		integer = true;

	point *ps = new point[count];
	random_points(ps, count, min, max, integer);
	space_partition(ps, count);

	double real_min = 999999;
	double real_max = -999999;
	for (int i = 0; i < count; i++)
	{
		real_max = ps[i].x > real_max ? ps[i].x : real_max;
		real_max = ps[i].y > real_max ? ps[i].y : real_max;
		real_max = ps[i].x < real_min ? ps[i].x : real_min;
		real_max = ps[i].y < real_min ? ps[i].y : real_min;
	}

	point start;
	point end;
	do
	{
		random_points(&start, 1, real_min, real_max, integer);
	} while (!in_polygon(start, ps, count));
	do
	{
		random_points(&end, 1, real_min, real_max, integer);
	} while (!in_polygon(end, ps, count));

	if (integer)
	{
		file << (int)round(start.x) << " " << (int)round(start.y) << " "
			<< (int)round(end.x) << " " << (int)round(end.y) << std::endl;
		file << count << std::endl;
		for (int i = 0; i < count; i++)
			file << (int)round(ps[i].x) << " " << (int)round(ps[i].y) << std::endl;
	}
	else
	{
		file << start.x << " " << start.y << " " << end.x << " " << end.y << std::endl;
		file << count << std::endl;
		for (int i = 0; i < count; i++)
			file << ps[i].x << " " << ps[i].y << std::endl;
	}
	
	delete[] ps;
	return 0;
}
Пример #5
0
//merging of 2 convex hulls
std::vector<Point2D> merge(std::vector<Point2D> set1, std::vector<Point2D> set2)
{

    Point2Df p;
    std::vector<Point2D> sum;
    int is_line1 = is_line(set1);
    int is_line2 = is_line(set2);

    if(!is_line1)
    {
        for(int i = 0; i < set1.size() - 2; i++)
        {
            if(is_left(set1[i], set1[i + 1], set1[i + 2]) != 0)
            {
                p = centroid(set1[i], set1[i + 1], set1[i + 2]);
                break;
            }
        }
    }
    else if(!is_line2)
    {
        for(int i = 0; i < set2.size() - 2; i++)
        {
            if(is_left(set2[i], set2[i + 1], set2[i + 2]) != 0)
            {
                p = centroid(set2[i], set2[i + 1], set2[i + 2]);
                break;
            }
        }
    }

    if(!is_line1 && !is_line2)// 2 polygons
    {
        if(in_polygon(set2, p) != 0)
        {
            sum = merge_polygons(set1, set2, p);
            return graham_scan(sum);

        }
        else
        {
            std::vector<Point2D> clean_set2;

            clean_set2 = delete_chain(set2, p);
            sum = merge_polygons(set1, clean_set2, p);

            return graham_scan(sum);
        }
    }
    else if (!is_line1 && is_line2)//polygon with centroid p and line
    {

        std::vector<Point2D> clean_set2;
       /*
        clean_set2 = delete_chain(set2, p);
        sum = merge_polygons(set1, clean_set2, p);
        */


        if(angle_compare(p, (Point2Df)set2[0], (Point2Df)set2[set2.size() - 1]))
        {
            clean_set2.push_back(set2[0]);
            clean_set2.push_back(set2[set2.size() - 1]);
        }
        else
        {
            clean_set2.push_back(set2[set2.size() - 1]);
            clean_set2.push_back(set2[0]);
        }

        sum = merge_polygons(set1, clean_set2, p);

        return graham_scan(sum);
    }
    else if(is_line1 && !is_line2)
    {
        std::vector<Point2D> clean_set1;
    /*
        clean_set1 = delete_chain(set1, p);
        sum = merge_polygons(clean_set1, set2, p);
    */
        if(angle_compare(p, (Point2Df)set1[0], (Point2Df)set1[set1.size() - 1]))
        {
            clean_set1.push_back(set1[0]);
            clean_set1.push_back(set1[set1.size() - 1]);
        }
        else
        {
            clean_set1.push_back(set1[set1.size() - 1]);
            clean_set1.push_back(set1[0]);
        }

        sum = merge_polygons(clean_set1, set2, p);
        return graham_scan(sum);

    }
    else // if(is_line1 && is_line2)
    {
        std::vector<Point2D> clean_set1;
        clean_set1.push_back(set1[0]);
        clean_set1.push_back(set1[set1.size() - 1]);
        clean_set1.push_back(set2[0]);
        clean_set1.push_back(set2[set2.size() - 1]);
        return get_hull(clean_set1);
    }
}