void AdvancingFront::computeIntersectionBetweenRedAndBlue(dolfin::Mesh * red_mesh, dolfin::Mesh * blue_mesh, int red, int blue, double * P, int & nP, int mark[3]) { // the points will be at most 9; they will describe a convex patch, after the points will be ordered and // collapsed (eliminate doubles) // the area is not really required double redTriangle[6];// column wise double blueTriangle[6]; getXYcoords(blue_mesh, blue, blueTriangle); getXYcoords(red_mesh, red, redTriangle); //we do not really need the mortar matrix //int n[3]={0, 0, 0};// no intersection of side red with blue //double area= 0.; // X corresponds to blue, Y to red nP = 0; // number of intersection points int ret = EdgeIntersections2(blueTriangle, redTriangle, mark, P, nP); int extraPoints = borderPointsOfXinY2(blueTriangle, redTriangle, &(P[2 * nP])); if (extraPoints > 1) { mark[0] = mark[1] = mark[2] = 1; } nP += extraPoints; extraPoints = borderPointsOfXinY2(redTriangle, blueTriangle, &(P[2 * nP])); nP += extraPoints; // now sort and orient the points in P, such that they are forming a convex polygon // this will be the foundation of our new mesh // SortAndRemoveDoubles2(P, nP); // nP should be at most 6 in the end // if there are more than 3 points, some area will be positive }
/* the elements are convex for sure, then do a gnomonic projection of both, * compute intersection in the plane, then go back to the sphere for the points * */ int Intx2MeshOnSphere::computeIntersectionBetweenRedAndBlue(EntityHandle red, EntityHandle blue, double * P, int & nP, double & area, int markb[MAXEDGES], int markr[MAXEDGES], int & nsBlue, int & nsRed, bool check_boxes_first) { // the points will be at most 40; they will describe a convex patch, after the points will be ordered and // collapsed (eliminate doubles) // the area is not really required, except to see if it is greater than 0 // gnomonic projection // int plane = 0; // get coordinates of the red quad, to decide the gnomonic plane int num_nodes; ErrorCode rval = mb->get_connectivity(red, redConn, num_nodes); if (MB_SUCCESS != rval ) return 1; nsRed = num_nodes; //CartVect coords[4]; rval = mb->get_coords(redConn, num_nodes, &(redCoords[0][0])); if (MB_SUCCESS != rval) return 1; CartVect middle = redCoords[0]; for (int i=1; i<nsRed; i++) middle += redCoords[i]; middle = 1./nsRed * middle; decide_gnomonic_plane(middle, plane);// output the plane //CartVect bluecoords[4]; rval = mb->get_connectivity(blue, blueConn, num_nodes); if (MB_SUCCESS != rval ) return 1; nsBlue = num_nodes; rval = mb->get_coords(blueConn, nsBlue, &(blueCoords[0][0])); if (MB_SUCCESS != rval) return 1; if (dbg_1) { std::cout << "red " << mb->id_from_handle(red) << "\n"; for (int j = 0; j < nsRed; j++) { std::cout << redCoords[j] << "\n"; } std::cout << "blue " << mb->id_from_handle(blue) << "\n"; for (int j = 0; j < nsBlue; j++) { std::cout << blueCoords[j] << "\n"; } mb->list_entities(&red, 1); mb->list_entities(&blue, 1); std::cout << "middle " << middle << " plane:" << plane << "\n"; } area = 0.; nP = 0; // number of intersection points we are marking the boundary of blue! if (check_boxes_first) { // look at the boxes formed with vertices; if they are far away, return false early if (!GeomUtil::bounding_boxes_overlap(redCoords, nsRed, blueCoords, nsBlue, box_error)) return 0; // no error, but no intersection, decide early to get out } for (int j = 0; j < nsRed; j++) { // populate coords in the plane for intersection // they should be oriented correctly, positively int rc = gnomonic_projection(redCoords[j], R, plane, redCoords2D[2 * j], redCoords2D[2 * j + 1]); if (rc != 0) return 1; } for (int j=0; j<nsBlue; j++) { int rc = gnomonic_projection(blueCoords[j], R, plane, blueCoords2D[2 * j], blueCoords2D[2 * j + 1]); if (rc != 0) return 1; } if (dbg_1) { std::cout << "gnomonic plane: " << plane << "\n"; std::cout << " red blue\n"; for (int j = 0; j < nsRed; j++) { std::cout << redCoords2D[2 * j] << " " << redCoords2D[2 * j + 1] << "\n"; } for (int j = 0; j < nsBlue; j++) { std::cout << blueCoords2D[2 * j] << " " << blueCoords2D[2 * j + 1] << "\n"; } } int ret = EdgeIntersections2(blueCoords2D, nsBlue, redCoords2D, nsRed, markb, markr, P, nP); if (ret != 0) return 1; // some unforeseen error int side[MAXEDGES] = { 0 };// this refers to what side? blue or red? int extraPoints = borderPointsOfXinY2(blueCoords2D, nsBlue, redCoords2D, nsRed, &(P[2 * nP]), side); if (extraPoints >= 1) { for (int k = 0; k < nsBlue; k++) { if (side[k]) { // this means that vertex k of blue is inside convex red; mark edges k-1 and k in blue, // as being "intersected" by red; (even though they might not be intersected by other edges, // the fact that their apex is inside, is good enough) markb[k] = 1; markb[(k + nsBlue-1) % nsBlue] = 1; // it is the previous edge, actually, but instead of doing -1, it is // better to do modulo +3 (modulo 4) // null side b for next call side[k]=0; } } } nP += extraPoints; extraPoints = borderPointsOfXinY2(redCoords2D, nsRed, blueCoords2D, nsBlue, &(P[2 * nP]), side); if (extraPoints >= 1) { for (int k = 0; k < nsRed; k++) { if (side[k]) { // this is to mark that red edges k-1 and k are intersecting blue markr[k] = 1; markr[(k + nsRed-1) % nsRed] = 1; // it is the previous edge, actually, but instead of doing -1, it is // better to do modulo +3 (modulo 4) // null side b for next call } } } nP += extraPoints; // now sort and orient the points in P, such that they are forming a convex polygon // this will be the foundation of our new mesh // this works if the polygons are convex SortAndRemoveDoubles2(P, nP, epsilon_1); // nP should be at most 8 in the end ? // if there are more than 3 points, some area will be positive if (nP >= 3) { for (int k = 1; k < nP - 1; k++) area += area2D(P, &P[2 * k], &P[2 * k + 2]); } return 0; // no error }
/* the elements are convex for sure, then do a gnomonic projection of both, * compute intersection in the plane, then go back to the sphere for the points * */ int IntxRllCssphere::computeIntersectionBetweenRedAndBlue(EntityHandle red, EntityHandle blue, double * P, int & nP, double & area, int markb[MAXEDGES], int markr[MAXEDGES], int & nsBlue, int & nsRed, bool check_boxes_first) { // the area will be used from now on, to see how well we fill the red cell with polygons // the points will be at most 40; they will describe a convex patch, after the points will be ordered and // collapsed (eliminate doubles) //CartVect bluecoords[4]; int num_nodes=0; ErrorCode rval = mb->get_connectivity(blue, blueConn, num_nodes); if (MB_SUCCESS != rval ) return 1; nsBlue = num_nodes; rval = mb->get_coords(blueConn, nsBlue, &(blueCoords[0][0])); if (MB_SUCCESS != rval) return 1; // determine the type of edge: const lat or not? // just look at the consecutive z coordinates for the edge for (int i=0; i<nsBlue; i++) { int nexti=(i+1)%nsBlue; if ( fabs(blueCoords[i][2]- blueCoords[nexti][2]) < 1.e-6 ) blueEdgeType[i]=1; else blueEdgeType[i]=0; } area = 0.; nP = 0; // number of intersection points we are marking the boundary of blue! if (check_boxes_first) { // look at the boxes formed with vertices; if they are far away, return false early // make sure the red is setup already setup_red_cell(red, nsRed); // we do not need area here if (!GeomUtil::bounding_boxes_overlap(redCoords, nsRed, blueCoords, nsBlue, box_error)) return 0; // no error, but no intersection, decide early to get out } if (dbg_1) { std::cout << "red " << mb->id_from_handle(red) << "\n"; for (int j = 0; j < nsRed; j++) { std::cout << redCoords[j] << "\n"; } std::cout << "blue " << mb->id_from_handle(blue) << "\n"; for (int j = 0; j < nsBlue; j++) { std::cout << blueCoords[j] << "\n"; } mb->list_entities(&red, 1); mb->list_entities(&blue, 1); } for (int j=0; j<nsBlue; j++) { int rc = gnomonic_projection(blueCoords[j], R, plane, blueCoords2D[2 * j], blueCoords2D[2 * j + 1]); if (rc != 0) return 1; } if (dbg_1) { std::cout << "gnomonic plane: " << plane << "\n"; std::cout << " red blue\n"; for (int j = 0; j < nsRed; j++) { std::cout << redCoords2D[2 * j] << " " << redCoords2D[2 * j + 1] << "\n"; } for (int j = 0; j < nsBlue; j++) { std::cout << blueCoords2D[2 * j] << " " << blueCoords2D[2 * j + 1] << "\n"; } } int ret = EdgeIntxRllCs(blueCoords2D, blueCoords, blueEdgeType, nsBlue, redCoords2D, redCoords, nsRed, markb, markr, plane, R, P, nP); if (ret != 0) return 1; // some unforeseen error int side[MAXEDGES] = { 0 };// this refers to what side? blue or red?// more tolerant here with epsilon_area int extraPoints = borderPointsOfXinY2(blueCoords2D, nsBlue, redCoords2D, nsRed, &(P[2 * nP]), side, 2*epsilon_area); if (extraPoints >= 1) { for (int k = 0; k < nsBlue; k++) { if (side[k]) { // this means that vertex k of blue is inside convex red; mark edges k-1 and k in blue, // as being "intersected" by red; (even though they might not be intersected by other edges, // the fact that their apex is inside, is good enough) markb[k] = 1; markb[(k + nsBlue-1) % nsBlue] = 1; // it is the previous edge, actually, but instead of doing -1, it is // better to do modulo +3 (modulo 4) // null side b for next call side[k]=0; } } } nP += extraPoints; extraPoints = borderPointsOfCSinRLL(redCoords, redCoords2D, nsRed, blueCoords, nsBlue, blueEdgeType, &(P[2 * nP]), side, 100*epsilon_area); // we need to compare with 0 a volume from 3 vector product; // lots of round off errors at stake if (extraPoints >= 1) { for (int k = 0; k < nsRed; k++) { if (side[k]) { // this is to mark that red edges k-1 and k are intersecting blue markr[k] = 1; markr[(k + nsRed-1) % nsRed] = 1; // it is the previous edge, actually, but instead of doing -1, it is // better to do modulo +3 (modulo 4) // null side b for next call } } } nP += extraPoints; // now sort and orient the points in P, such that they are forming a convex polygon // this will be the foundation of our new mesh // this works if the polygons are convex SortAndRemoveDoubles2(P, nP, epsilon_1); // nP should be at most 8 in the end ? // if there are more than 3 points, some area will be positive if (nP >= 3) { for (int k = 1; k < nP - 1; k++) area += area2D(P, &P[2 * k], &P[2 * k + 2]); } return 0; // no error }