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); } }
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; }
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); }
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; }
//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); } }