void ConvexHull::graham() { if(is_degenerate()) // nothing to do return; find_pivot(); angle_sort(); graham_scan(); }
/*** ConvexHull::is_clockwise * We require that successive pairs of edges always turn right. * proposed algorithm: walk successive edges and require triangle area is positive. */ bool ConvexHull::is_clockwise() const { if(is_degenerate()) return true; Point first = boundary[0]; Point second = boundary[1]; for(std::vector<Point>::const_iterator it(boundary.begin()+2), e(boundary.end()); it != e;) { if(SignedTriangleArea(first, second, *it) > 0) return false; first = second; second = *it; ++it; } return true; }
Mesh marching_cubes(Grid& grid, double isovalue, SurfaceType surface_type) { Mesh mesh; int offset[8]; Vertex* vertices[12]; unordered_set<Vertex*, vertex_hash, vertex_equals> vertex_set; compute_offset(grid, offset); for(int z = 0; z < grid.get_axis(2)-1; z++) { for(int y = 0; y < grid.get_axis(1)-1; y++) { for(int x = 0; x < grid.get_axis(0)-1; x++) { int ic = grid.index(x,y,z); int table_index = get_index(grid, ic, offset, isovalue); for(int i = 0; i < 12; i++) { if(edge_table[table_index] & (1 << i)) { int v[3], u[3]; get_grid_edge(x, y, z, i, v, u); double sv = grid[grid.index(v[0],v[1],v[2])]; double su = grid[grid.index(u[0],u[1],u[2])]; double vc[3] = {(v[0]-grid.get_axis(0)/2.0)*grid.get_spacing(0), (v[1]-grid.get_axis(1)/2.0)*grid.get_spacing(1), (v[2]-grid.get_axis(2)/2.0)*grid.get_spacing(2)}; double uc[3] = {(u[0]-grid.get_axis(0)/2.0)*grid.get_spacing(0), (u[1]-grid.get_axis(1)/2.0)*grid.get_spacing(1), (u[2]-grid.get_axis(2)/2.0)*grid.get_spacing(2)}; if(surface_type == NO_SURFACE) { vertices[i] = lerp(vc, sv, uc, su, isovalue); } else { vertices[i] = find_cut_point(vc, sv, uc, su, isovalue, surface_type); } vertices[i] = merge_vertex(vertices[i], vertex_set, mesh); } } for(int i = 0; triangle_table[table_index][i] != -1; i += 3) { Vertex *v0, *v1, *v2; v0 = vertices[triangle_table[table_index][i]]; v1 = vertices[triangle_table[table_index][i+1]]; v2 = vertices[triangle_table[table_index][i+2]]; if(!is_degenerate(v0, v1, v2)) { Face* f = new Face; f->v.push_back(v0); f->v.push_back(v1); f->v.push_back(v2); v0->f.push_back(f); v1->f.push_back(f); v2->f.push_back(f); Edge* e0 = create_edge(v0, v1, f, mesh); Edge* e1 = create_edge(v1, v2, f, mesh); Edge* e2 = create_edge(v2, v0, f, mesh); f->e.push_back(e0); f->e.push_back(e1); f->e.push_back(e2); mesh.add(f); } } } } } compute_normals(mesh); return mesh; }
Line_d<R> Segment_d<R>::supporting_line() const { CGAL_assertion_msg((!is_degenerate()), "Segment_d::supporting_line(): degenerate segment cannot be converted."); return Line_d<R>(Base(*this)); }
int Face3::split_by_plane(const Plane &p_plane, Face3 p_res[3], bool p_is_point_over[3]) const { ERR_FAIL_COND_V(is_degenerate(), 0); Vector3 above[4]; int above_count = 0; Vector3 below[4]; int below_count = 0; for (int i = 0; i < 3; i++) { if (p_plane.has_point(vertex[i], CMP_EPSILON)) { // point is in plane ERR_FAIL_COND_V(above_count >= 4, 0); above[above_count++] = vertex[i]; ERR_FAIL_COND_V(below_count >= 4, 0); below[below_count++] = vertex[i]; } else { if (p_plane.is_point_over(vertex[i])) { //Point is over ERR_FAIL_COND_V(above_count >= 4, 0); above[above_count++] = vertex[i]; } else { //Point is under ERR_FAIL_COND_V(below_count >= 4, 0); below[below_count++] = vertex[i]; } /* Check for Intersection between this and the next vertex*/ Vector3 inters; if (!p_plane.intersects_segment(vertex[i], vertex[(i + 1) % 3], &inters)) continue; /* Intersection goes to both */ ERR_FAIL_COND_V(above_count >= 4, 0); above[above_count++] = inters; ERR_FAIL_COND_V(below_count >= 4, 0); below[below_count++] = inters; } } int polygons_created = 0; ERR_FAIL_COND_V(above_count >= 4 && below_count >= 4, 0); //bug in the algo if (above_count >= 3) { p_res[polygons_created] = Face3(above[0], above[1], above[2]); p_is_point_over[polygons_created] = true; polygons_created++; if (above_count == 4) { p_res[polygons_created] = Face3(above[2], above[3], above[0]); p_is_point_over[polygons_created] = true; polygons_created++; } } if (below_count >= 3) { p_res[polygons_created] = Face3(below[0], below[1], below[2]); p_is_point_over[polygons_created] = false; polygons_created++; if (below_count == 4) { p_res[polygons_created] = Face3(below[2], below[3], below[0]); p_is_point_over[polygons_created] = false; polygons_created++; } } return polygons_created; }