int HullToObjectModule::getContourToLineIntersectionIndexed(std::vector<cv::Point> &polygon, cv::Point3f &rline, cv::Point2f &r1, cv::Point2f &r2, int &n1, int &n2) { int i, k1 = 0, k2 = 0, n = polygon.size(); cv::Point2f p1_1, p2_1, p1_2, p2_2, r; bool ready1 = false, ready2 = false, got_same = false; p1_1 = polygon[n1]; p2_1 = polygon[(n1+1 == n ? 0 : n1+1)]; if(lineSegmentIntersection(rline, p1_1, p2_1, r)) got_same = true; n1 = (n1+1 == n ? 0 : n1+1); n2 = (n2-1 == -1) ? n-1 : n2-1; do { if(!ready1) { p1_1 = polygon[n1]; p2_1 = polygon[(n1+1 == n ? 0 : n1+1)]; if(lineSegmentIntersection(rline, p1_1, p2_1, r1)) { ready1 = true; if(got_same) { r2 = r; break; } } else n1 = (n1+1 == n ? 0 : n1+1); k1++; } if(!ready2) { p1_2 = polygon[n2]; p2_2 = polygon[(n2+1 == n ? 0 : n2+1)]; if(lineSegmentIntersection(rline, p1_2, p2_2, r2)) { ready2 = true; if(got_same) { r1 = r; break; } } else n2 = (n2-1 == -1) ? n-1 : n2-1; k2++; } if(k1 > n && k2 > n) //If true, there is a problem break; } while (!ready1 || !ready2); if(k1 > n && k2 > n) //If true, there is a problem return 0; else if(k1 > n || k2 > n) //If true, there is a problem return 1; return 2; }
//Checks for collision of the ship with ground, called from timer.c critical zone int checkCollision(Ship *ship, iArgs input) { //Compare every line from ship structure with file input double shipx[3]; double shipy[3]; MapStructure *mapStructure = input.mapStructure; int n = mapStructure -> n; double *mapx = malloc(n*sizeof(double)); double *mapy = malloc(n*sizeof(double)); double dumpResultx = 0; double dumpResulty = 0; int i = 0; for (i = 0; i < 3; i++) { shipx[i] = ship -> structure[0][i]; shipy[i] = ship -> structure[1][i]; } for (i = 0; i < n; i++) { mapx[i] = (mapStructure -> x)[i]; mapy[i] = (mapStructure -> y)[i]; } //Check landed: bottom points of ship equal to some //Check collision for all possible lines for (i = 0; i < n - 1; i++) { //line 1 if (lineSegmentIntersection(shipx[0], shipy[0], shipx[1], shipy[1], mapx[i], mapy[i], mapx[i+1], mapy[i+1], &dumpResultx, &dumpResulty)) return freeAndQuit(mapx, mapy, 1); //line 2 else if (lineSegmentIntersection(shipx[1], shipy[1], shipx[2], shipy[2], mapx[i], mapy[i], mapx[i+1], mapy[i+1], &dumpResultx, &dumpResulty)) return freeAndQuit(mapx, mapy, 1); //line 3 else if (lineSegmentIntersection(shipx[2], shipy[2], shipx[0], shipy[0], mapx[i], mapy[i], mapx[i+1], mapy[i+1], &dumpResultx, &dumpResulty)) return freeAndQuit(mapx, mapy, 1); } return freeAndQuit(mapx, mapy, 0); }
bool lineSegmentIntersection( const SEGMENT& _seg0, const SEGMENT& _seg1, POINT& _point) { return lineSegmentIntersection(_seg0.p0(),_seg0.p1(),_seg1.p0(),_seg1.p1(),_point); }
int HullToObjectModule::getContourToLineIntersection(std::vector<cv::Point> &polygon, cv::Point3f &rline, cv::Point2f &r1, cv::Point2f &r2, int *n1, int *n2) { int i, ind[3], n = polygon.size(); int num_found = 0; cv::Point2f p1, p2, pts[3]; //Max 4 for a convex polygon (2 in 2 corners) p2 = polygon[n-1]; for(i=0; i<n; i++) { p1 = p2; p2 = polygon[i]; if(lineSegmentIntersection(rline, p1, p2, pts[num_found])) { ind[num_found] = i == 0 ? n-1 : i-1; if(++num_found == 3) break; } } if (num_found == 1) { if(n1 != NULL) *n1 = ind[0]; if(n2 != NULL) *n2 = ind[0]; r1 = pts[0]; return 1; } else if(num_found == 2) { r1 = pts[0]; r2 = pts[1]; if(n1 != NULL) *n1 = ind[0]; if(n2 != NULL) *n2 = ind[1]; return 2; } //If more than two, the intersection repeated a polygon point if( fabs(pts[0].y - pts[1].y) < /*EPS*/1e-8 && fabs(pts[0].x - pts[1].x) < /*EPS*/1e-8) { //Take 1 and 3 r1 = pts[0]; r2 = pts[2]; if(n1 != NULL) *n1 = ind[0]; if(n2 != NULL) *n2 = ind[2]; return 3; } r1 = pts[0]; r2 = pts[1]; if(n1 != NULL) *n1 = ind[0]; if(n2 != NULL) *n2 = ind[1]; return 3; }
//performs testing to see if a possible new edge overlaps any existing edges //function is used in creating the adjacency matrix for the board int overlaps(Board *B, int start, int end) { int x1, y1; int x2, y2; int indS = findIndex(B, start); //extract vertex list indexes int indE = findIndex(B, end); x1 = B->Vertices[indS].x; y1 = B->Vertices[indS].y; x2 = B->Vertices[indE].x; y2 = B->Vertices[indE].y; int x3 = 0; int y3 = 0; int x4 = 0; int y4 = 0; int indTS; int indTE; for (int i = 0; i < B->num; i++) //loop through edges starts { for (int j = 0; j < B->num; j++) //loop through edge ends { indTS = findIndex(B, i); //find index in vertex list indTE = findIndex(B, j); if ((indS != indE) && (indTS != indTE)){ //edge does not start and end on same node if (!((B->edges[start][end] != noArc) || (B->edges[end][start] != noArc))) //edge does not already exists { if (!(((indTS == indS) && (indTE == indE)) || ((indTE == indS) && (indTS == indE)))){//ensure there is no tests for same edge if (((B->edges[i][j] != noArc) || (B->edges[j][i] != noArc))){ //ensure an edge exists between two nodes before looking to calc intersect x3 = B->Vertices[indTS].x; //extract coordinates of line segment for test edge y3 = B->Vertices[indTS].y; x4 = B->Vertices[indTE].x; y4 = B->Vertices[indTE].y; if (lineSegmentIntersection((double)x1, (double)y1, (double)x2, (double)y2, (double)x3, (double)y3, (double)x4, (double)y4)){//determine if two segments intersect return 1; } } } } } } } return 0; }
int lineSegmentPolyIntersections(const P2Vector &points, LineSegment2 line, std::vector<PolyIntersectionInfo> &out) { int count = 0; if (line.v2 < line.v1) { line.flip(); } out.clear(); for (P2Vector::size_type i = 0, l = points.size(); i < l; i++) { P2Vector::size_type j = (i + 1) % l; LineIntersectionInfo e = lineSegmentIntersection(LineSegment2(points[i], points[j]), line); switch (e.iclass) { case INTERSECTION_PL: { out.push_back(PolyIntersectionInfo(INTERSECT_EDGE, e.ipoint, i)); count++; break; } case INTERSECTION_PP: { out.push_back(PolyIntersectionInfo(INTERSECT_VERTEX, e.ipoint, i + e.p2 - 2)); count++; break; } case INTERSECTION_LP: { out.push_back(PolyIntersectionInfo(INTERSECT_VERTEX, e.ipoint, i + e.p2 - 2)); count++; break; } case INTERSECTION_LL: { out.push_back(PolyIntersectionInfo(INTERSECT_EDGE, e.ipoint, i)); count++; break; } case COLINEAR: { int n1 = (int)i, n2 = (int)j; P2 q1 = points[i], q2 = points[j]; if (q2 < q1) { std::swap(q1, q2); std::swap(n1, n2); } if (equal(q1, line.v1)) { out.push_back(PolyIntersectionInfo(INTERSECT_VERTEX, q1, n1)); } else if (q1.x < line.v1.x) { out.push_back(PolyIntersectionInfo(INTERSECT_EDGE, line.v1, i)); } else { out.push_back(PolyIntersectionInfo(INTERSECT_VERTEX, q1, n1)); } if (equal(q2, line.v2)) { out.push_back(PolyIntersectionInfo(INTERSECT_VERTEX, q2, n2)); } else if (line.v2.x < q2.x) { out.push_back(PolyIntersectionInfo(INTERSECT_EDGE, line.v2, i)); } else { out.push_back(PolyIntersectionInfo(INTERSECT_VERTEX, q2, n2)); } count += 2; break; } default: break; } } return count; }
LineIntersectionInfo lineSegmentIntersection(const LineSegment2 &l1, const LineSegment2 &l2) { return lineSegmentIntersection(l1.v1, l1.v2, l2.v1, l2.v2); }