Exemplo n.º 1
0
void
ConvexHull::graham() {
    if(is_degenerate()) // nothing to do
        return;
    find_pivot();
    angle_sort();
    graham_scan();
}
Exemplo n.º 2
0
/*** 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;
}
Exemplo n.º 3
0
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;
}
Exemplo n.º 4
0
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));
}
Exemplo n.º 5
0
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;
}