예제 #1
0
void FruchtermanReingold::make_initialisations(double bl, DPoint d_l_c, int grid_quot)
{
	grid_quotient(grid_quot);
	down_left_corner = d_l_c; //export this two values from FMMM
	boxlength = bl;
}
예제 #2
0
FruchtermanReingold:: FruchtermanReingold()  
{
	grid_quotient(2);
}
예제 #3
0
void FruchtermanReingold::calculate_approx_repulsive_forces(
	const Graph &G,
	NodeArray<NodeAttributes> &A,
	NodeArray<DPoint>& F_rep)
{
	//GRID algorithm by Fruchterman & Reingold
	numexcept N;
	List<IPoint> neighbour_boxes;
	List<node> neighbour_box;
	IPoint act_neighbour_box;
	IPoint neighbour;
	DPoint f_rep_u_on_v;
	DPoint vector_v_minus_u;
	DPoint nullpoint(0, 0);
	DPoint pos_u, pos_v;
	double norm_v_minus_u;
	double scalar;

	int i, j, act_i, act_j, k, l, length;
	double gridboxlength;//length of a box in the GRID

	//init F_rep
	for (node v : G.nodes)
		F_rep[v] = nullpoint;

	//init max_gridindex and set contained_nodes;

	max_gridindex = static_cast<int> (sqrt(double(G.numberOfNodes())) / grid_quotient()) - 1;
	max_gridindex = ((max_gridindex > 0) ? max_gridindex : 0);
	Array2D<List<node> >  contained_nodes(0, max_gridindex, 0, max_gridindex);

	for (i = 0; i <= max_gridindex; i++)
	for (j = 0; j <= max_gridindex; j++)
	{
		contained_nodes(i, j).clear();
	}

	gridboxlength = boxlength / (max_gridindex + 1);
	for (node v : G.nodes)
	{
		double x = A[v].get_x() - down_left_corner.m_x;//shift comput. box to nullpoint
		double y = A[v].get_y() - down_left_corner.m_y;
		int x_index = static_cast<int>(x / gridboxlength);
		int y_index = static_cast<int>(y / gridboxlength);
		contained_nodes(x_index, y_index).pushBack(v);
	}

	//force calculation

	for (i = 0; i <= max_gridindex; i++)
	for (j = 0; j <= max_gridindex; j++)
	{
		//step1: calculate forces inside contained_nodes(i,j)

		length = contained_nodes(i, j).size();
		Array<node> nodearray_i_j(length + 1);
		k = 1;
		for (node v : contained_nodes(i, j))
		{
			nodearray_i_j[k] = v;
			k++;
		}

		for (k = 1; k < length; k++)
		for (l = k + 1; l <= length; l++)
		{
			node u = nodearray_i_j[k];
			node v = nodearray_i_j[l];
			pos_u = A[u].get_position();
			pos_v = A[v].get_position();
			if (pos_u == pos_v)
			{//if2  (Exception handling if two nodes have the same position)
				pos_u = N.choose_distinct_random_point_in_radius_epsilon(pos_u);
			}//if2
			vector_v_minus_u = pos_v - pos_u;
			norm_v_minus_u = vector_v_minus_u.norm();

			if (!N.f_rep_near_machine_precision(norm_v_minus_u, f_rep_u_on_v))
			{
				scalar = f_rep_scalar(norm_v_minus_u) / norm_v_minus_u;
				f_rep_u_on_v.m_x = scalar * vector_v_minus_u.m_x;
				f_rep_u_on_v.m_y = scalar * vector_v_minus_u.m_y;
			}
			F_rep[v] = F_rep[v] + f_rep_u_on_v;
			F_rep[u] = F_rep[u] - f_rep_u_on_v;
		}

		//step 2: calculated forces to nodes in neighbour boxes

		//find_neighbour_boxes

		neighbour_boxes.clear();
		for (k = i - 1; k <= i + 1; k++)
		for (l = j - 1; l <= j + 1; l++)
		if ((k >= 0) && (l >= 0) && (k <= max_gridindex) && (l <= max_gridindex))
		{
			neighbour.m_x = k;
			neighbour.m_y = l;
			if ((k != i) || (l != j))
				neighbour_boxes.pushBack(neighbour);
		}


		//forget neighbour_boxes that already had access to this box
		for (const IPoint &act_neighbour_box : neighbour_boxes)
		{
			act_i = act_neighbour_box.m_x;
			act_j = act_neighbour_box.m_y;
			if ((act_j == j + 1) || ((act_j == j) && (act_i == i + 1)))
			{
				for (node v : contained_nodes(i, j)) {
					for (node u : contained_nodes(act_i, act_j))
					{
						pos_u = A[u].get_position();
						pos_v = A[v].get_position();
						if (pos_u == pos_v)
						{//  (Exception handling if two nodes have the same position)
							pos_u = N.choose_distinct_random_point_in_radius_epsilon(pos_u);
						}
						vector_v_minus_u = pos_v - pos_u;
						norm_v_minus_u = vector_v_minus_u.norm();

						if (!N.f_rep_near_machine_precision(norm_v_minus_u, f_rep_u_on_v))
						{
							scalar = f_rep_scalar(norm_v_minus_u) / norm_v_minus_u;
							f_rep_u_on_v.m_x = scalar * vector_v_minus_u.m_x;
							f_rep_u_on_v.m_y = scalar * vector_v_minus_u.m_y;
						}
						F_rep[v] = F_rep[v] + f_rep_u_on_v;
						F_rep[u] = F_rep[u] - f_rep_u_on_v;
					}
				}
			}
		}
	}
}