int main() { point A[N], B[N]; int an, bn, i; while(~scanf("%d%d", &an, &bn)) { for(i=0; i<an; i++)A[i].init(); for(i=0; i<bn; i++)B[i].init(); printf("%.2lf\n",polygon_area(A,an)+polygon_area(B, n)-simple_polygon_inter_area(A, an,B,bn)); } return 0; }
PolygonPartition find_polygon_partition_for_angle(const std::vector<Point>& polygon, double angle) { Intersection inter1 = find_bisection(Point(sin(angle), -cos(angle)), polygon); Intersection inter2 = find_bisection(Point(cos(angle), sin(angle)), polygon); Point center = find_intersection_center(inter1, inter2); IntersectionPoint stop = find_polygon_breakpoint(inter1, inter2, polygon); std::vector<Point> quarter_pol = construct_polygon_part(polygon, inter1.left, stop, center); double quarter_area = polygon_area(quarter_pol); return PolygonPartition(angle, center, 4 * quarter_area - polygon_area(polygon)); }
Intersection find_bisection(const Point& line_direction, const std::vector<Point>& polygon) { int min_offset_ind; OffsetRange offset_range; find_offset_range(line_direction, polygon, min_offset_ind, offset_range); const double whole_area = polygon_area(polygon); double area_difference = whole_area; Intersection inter; while (!are_equal(area_difference, 0.0, EPS * whole_area)) { double cur_offset = offset_range.middle_of_range(); inter = find_line_polygon_intersection(line_direction, cur_offset, polygon); std::vector<Point> half_pol = construct_polygon_part(polygon, inter.left, inter.right); area_difference = whole_area - 2 * polygon_area(half_pol); (is_half_consisting_min_offset_ind_greater(min_offset_ind, area_difference, inter) ? offset_range.right : offset_range.left) = cur_offset; } return inter; }
int main () { FILE *fpi, *fpo; int size; double area; double x[20]; double y[20]; fpi = fopen ("data.txt", "r"); fpo = fopen ("data2.txt", "a+"); size = get_corners (fpi, x, y, MAX_SIZE); output_corners (fpo, x, y, size); area = polygon_area (x, y, size); printf ("The area is %.1lf\n", area); return 0; }
static void select_quad(void) { int q, x, y, v, viewport[4]; float modelview[16], proj[16]; best_quad = -1; best_depth = 1000000.0f; nos_mouse_pos(&x, &y); if(x == 0 || y == 0) { return; } glGetFloatv(GL_PROJECTION_MATRIX, proj); glGetFloatv(GL_MODELVIEW_MATRIX, modelview); glGetIntegerv(GL_VIEWPORT, viewport); y = viewport[3] - y; for(v = 0; v < model.vertexes; ++v) { _project(model.vertex_pos[v], modelview, proj, viewport, vertexes_projected[v]); } for(q = 0; q < model.quads; ++q) { float *quad[4]; if(unpacker.deleted_quads[q]) { continue; } quad[0] = vertexes_projected[model.quad_index[q][0]]; quad[1] = vertexes_projected[model.quad_index[q][1]]; quad[2] = vertexes_projected[model.quad_index[q][2]]; quad[3] = vertexes_projected[model.quad_index[q][3]]; if(polygon_inside(4, quad, (float)x, (float)y)) { float depth = quad[0][2] + quad[1][2] + quad[2][2] + quad[3][2]; if(depth < best_depth && polygon_area(4, quad) > 0.0f) { best_quad = q; best_depth = depth; } } } }
inline double convex_poly_inter_area(point A[],int an,point B[],int bn)//凸多边形面积并 { point tmp[N], tpp; int tn, i, j, next, now; A[an]=A[0]; B[bn]=B[0]; for(i=0;i<an && bn>2; i++) { now=sgn(cross(A[i+1]-A[i], B[0]-A[i+1])); for(j=tn=0; j<bn; j++, now=next) { if(now>=0)tmp[tn++]=B[j]; next=sgn(cross(A[i+1]-A[i], B[j+1]-A[i+1])); if(now*next<0) tmp[tn++]=intersect(A[i], A[i+1], B[j], B[j+1]);//tpp; } for(j=0; j<tn; j++)B[j]=tmp[j]; bn=tn; B[bn]=B[0]; } if(bn<3)return 0.00; return polygon_area(B, bn); }
double intersection_area_circle_triangle( double radius, // triangle vertices: {org, org+u, org+v} are in CCW orientation const double tri_org[2], const double tri_u[2], const double tri_v[2] ){ const double origin[2] = {0,0}; int i, j; const double iradius = 1./radius; const double iradius2 = 1./(radius*radius); int inside = 0; // bitfield of which triangle vertices are in circle, 4th bit is if circle center is in triangle double vert[6]; vert[2*0+0] = tri_org[0]; vert[2*0+1] = tri_org[1]; vert[2*1+0] = (tri_org[0] + tri_u[0]); vert[2*1+1] = (tri_org[1] + tri_u[1]); vert[2*2+0] = (tri_org[0] + tri_v[0]); vert[2*2+1] = (tri_org[1] + tri_v[1]); double vert_org[6]; vert_org[2*0+0] = 0; vert_org[2*0+1] = 0; vert_org[2*1+0] = tri_u[0]; vert_org[2*1+1] = tri_u[1]; vert_org[2*2+0] = tri_v[0]; vert_org[2*2+1] = tri_v[1]; double tri_r[3]; // distance from circle center of each vertex of triangle, normalized to radius for(i = 0; i < 3; ++i){ tri_r[i] = hypot(vert[2*i+0], vert[2*i+1]) * iradius; if(tri_r[i] <= 1.0){ inside |= (1<<i); } } if(TriangleContainsPoint(tri_org, tri_u, tri_v, origin)){ inside |= (1<<3); } if((inside & 0x7) == 0x7){ // all triangle points in circle return 0.5*fabs(LeftTurn(origin,tri_u,tri_v)); } double seg[6]; seg[2*0+0] = tri_u[0]; seg[2*0+1] = tri_u[1]; seg[2*1+0] = (tri_v[0] - tri_u[0]); seg[2*1+1] = (tri_v[1] - tri_u[1]); seg[2*2+0] = -tri_v[0]; seg[2*2+1] = -tri_v[1]; double side_length[3]; // normalized to radius for(i = 0; i < 3; ++i){ side_length[i] = hypot(seg[2*i+0], seg[2*i+1]) * iradius; } double seg_dot[3]; // p0.(p1-p0)/r^2 for(i = 0; i < 3; ++i){ seg_dot[i] = (vert[2*i+0]*seg[2*i+0] + vert[2*i+1]*seg[2*i+1]) * iradius2; } // Get intersections of each segment with each circle // segment 0 is org to u, segment 1 is u to v, segment 2 is v to org double xp[12]; // intersection points int nxp[3]; // number of intersections with each segment int nx = 0; for(i = 0; i < 3; ++i){ int ip1 = (i+1)%3; int in0 = (inside & (1<<i)) ? 1 : 0; int in1 = (inside & (1<<ip1)) ? 1 : 0; if(in0 && in1){ nxp[i] = 0; }else{ // line: x = p0 + t(p1-p0) // circle: x^2 = r^2 // (p0 + t(p1-p0))^2 = r^2 // t^2(p1-p0)^2 + 2t(p0).(p1-p0) + (p0)^2 - r^2 = 0 // t^2 * side_length^2 + 2*t*seg_dot + tri_r^2 - 1 = 0 // t = -seg_dot/side_length^2 +/- sqrt(seg_dot^2/side_length^4 - (tri_r^2-1)/side_length^2) double isl2 = 1./(side_length[i]*side_length[i]); double disc = (seg_dot[i]*seg_dot[i]*isl2 - (tri_r[i]*tri_r[i]-1)) * isl2; double t0 = -seg_dot[i]*isl2; double t, t2, tdist, t2dist; if(in0 != in1){ // get the one intersection point nxp[i] = 1; nx += 1; if(disc < 0){ disc = 0; } disc = sqrt(disc); t = t0+disc; t2 = t0-disc; if(t > 0.5){ tdist = fabs(t-1.); }else{ tdist = fabs(t); } if(t2 > 0.5){ t2dist = fabs(t2-1.); }else{ t2dist = fabs(t2); } if(t2dist < tdist){ t = t2; } if(t < 0){ t = 0; } if(t > 1){ t = 1; } xp[2*2*i+0] = vert_org[2*i+0] + t*seg[2*i+0]; xp[2*2*i+1] = vert_org[2*i+1] + t*seg[2*i+1]; }else{ // possibly 0 or 2 intersection points; we count 1 degenerate point as none if(disc <= 0){ nxp[i] = 0; }else{ disc = sqrt(disc); nxp[i] = 0; t = t0-disc; t2 = t0+disc; if(0 < t && t < 1 && 0 < t2 && t2 < 1){ xp[2*(2*i+0)+0] = vert_org[2*i+0] + t*seg[2*i+0]; xp[2*(2*i+0)+1] = vert_org[2*i+1] + t*seg[2*i+1]; xp[2*(2*i+1)+0] = vert_org[2*i+0] + t*seg[2*i+0]; xp[2*(2*i+1)+1] = vert_org[2*i+1] + t*seg[2*i+1]; nxp[i] += 2; nx += 2; } } } } } /* printf("tri: (%f,%f) (%f,%f) (%f,%f)\n", vert[0], vert[1], vert[2], vert[3], vert[4], vert[5]); printf("rad: %f\n", radius); printf("inside = %d, nx = %d\n", inside, nx); printf("xp:"); for(i = 0; i < 3; ++i){ for(j = 0; j < nxp[i]; ++j){ printf(" (%d,%d,{%f,%f})", i, j, tri_org[0]+xp[2*(2*i+j)+0], tri_org[1]+xp[2*(2*i+j)+1]); } }printf("\n"); */ if(0 == nx){ // either no intersection area, or triangle entirely in circle, or circle in triangle if((inside & 0x7) == 0x7){ // all triangle points in circle // we already dealt with this above; getting here would be an error. return -1; }else{ // either no intersection area, or circle in triangle if(inside & 0x8){ // triangle contains circle center, intersection area is either circle area or triangle area return M_PI*radius*radius; }else{ return 0; } } }else if(2 == nx){ // Either the 2 intersections are a single side or on two different sides if(nxp[0] < 2 && nxp[1] < 2 && nxp[2] < 2){ // on different sides // The area is determined by tracing }else{ for(i = 0; i < 3; ++i){ if(nxp[i] > 1){ break; } } // Either the circle is mostly inside with a wedge poking out a side // or the circle is mostly outside with a wedge poking inside double sector_area = CircularSectorArea(radius, hypot(xp[2*(2*i+1)+0]-xp[2*2*i+0],xp[2*(2*i+1)+1]-xp[2*2*i+1])); if(inside & (1 << 3)){ // Area of circle minus a wedge return M_PI*radius*radius - sector_area; }else{ return sector_area; } } }else if(4 == nx){ // The area is determined by tracing }else if(6 == nx){ // The area is determined by tracing }else{ // There is no way we can get here return -1; } // At this point we expect to just trace out the intersection shape // The vertices of the intersection shape is either a triangle vertex // or a intersection point on a triangle edge. int vtype[6]; // 1 = triangle vertex, 0 = intersection point double vp[12]; int nv = 0; // number of actual vertices for(i = 0; i < 3; ++i){ if(inside & (1 << i)){ vp[2*nv+0] = vert_org[2*i+0]; vp[2*nv+1] = vert_org[2*i+1]; vtype[nv++] = 1; } for(j = 0; j < nxp[i]; ++j){ vp[2*nv+0] = xp[2*(2*i+j)+0]; vp[2*nv+1] = xp[2*(2*i+j)+1]; vtype[nv++] = 0; } } if(nv < 3){ // this should not be possible return -1; } // All neighboring points in v which are intersection points should have circular caps added double area = polygon_area(nv, vp); for(i = 0; i < nv; ++i){ int im1 = i-1; if(im1 < 0){ im1 = nv-1; } if((0 == vtype[im1]) && (0 == vtype[i])){ area += CircularSectorArea(radius, hypot(vp[2*i+0]-vp[2*im1+0],vp[2*i+1]-vp[2*im1+1])); } } return area; }
void test01 ( int nv, double v[] ) /******************************************************************************/ /* Purpose: TEST01 estimates integrals over a polygon in 2D. Licensing: This code is distributed under the GNU LGPL license. Modified: 09 May 2014 Author: John Burkardt */ { int e[2]; int e_test[2*7] = { 0, 0, 2, 0, 0, 2, 4, 0, 2, 2, 0, 4, 6, 0 }; double error; double exact; int j; int n; double result; int seed; double *value; double *x; printf ( "\n" ); printf ( "TEST01\n" ); printf ( " Use POLYGON_SAMPLE to estimate integrals\n" ); printf ( " over the interior of a polygon in 2D.\n" ); seed = 123456789; printf ( "\n" ); printf ( " N" ); printf ( " 1" ); printf ( " X^2 " ); printf ( " Y^2" ); printf ( " X^4" ); printf ( " X^2Y^2" ); printf ( " Y^4" ); printf ( " X^6\n" ); printf ( "\n" ); n = 1; while ( n <= 65536 ) { x = polygon_sample ( nv, v, n, &seed ); printf ( " %8d", n ); for ( j = 0; j < 7; j++ ) { e[0] = e_test[0+j*2]; e[1] = e_test[1+j*2]; value = monomial_value ( 2, n, e, x ); result = polygon_area ( nv, v ) * r8vec_sum ( n, value ) / ( double ) ( n ); printf ( " %14.6g", result ); } printf ( "\n" ); free ( value ); free ( x ); n = 2 * n; } printf ( "\n" ); printf ( " Exact" ); for ( j = 0; j < 7; j++ ) { e[0] = e_test[0+j*2]; e[1] = e_test[1+j*2]; result = polygon_monomial_integral ( nv, v, e ); printf ( " %14.6g", result ); } printf ( "\n" ); return; }
/** Compute graph. * @param graph the resulting nodes and edges will be added to this graph. * The graph will *not* be cleared automatically. The graph will be locked * while adding nodes. */ void NavGraphGeneratorVoronoi::compute(fawkes::LockPtr<fawkes::NavGraph> graph) { VD vd; for (auto o : obstacles_) { vd.insert(Site_2(o.first, o.second)); } polygons_.clear(); Iso_rectangle rect(Point_2(bbox_p1_x_, bbox_p1_y_), Point_2(bbox_p2_x_, bbox_p2_y_)); std::map<std::string, Point_2> points; std::map<std::string, std::string> props_gen; props_gen["generated"] = "true"; unsigned int num_nodes = 0; if (vd.is_valid()) { VD::Edge_iterator e; graph.lock(); for (e = vd.edges_begin(); e != vd.edges_end(); ++e) { if (e->is_segment()) { if (bbox_enabled_) { CGAL::Bounded_side source_side, target_side; source_side = rect.bounded_side(e->source()->point()); target_side = rect.bounded_side(e->target()->point()); if (source_side == CGAL::ON_UNBOUNDED_SIDE || target_side == CGAL::ON_UNBOUNDED_SIDE) continue; } // check if we have a point in the vicinity std::string source_name, target_name; bool have_source = contains(points, e->source()->point(), source_name, near_threshold_); bool have_target = contains(points, e->target()->point(), target_name, near_threshold_); if (! have_source) { source_name = genname(num_nodes); //printf("Adding source %s\n", source_name.c_str()); graph->add_node(NavGraphNode(source_name, e->source()->point().x(), e->source()->point().y(), props_gen)); points[source_name] = e->source()->point(); } if (! have_target) { target_name = genname(num_nodes); //printf("Adding target %s\n", target_name.c_str()); graph->add_node(NavGraphNode(target_name, e->target()->point().x(), e->target()->point().y(), props_gen)); points[target_name] = e->target()->point(); } graph->add_edge(NavGraphEdge(source_name, target_name, props_gen)); } else { //printf("Unbounded edge\n"); } } // Store Polygons VD::Bounded_faces_iterator f; for (f = vd.bounded_faces_begin(); f != vd.bounded_faces_end(); ++f) { unsigned int num_v = 0; Ccb_halfedge_circulator ec_start = f->outer_ccb(); Ccb_halfedge_circulator ec = ec_start; do { ++num_v; } while ( ++ec != ec_start ); Polygon2D poly(num_v); size_t poly_i = 0; bool f_ok = true; do { const Point_2 &p = ec->source()->point(); if (bbox_enabled_) { if (rect.has_on_unbounded_side(p)) { f_ok = false; break; } } poly[poly_i][0] = p.x(); poly[poly_i][1] = p.y(); ++poly_i; } while ( ++ec != ec_start ); if (f_ok) polygons_.push_back(poly); } std::list<Eigen::Vector2f> node_coords; std::vector<NavGraphNode>::const_iterator n; for (n = graph->nodes().begin(); n != graph->nodes().end(); ++n) { node_coords.push_back(Eigen::Vector2f(n->x(), n->y())); } polygons_.remove_if([&node_coords](const Polygon2D &poly) { for (const auto nc : node_coords) { if (polygon_contains(poly, nc)) return true; } return false; } ); polygons_.sort([](const Polygon2D &p1, const Polygon2D &p2) { return polygon_area(p2) < polygon_area(p1); } ); graph->calc_reachability(); graph.unlock(); } }
// returns the verts of an empty box, centered on the origin which is surrounded by triangles void generate_box_space( moab::EntityHandle surf, double A_f, std::vector<moab::EntityHandle> &box_verts, int axis ) { int x_idx, y_idx; //set the indices of the cartesian vectors based on the constant axis for this surface switch(axis){ case 0: x_idx = 1; y_idx = 2; break; case 1: x_idx = 0; y_idx = 2; break; case 2: x_idx = 0; y_idx = 1; break; default: std::cout << "Value of axis muxt be 0, 1, or 2" << std::endl; assert(false); } std::vector<moab::EntityHandle> corners; moab::ErrorCode rval = mbi->get_entities_by_type( surf, MBVERTEX, corners ); MB_CHK_ERR_CONT(rval); double surface_area = polygon_area( corners ); //going to start taking advantage of knowing the geometry here... double surface_side = sqrt(surface_area); double cube_area = 6*surface_area; //now create the vertices for the new regions //based on surface area, get the length of one of the center-square sides if( A_f == 1 ) { std::vector<moab::EntityHandle> ordered_corners; order_corner_verts(corners, ordered_corners); box_verts = ordered_corners; return; } double hv_area = A_f*cube_area/6; //divide by 6 because this surface represents all surfaces of the cube if ( hv_area >= surface_area ) std::cout << "ERROR: Area fraction must be less than 1/6 for now. " << surf << std::endl; assert( hv_area < surface_area ); double hv_side = sqrt(hv_area); //get the move distance for the given area. double box_bump_dist = 0.5 * (surface_side - hv_side); double dam_bump_short = 0.25 * (surface_side - hv_side); double dam_bump_long = 0.5 * surface_side; //vectors for the dam nodes and the inner vert points std::vector<moab::EntityHandle> nd, /*north dam tri verts*/ sd, /*south dam tri verts*/ ed, /*east dam tri verts*/ wd; /*west dam tri verts*/ moab::EntityHandle ndv, /*north dam vertex*/ sdv, /*south dam vertex*/ edv, /*east dam vertex*/ wdv; /*west dam vertex*/ std::vector<moab::EntityHandle> box; /* inner box vert list */ //loop over the original verts (corners) and create the needed vertices for(std::vector<moab::EntityHandle>::iterator i=corners.begin(); i!=corners.end(); i++) { //first get the coordinates of this corner moab::CartVect coords; mbi->get_coords( &(*i), 1, coords.array() ); //need three cartesian vectors telling us where to put the verts, two for the dam points, one for the inner point. moab::CartVect to_ewdam, to_nsdam, to_box; to_ewdam[axis] = 0; to_nsdam[axis] = 0; to_box[axis] = 0; //only moving on the x-y plane here //always want to create this vert //using the fact that we're centered on the origin here... //x-points if( coords[x_idx] < 0 ){ to_box[x_idx] = box_bump_dist; } else { to_box[x_idx] = -box_bump_dist; } //y-points if( coords[y_idx] < 0 ){ to_box[y_idx]= box_bump_dist; } else { to_box[y_idx] = -box_bump_dist; } //create the inner point moab::EntityHandle box_vert; mbi->create_vertex( (coords+to_box).array(), box_vert); box.push_back(box_vert); //figure out which dams we're adjacent to std::vector<moab::EntityHandle> *nsdam = &nd, *ewdam = &ed; moab::EntityHandle *nsdam_vert = &ndv, *ewdam_vert = &edv; //set the north-south dam based on our y location if( coords[y_idx] < 0) { nsdam_vert = &sdv; nsdam = &sd; } else { nsdam_vert = &ndv; nsdam = &nd; } //set the east-west dam based on our x location if( coords[x_idx] < 0) { ewdam_vert = &wdv; ewdam = &wd; } else { ewdam_vert = &edv; ewdam = &ed; } //////NORTH-SOUTH DAM\\\\\\\ //if the dams already have info from another corner, no need to create it's point, //just add this corner to the dam triangle if( 0 != nsdam->size() && NULL != nsdam_vert ) { nsdam->push_back(*i); } // if the dam has no info, then we'll create it else { //set the dam coordinates if ( coords[x_idx] < 0 ) to_nsdam[x_idx] = dam_bump_long; else to_nsdam[x_idx] = -dam_bump_long; if ( coords[y_idx] < 0 ) to_nsdam[y_idx] = dam_bump_short; else to_nsdam[y_idx] = -dam_bump_short; //create the dam vertex mbi->create_vertex( (coords+to_nsdam).array(), *nsdam_vert); //now add this corner and the dam vert to the dam verts list nsdam->push_back(*nsdam_vert); nsdam->push_back(*i); } //////EAST-WEST DAM\\\\\\\ //if the dams already have info from another corner, no need to create it's point, //just add this corner to the dam triangle if( 0 != ewdam->size() && NULL != ewdam_vert ) { ewdam->push_back(*i); } // if the dam has no info, then we'll create it else { //set the dam coordinates if ( coords[x_idx] < 0 ) to_ewdam[x_idx] = dam_bump_short; else to_ewdam[x_idx] = -dam_bump_short; if ( coords[y_idx] < 0 ) to_ewdam[y_idx] = dam_bump_long; else to_ewdam[y_idx] = -dam_bump_long; //create the dam vertex mbi->create_vertex( (coords+to_ewdam).array(), *ewdam_vert); //now add this corner and the dam vert to the dam verts list //order of push back is reversed here in comparison to north-south dam for correct normal ewdam->push_back(*i); ewdam->push_back(*ewdam_vert); } //dam info should now all be set //there are always two triangles to create that connect the dam //to the corner, we'll do that now moab::CartVect corner_coords; mbi->get_coords(&(*i), 1, corner_coords.array()); moab::EntityHandle tri1_verts[3] = {*i, *nsdam_vert, box_vert}; moab::EntityHandle tri2_verts[3] = {*i, *ewdam_vert, box_vert}; if( coords[x_idx] < 0 ) { if ( coords[y_idx] > 0 ) { tri1_verts[1] = *nsdam_vert; tri1_verts[2] = box_vert; tri2_verts[1] = box_vert; tri2_verts[2] = *ewdam_vert; } else { tri1_verts[1] = box_vert; tri1_verts[2] = *nsdam_vert; } } else { if ( coords[y_idx] > 0 ) { tri1_verts[1] = box_vert; tri1_verts[2] = *nsdam_vert; } else { tri2_verts[1] = box_vert; tri2_verts[2] = *ewdam_vert; } } std::vector<moab::EntityHandle> tris(2); mbi->create_element( MBTRI, &tri1_verts[0], 3, tris[0] ); mbi->create_element( MBTRI, &tri2_verts[0], 3, tris[1] ); //now we'll add these to the set mbi->add_entities( surf, &tri1_verts[0], 3 ); mbi->add_entities( surf, &tri2_verts[0], 3 ); mbi->add_entities( surf, &(tris[0]), tris.size() ); } //now we should have all of the info needed to create our dam triangles std::vector<moab::EntityHandle> dam_tris(4); assert( nd.size()==3 ); moab::EntityHandle temp = nd[1]; nd[1] = nd[2]; nd[2] = temp; temp = wd[1]; wd[1] = wd[2]; wd[2] = temp; mbi->create_element( MBTRI, &(nd[0]), nd.size(), dam_tris[0]); mbi->create_element( MBTRI, &(sd[0]), sd.size(), dam_tris[1]); mbi->create_element( MBTRI, &(ed[0]), ed.size(), dam_tris[2]); mbi->create_element( MBTRI, &(wd[0]), wd.size(), dam_tris[3]); //add these to the surface mbi->add_entities( surf, &(dam_tris[0]), dam_tris.size() ); //re-order the M verts std::vector<moab::EntityHandle> ordered_box(4); order_corner_verts(box, ordered_box); box_verts = ordered_box; //now that the middle box is ordered we can add the triangles that //connect the dams to to the box box_verts.push_back(box_verts[0]); // psuedo-loop to make creating these tris easier moab::EntityHandle all_dam_verts[4] = { wdv, ndv, edv, sdv }; std::vector<moab::EntityHandle> last_few_tris(4); //create triangle that connect the box to the dams for(unsigned int i = 0; i < last_few_tris.size(); i++) { moab::EntityHandle tri_verts[3] = { box_verts[i], all_dam_verts[i], box_verts[i+1] }; mbi->create_element( MBTRI, &(tri_verts[0]), 3, last_few_tris[i]); } //now add these to the surface mbi->add_entities( surf, &last_few_tris[0], 4); box_verts = ordered_box; } // end generate_box_space