Esempio n. 1
0
int TriMesh2D::get_containing_tri(const Vec2f& point) const {
   
   Vec2f cell = (point - accel_origin)*inv_accel_dx;
   unsigned int offset = (int)cell[0] + accel_ni * (int)cell[1];
   if(offset < accel_grid.size()) {
      for(unsigned int i = 0; i < accel_grid[offset].size(); ++i)
         if(point_in_tri(point, accel_grid[offset][i]))
            return accel_grid[offset][i];
   }
   
   return -1;
   
}
Esempio n. 2
0
void tri_grid::assign_points_from_grid(ncdata* nc_input_data, int perim)
{
	// relative coordinates for the 5 points of a grid box
	const int n_gp = 5;
	const FP_TYPE x_pts[5] = {0,-1,1,1,-1};
	const FP_TYPE y_pts[5] = {0,-1,-1,1,1};
	FP_TYPE lon_d = nc_input_data->get_lon_d();
	FP_TYPE lat_d = nc_input_data->get_lat_d();
	FP_TYPE lon_s = nc_input_data->get_lon_s();
	FP_TYPE lat_s = nc_input_data->get_lat_s();
	
	FP_TYPE rot_pole_lon, rot_pole_lat;
	if (nc_input_data->has_rotated_grid())
	{
		 rot_pole_lon = nc_input_data->get_rotated_grid()->get_rotated_pole_longitude();
		 rot_pole_lat = nc_input_data->get_rotated_grid()->get_rotated_pole_latitude();
	}
	
	// get the coordinates from the ncdata file and add to the quad trees
	for (int j=perim; j<nc_input_data->get_lat_len()-perim; j++)
	{
		for (int i=perim; i<nc_input_data->get_lon_len()-perim; i++)
		{
			FP_TYPE lon_b = lon_s + i*lon_d;
			FP_TYPE lat_b = lat_s + j*lat_d;
			for (int k=0; k<n_gp; k++)
			{
				// get the lon as the corners of a grid box
				FP_TYPE lon = lon_b + x_pts[k] * lon_d * 0.49999;
				FP_TYPE lat = lat_b + y_pts[k] * lat_d * 0.49999;
				// extra conversion for rotated grid
				if (nc_input_data->has_rotated_grid())
				{
					FP_TYPE glob_lon, glob_lat;
					Rot2Global(lat, lon, rot_pole_lat, rot_pole_lon, 
             		     	   glob_lat, glob_lon);
             		lat = glob_lat;
             		lon = glob_lon;
				}
				// convert to Cartesian coordinates
				vector_3D cart_coords = model_to_cart(lon, lat);
				// determine which triangle (head node) this point is in
				for (unsigned int tri=0; tri<triangles.size(); tri++)
					if (point_in_tri(&cart_coords, triangles[tri]->get_root()->get_data()))
						triangles[tri]->get_root()->get_data()->add_index(i,j, cart_coords);
			}
		}
	}
}
Esempio n. 3
0
LABEL tri_grid::get_triangle_for_point(vector_3D* P)
{
	// determine which of the 20 base triangles the point is in
	int base_tri = -1;
	for (unsigned int tri=0; tri<triangles.size(); tri++)
		if (point_in_tri(P, triangles[tri]->get_root()->get_data()))
		{
			base_tri = tri;
			break;
		}
	// not found so find by distance
	if (base_tri == -1)
	{
		FP_TYPE min_dist = 2e20;
		int min_base = -1;
		FP_TYPE P_lon, P_lat;
		cart_to_model(*P, P_lon, P_lat);
		for (unsigned int tri=0; tri<triangles.size(); tri++)
		{
			FP_TYPE T_lon, T_lat;
			cart_to_model(triangles[tri]->get_root()->get_data()->centroid(), T_lon, T_lat);
			FP_TYPE dist = haversine(P_lon, P_lat, T_lon, T_lat, 1.0);
			if (dist < min_dist)
			{
				dist = min_dist;
				min_base = tri;
			}
		}	
		base_tri = min_base;
	}
	// get the base node
	QT_TRI_NODE* current_node = get_base_tri(base_tri);
	bool found = false;
	while (not found)
	{
		if (current_node->is_leaf())
		{
			found = true;
			break;
		}
		else
		{
			bool found_in_child = false;
			for (int i=0; i<4; i++)
			{
				QT_TRI_NODE* current_child = current_node->get_child(i);
				if (point_in_tri(P, current_child->get_data()))
				{
					current_node = current_child;
					found_in_child = true;
					break;
				}
			}
			// not found by point inclusion - find by minimum distance
			if (not found_in_child)
			{
				FP_TYPE min_dist = 2e20;
				int min_child = -1;
				FP_TYPE P_lon, P_lat;
				cart_to_model(*P, P_lon, P_lat);
				for (int i=0; i<4; i++)
				{
					FP_TYPE T_lon, T_lat;
					cart_to_model(current_node->get_child(i)->get_data()->centroid(), T_lon, T_lat);
					FP_TYPE dist = haversine(P_lon, P_lat, T_lon, T_lat, 1.0);
					if (dist < min_dist)
					{
						dist = min_dist;
						min_child = i;
					}
				}
				current_node = current_node->get_child(min_child);
			}
		}
	}
	return current_node->get_data()->get_label();
}
Esempio n. 4
0
void tri_grid::split_triangle(QT_TRI_NODE* triangle, int max_pts, int max_levs)
{
	// split the triangle indicated by PTI (parent triangle index) into four
	// new triangles and insert the 3 new force points into the point cloud 
	// and the triangle definition into the HTMA containing the references to 
	// the force points
	int iM[3];		// indices to new points in the point cloud
	for (int i=0; i<3; i++)
	{
		int j = i<2 ? i+1 : 0;
		// get the two points of the current triangle edge and create a mid point
		force_point MP = (PC[(*(triangle->get_data()))[i]] + PC[(*(triangle->get_data()))[j]]) * 0.5;
		// normalise the mid point
		MP *= 1.0 / MP.mag();
		// add to the point cloud
		iM[i] = PC_ADD_SPLIT(MP);
	}
	// new points have been created - now add the four new triangles
	indexed_force_tri_3D* ift = triangle->get_data();
	// get the current label
	LABEL c_label = ift->get_label();
	// calculate the multiplier
	long int mp = (long int)(pow(10, c_label.max_level+2));
	triangle->add_child(indexed_force_tri_3D(&PC, (*ift)[0],     iM[0], iM[2], LABEL(c_label.label+1*mp, c_label.max_level+1)));
	triangle->add_child(indexed_force_tri_3D(&PC,     iM[0], (*ift)[1], iM[1], LABEL(c_label.label+2*mp, c_label.max_level+1)));
	triangle->add_child(indexed_force_tri_3D(&PC,     iM[1], (*ift)[2], iM[2], LABEL(c_label.label+3*mp, c_label.max_level+1)));
	triangle->add_child(indexed_force_tri_3D(&PC,     iM[0],     iM[1], iM[2], LABEL(c_label.label+4*mp, c_label.max_level+1)));
	// check whether the triangles should contain one of the indexed points
	const std::list<grid_index>* grid_index_list = triangle->get_data()->get_grid_indices();
	for (std::list<grid_index>::const_iterator gii = grid_index_list->begin();
		 gii != grid_index_list->end(); gii++)
	{
		// get the actual triangle from the quad tree
		// check for point inclusion of current grid index
		bool pit = false;
		for (int i=0; i<4; i++)
		{
			// need to check each child triangle
			indexed_force_tri_3D* child_tri = triangle->get_child(i)->get_data();
			if (point_in_tri(&(gii->cart_coord), child_tri))
			{
				child_tri->add_index(gii->i, gii->j, gii->cart_coord);
				pit = true;
			}
		}
		// if not added then add to nearest
		FP_TYPE min_dist = 1e10;
		int min_tri_idx = -1;
		if (not pit)
		{
			for (int i=0; i<4; i++)
			{
				// calculate distance between point and centroid
				indexed_force_tri_3D* child_tri = triangle->get_child(i)->get_data();
				FP_TYPE dist = (child_tri->centroid() - gii->cart_coord).mag();
				if (dist < min_dist)
					min_tri_idx = i;
			}
			// add to the child tri the point is nearest to
			triangle->get_child(min_tri_idx)->get_data()->add_index(gii->i, gii->j, gii->cart_coord);
		}
	}
	
	// check whether each child should be split again
	for (int i=0; i<4; i++)
	{
		if ((triangle->get_child(i)->get_data()->get_number_of_indices() > max_pts ||
			// this ensures that any (for example level 7) levels with triangles in a previous level still get split
			 triangle->get_level() > max_levs-3) &&
			 triangle->get_level() < (max_levs-1))
			// recursive split
			split_triangle(triangle->get_child(i), max_pts, max_levs);
	}
}