Ejemplo n.º 1
0
LABEL_STORE tri_grid::get_path(LABEL SL, LABEL EL, int resolution)
{
	// create a path of labels between the starting label (SL) and the 
	// ending label (EL)
	// In the feature recognition routines, SL is the triangle being tested for
	// inclusion (candidate triangle - CL ) and EL is the original triangle at 
	// the centre of the feature (OL)

	// the path is derived by taking a line between the SL and EL and interpolating
	// along the line at points equal to the minimum of the distance between SL and
	// its neighbours.  The point inclusion test is then used to determine which
	// triangle each point is in
	
	// This algorithm has the benefit of terminating always - other path finding methods
	// I have tried, based on the adjacency list, have not!

	// what is the minimum distance between SL and it's adjacent labels?
	indexed_force_tri_3D* s_tri = get_triangle(SL);
	LABEL_STORE path;
	FP_TYPE min_dist = 2e20;
	const LABEL_STORE* s_adj_labs = s_tri->get_adjacent_labels(POINT);
	for (LABEL_STORE::const_iterator it_adj_lab = s_adj_labs->begin();
		 it_adj_lab != s_adj_labs->end(); it_adj_lab++)
	{
		indexed_force_tri_3D* a_tri = get_triangle(*it_adj_lab);
		vector_3D V = s_tri->centroid() - a_tri->centroid();
		FP_TYPE dist = V.mag();
		if (dist < min_dist)
			min_dist = dist;
	}
	
	// form the SL to EL vector
	indexed_force_tri_3D* e_tri = get_triangle(EL);
	vector_3D se_vec = s_tri->centroid() - e_tri->centroid();
	// loop until we reach the EL triangle	
	FP_TYPE n_pts = se_vec.mag()/(min_dist*resolution);	// how many points ?	
	vector_3D add_vec = se_vec / n_pts;		// what to add each iteration (vector)
	for (int i=0; i<int(n_pts+0.5)+1; i++)
	{
		vector_3D c_vec = s_tri->centroid() - add_vec * i;
		// normalise
		c_vec = c_vec / c_vec.mag();
		// point inclusion
		LABEL tri_label = get_triangle_for_point(&c_vec);
		// only add if not already added
		if (std::find(path.begin(), path.end(), tri_label) == path.end())
			path.push_back(tri_label);
	}
	return path;
}
Ejemplo n.º 2
0
void tri_grid::fill_index_holes(void)
{
	std::cout << "# Filling indexing holes" << std::endl;
	// try to fill holes in the mapping of the regular grid to the triangular
	// mesh for all the levels except level zero
	int tgt_tris = 3;
	for (int l=1; l<get_max_level(); l++)
	{
		std::list<QT_TRI_NODE*> tri_list = get_triangles_at_level(l);
		// go through the tri list and find those triangles with no indices
		for (std::list<QT_TRI_NODE*>::iterator it = tri_list.begin();
			 it != tri_list.end(); it++)
		{
			indexed_force_tri_3D* c_tri = (*it)->get_data();
			// get length of index list and if zero do something
			int n_sur_tris = 0;
			if (c_tri->get_grid_indices()->size() == 0)
			{
				// use the edge adjacencies to fill in the missing indices
				const LABEL_STORE* adj_map = c_tri->get_adjacent_labels(EDGE);
				for (LABEL_STORE::const_iterator jt = adj_map->begin();
					 jt != adj_map->end(); jt++)
				{
					indexed_force_tri_3D* s_tri = get_triangle(*jt);
					// check that this has indices!
					if (s_tri->get_grid_indices()->size() != 0)
						n_sur_tris++;
				}
				if (n_sur_tris >= tgt_tris)
				{
					// if the 3 surrounding triangles have indices then add the indices to
					// this triangle - this will produce a mean average in the regridding
					for (LABEL_STORE::const_iterator jt = adj_map->begin();
						 jt != adj_map->end(); jt++)
					{
						indexed_force_tri_3D* s_tri = get_triangle(*jt);
						const std::list<grid_index>* new_grid_indices = s_tri->get_grid_indices();
						for (std::list<grid_index>::const_iterator kt = new_grid_indices->begin();
							 kt != new_grid_indices->end(); kt++)
						{
							c_tri->add_index(kt->i, kt->j, kt->cart_coord);
						}
					}
				}
			}
		}
	}
}
Ejemplo n.º 3
0
void dopoly(double x[], double y[], int pts) {
	int n = 0;
	double *xcopy, *ycopy;

	/* Make copies of x[] and y[] -- they will be destroyed */
	xcopy = (double *)malloc(sizeof(*x)*pts);
	ycopy = (double *)malloc(sizeof(*y)*pts);
	memcpy(xcopy, x, sizeof(*x)*pts);
	memcpy(ycopy, y, sizeof(*y)*pts);

	pts--;

	/* Iterate through the polygon until only a triangle is left */
	while(pts > 3) {
		pts = get_triangle(xcopy, ycopy, pts, n);
		n = (n + 1) % pts;
	}

	/* Print out the coordinates of the triangle.
	 * If we are going to do something with the triangle, we should
	 * do it here.
	 */
	printf("Triangle: (%f, %f) (%f, %f) (%f, %f)\n",
		x[0], y[0], x[1], y[1], x[2], y[2]);
}
Ejemplo n.º 4
0
long optimise_heuristic(long tri_id1, long tri_id2)
{
    //return _DK_optimise_heuristic(tri_id1, tri_id2);
    struct Triangle *tri1;
    struct Triangle *tri3;
    struct Point *pt;
    long tri_id3,tri_lnk;
    long Ax,Ay,Bx,By,Cx,Cy,Dx,Dy;

    tri1 = get_triangle(tri_id1);
    tri_id3 = tri1->tags[tri_id2];
    if (tri_id3 == -1)
        return 0;
    tri3 = get_triangle(tri_id3);
    if (get_triangle_tree_alt(tri_id3) != get_triangle_tree_alt(tri_id1))
    {
        return 0;
    }
    tri_lnk = link_find(tri_id3, tri_id1);
    if (( (tri1->field_D & (1 << tri_id2)) == 0)
     || ( (tri3->field_D & (1 << tri_lnk)) == 0))
    {
        return 0;
    }
    pt = get_triangle_point(tri_id3, MOD3[tri_lnk+2]);
    Ax = pt->x;
    Ay = pt->y;
    pt = get_triangle_point(tri_id1, MOD3[tri_id2+2]);
    Bx = pt->x;
    By = pt->y;
    pt = get_triangle_point(tri_id1, MOD3[tri_id2+1]);
    Cx = pt->x;
    Cy = pt->y;
    pt = get_triangle_point(tri_id1, MOD3[tri_id2]);
    Dx = pt->x;
    Dy = pt->y;
    if (LbCompareMultiplications(Ay-By, Dx-Bx, Ax-Bx, Dy-By) >= 0)
        return 0;
    if (LbCompareMultiplications(Ay-By, Cx-Bx, Ax-Bx, Cy-By) <= 0)
        return 0;

    return ((Bx-Ax) * (Bx-Ax)) + ((By-Ay) * (By-Ay)) <
           ((Dy-Ay) - (Cy-Ay)) * ((Dy-Ay) - (Cy-Ay)) +
           ((Dx-Ax) - (Cx-Ax)) * ((Dx-Ax) - (Cx-Ax));
}
Ejemplo n.º 5
0
void Triangulation::nearest_exterior_triangle(unsigned int &output_index, double &alpha, double &beta, double &gamma,
                                              const Point &point) const
{
    unsigned int i;
    double distance, distance_min;
    Point proj;
    Curve tri;
    Triangle triangle;
    std::vector<Point> nodes;
    std::vector<complex_number> tangents;

    nodes.resize(3);
    i = nb_interior_triangles_;
    triangle = get_triangle(i);
    triangle.get_ABC(nodes[0], nodes[1], nodes[2]);
    tri.create_custom(nodes, tangents);
    tri.point_projection(proj, point);
    distance_min = norm(proj.get_affix() - point.get_affix());
    output_index = i;
    for(i=nb_interior_triangles_+1; i<triangles_.size(); i++)
    {
        if(!triangle.barycentric_coordinates(alpha, beta, gamma, point))
        {
            continue;
        }
        triangle = get_triangle(i);
        triangle.get_ABC(nodes[0], nodes[1], nodes[2]);
        tri.create_custom(nodes, tangents);
        tri.point_projection(proj, point);
        distance = norm(proj.get_affix() - point.get_affix());
        if(distance < distance_min )
        {
            distance_min = distance;
            output_index = i;
        }
    }
    triangle = get_triangle(output_index);
    triangle.barycentric_coordinates(alpha,beta,gamma,point);
    return;
}
Ejemplo n.º 6
0
bool Triangulation::triangle_containing(unsigned int &output_index,
                                        double &alpha, double &beta, double &gamma,const Point &point) const
{
    unsigned int i;
    for(i=0; i<triangles_.size(); i++)
    {
        if(get_triangle(i).is_inside(alpha, beta, gamma, point))
        {
            output_index = i;
            return true;
        }
    }
    return false;
}
Ejemplo n.º 7
0
	void operator ()(VcacheMesh &vcache_mesh, submesh_id_t const &submesh_id, ProgressCallback & progress_callback, bool const reorder_vertices = true)
	{
		//////// prerequisites
		//////////////////////

		has_best_triangle = false;
		best_triangle = 0;

		optimized_tris.clear();
		lru_cache.clear();

		vtx_data.resize(get_num_vertices(vcache_mesh, submesh_id));
		tri_data.resize(get_num_triangles(vcache_mesh, submesh_id));

		// fetch the triangle data and put it in the internal vector
		// also fill the tri_indices_using vectors in the process
		{
			for (triangle_index_t tri_index = 0; tri_index < get_num_triangles(vcache_mesh, submesh_id); ++tri_index)
			{
				triangle_t triangle = get_triangle(vcache_mesh, submesh_id, tri_index);

				for (int i = 0; i < 3; ++i)
				{
					tri_data[tri_index].indices[i] = triangle[i];
					vtx_data[triangle[i]].tri_indices_using.insert(tri_index);
				}
			}
		}


		//////// optimize triangles
		///////////////////////////

		// calculate vertex and triangle scores
		{
			for (vertex_index_t vtx_index = 0; vtx_index < get_num_vertices(vcache_mesh, submesh_id); ++vtx_index)
			{
				vertex_data &vtx = vtx_data[vtx_index];
				vtx.score = find_vertex_score(vtx); // calculate the vertex score

				for (typename tri_indices_using_t::const_iterator tri_idx_iter = vtx.tri_indices_using.begin(); tri_idx_iter != vtx.tri_indices_using.end(); ++tri_idx_iter)
					tri_data[*tri_idx_iter].score += vtx.score; // add the vertex score to the triangles using this vertex
			}
		}

		// tell the progress callback the maximum progress value
		set_maximum_optimizing_triangles_progress(progress_callback, tri_data.size());

		/*
		the actual optimization step; reorder triangles by repeatedly finding a "best" triangle
		(= look at all the vertices in the LRU cache, and from all the triangles using these vertices,
		find the one with the highest score, remove this one from the vertices and put it in
		optimized_tris, and then find the next best triangle etc.)
		*/
		{
			size_t progress_counter = 0;
			while (optimized_tris.size() < tri_data.size())
			{
				push_best_triangle();
				++progress_counter;
				set_current_optimizing_triangles_progress(progress_callback, progress_counter);
			}
		}


		//////// reoder vertices
		////////////////////////

		if (reorder_vertices)
		{
			// even though *vertices* are reordered, reordering happens across *triangles*
			set_maximum_reordering_vertices_progress(progress_callback, tri_data.size());

			// get the vertices from the mesh
			std::vector < vertex_t > src_vertices;
			src_vertices.resize(vtx_data.size());
			for (vertex_index_t vtx_index = 0; vtx_index < vtx_data.size(); ++vtx_index)
				src_vertices[vtx_index] = get_vertex(vcache_mesh, submesh_id, vtx_index);

			// create and initialize the permutation sequence;
			// this sequence will be used for updating the triangle vertex indices later
			std::vector < std::pair < bool, vertex_index_t > > permutation;
			permutation.resize(vtx_data.size());
			std::fill(permutation.begin(), permutation.end(), std::pair < bool, vertex_index_t > (false, 0));

			/*
			reordering is done according to the order of access
			"access" refers to the triangles; for example, it makes no sense when the first
			triangle's vertices are at the end of the list of vertices, the second triangle's
			are in the middle etc.
			Instead, the first triangle's vertices should be at the beginning, the second triangle's
			should be right after these etc.
			*/
			size_t progress_counter = 0;
			vertex_index_t mesh_vertex_index = 0;
			for (triangle_index_t tri_index = 0; tri_index < optimized_tris.size(); ++tri_index)
			{
				triangle_data const &tri = tri_data[tri_index];

				// go through all 3 indices of each triangle,
				// and if it wasn't reordered, do so
				for (int i = 0; i < 3; ++i)
				{
					vertex_index_t vtx_index = tri.indices[i];
					if (!permutation[vtx_index].first) // first false -> was not reordered yet
					{
						// check for overflow; it should never happen, since
						// each vertex is reordered only once
						assert(mesh_vertex_index < src_vertices.size());

						// mark the vertex as reordered and store its new index
						permutation[vtx_index].first = true;
						permutation[vtx_index].second = mesh_vertex_index;

						// write the vertex at its new position in the mesh
						set_vertex(vcache_mesh, submesh_id, mesh_vertex_index, src_vertices[vtx_index]);
						++mesh_vertex_index;
					}
				}

				++progress_counter;
				set_current_reordering_vertices_progress(progress_callback, progress_counter);
			}

			// After the vertices have been reodered, the triangle vertex indices need to be updated
			for (triangle_index_t tri_index = 0; tri_index < optimized_tris.size(); ++tri_index)
			{
				triangle_data &tri = optimized_tris[tri_index];
				for (int i = 0; i < 3; ++i)
					tri.indices[i] = permutation[tri.indices[i]].second;
			}
		}

		// finally, store the contents of optimized_tris in the mesh
		{
			for (triangle_index_t tri_index = 0; tri_index < optimized_tris.size(); ++tri_index)
			{
				triangle_data const &tri = optimized_tris[tri_index];
				triangle_t new_triangle = create_new_triangle(
					vcache_mesh,
					tri.indices[0],
					tri.indices[1],
					tri.indices[2]
				);

				set_triangle(vcache_mesh, submesh_id, tri_index, new_triangle);
			}
		}
	}