kamada_kawai_spring_layout.hpp
来自「CGAL is a collaborative effort of severa」· HPP 代码 · 共 543 行 · 第 1/2 页
HPP
543 行
return true; } const Graph& g; PositionMap position; WeightMap weight; EdgeOrSideLength edge_or_side_length; Done done; weight_type spring_constant; VertexIndexMap index; DistanceMatrix distance; SpringStrengthMatrix spring_strength; PartialDerivativeMap partial_derivatives; }; } } // end namespace detail::graph /// States that the given quantity is an edge length. template<typename T> inline detail::graph::edge_or_side<true, T> edge_length(T x) { return detail::graph::edge_or_side<true, T>(x); } /// States that the given quantity is a display area side length. template<typename T> inline detail::graph::edge_or_side<false, T> side_length(T x) { return detail::graph::edge_or_side<false, T>(x); } /** * \brief Determines when to terminate layout of a particular graph based * on a given relative tolerance. */ template<typename T = double> struct layout_tolerance { layout_tolerance(const T& tolerance = T(0.001)) : tolerance(tolerance), last_energy(std::numeric_limits<T>::max()), last_local_energy(std::numeric_limits<T>::max()) { } template<typename Graph> bool operator()(T delta_p, typename boost::graph_traits<Graph>::vertex_descriptor p, const Graph& g, bool global) { if (global) { if (last_energy == std::numeric_limits<T>::max()) { last_energy = delta_p; return false; } T diff = last_energy - delta_p; if (diff < T(0)) diff = -diff; bool done = (delta_p == T(0) || diff / last_energy < tolerance); last_energy = delta_p; return done; } else { if (last_local_energy == std::numeric_limits<T>::max()) { last_local_energy = delta_p; return false; } T diff = last_local_energy - delta_p; bool done = (delta_p == T(0) || diff / last_local_energy < tolerance); last_local_energy = delta_p; return done; } } private: T tolerance; T last_energy; T last_local_energy; }; /** \brief Kamada-Kawai spring layout for undirected graphs. * * This algorithm performs graph layout (in two dimensions) for * connected, undirected graphs. It operates by relating the layout * of graphs to a dynamic spring system and minimizing the energy * within that system. The strength of a spring between two vertices * is inversely proportional to the square of the shortest distance * (in graph terms) between those two vertices. Essentially, * vertices that are closer in the graph-theoretic sense (i.e., by * following edges) will have stronger springs and will therefore be * placed closer together. * * Prior to invoking this algorithm, it is recommended that the * vertices be placed along the vertices of a regular n-sided * polygon. * * \param g (IN) must be a model of Vertex List Graph, Edge List * Graph, and Incidence Graph and must be undirected. * * \param position (OUT) must be a model of Lvalue Property Map, * where the value type is a class containing fields @c x and @c y * that will be set to the @c x and @c y coordinates of each vertex. * * \param weight (IN) must be a model of Readable Property Map, * which provides the weight of each edge in the graph @p g. * * \param edge_or_side_length (IN) provides either the unit length * @c e of an edge in the layout or the length of a side @c s of the * display area, and must be either @c boost::edge_length(e) or @c * boost::side_length(s), respectively. * * \param done (IN) is a 4-argument function object that is passed * the current value of delta_p (i.e., the energy of vertex @p p), * the vertex @p p, the graph @p g, and a boolean flag indicating * whether @p delta_p is the maximum energy in the system (when @c * true) or the energy of the vertex being moved. Defaults to @c * layout_tolerance instantiated over the value type of the weight * map. * * \param spring_constant (IN) is the constant multiplied by each * spring's strength. Larger values create systems with more energy * that can take longer to stabilize; smaller values create systems * with less energy that stabilize quickly but do not necessarily * result in pleasing layouts. The default value is 1. * * \param index (IN) is a mapping from vertices to index values * between 0 and @c num_vertices(g). The default is @c * get(vertex_index,g). * * \param distance (UTIL/OUT) will be used to store the distance * from every vertex to every other vertex, which is computed in the * first stages of the algorithm. This value's type must be a model * of BasicMatrix with value type equal to the value type of the * weight map. The default is a a vector of vectors. * * \param spring_strength (UTIL/OUT) will be used to store the * strength of the spring between every pair of vertices. This * value's type must be a model of BasicMatrix with value type equal * to the value type of the weight map. The default is a a vector of * vectors. * * \param partial_derivatives (UTIL) will be used to store the * partial derivates of each vertex with respect to the @c x and @c * y coordinates. This must be a Read/Write Property Map whose value * type is a pair with both types equivalent to the value type of * the weight map. The default is an iterator property map. * * \returns @c true if layout was successful or @c false if a * negative weight cycle was detected. */ template<typename Graph, typename PositionMap, typename WeightMap, typename T, bool EdgeOrSideLength, typename Done, typename VertexIndexMap, typename DistanceMatrix, typename SpringStrengthMatrix, typename PartialDerivativeMap> bool kamada_kawai_spring_layout( const Graph& g, PositionMap position, WeightMap weight, detail::graph::edge_or_side<EdgeOrSideLength, T> edge_or_side_length, Done done, typename property_traits<WeightMap>::value_type spring_constant, VertexIndexMap index, DistanceMatrix distance, SpringStrengthMatrix spring_strength, PartialDerivativeMap partial_derivatives) { BOOST_STATIC_ASSERT((is_convertible< typename graph_traits<Graph>::directed_category*, undirected_tag* >::value)); detail::graph::kamada_kawai_spring_layout_impl< Graph, PositionMap, WeightMap, detail::graph::edge_or_side<EdgeOrSideLength, T>, Done, VertexIndexMap, DistanceMatrix, SpringStrengthMatrix, PartialDerivativeMap> alg(g, position, weight, edge_or_side_length, done, spring_constant, index, distance, spring_strength, partial_derivatives); return alg.run(); } /** * \overload */ template<typename Graph, typename PositionMap, typename WeightMap, typename T, bool EdgeOrSideLength, typename Done, typename VertexIndexMap> bool kamada_kawai_spring_layout( const Graph& g, PositionMap position, WeightMap weight, detail::graph::edge_or_side<EdgeOrSideLength, T> edge_or_side_length, Done done, typename property_traits<WeightMap>::value_type spring_constant, VertexIndexMap index) { typedef typename property_traits<WeightMap>::value_type weight_type; typename graph_traits<Graph>::vertices_size_type n = num_vertices(g); typedef std::vector<weight_type> weight_vec; std::vector<weight_vec> distance(n, weight_vec(n)); std::vector<weight_vec> spring_strength(n, weight_vec(n)); std::vector<std::pair<weight_type, weight_type> > partial_derivatives(n); return kamada_kawai_spring_layout( g, position, weight, edge_or_side_length, done, spring_constant, index, distance.begin(), spring_strength.begin(), make_iterator_property_map(partial_derivatives.begin(), index, std::pair<weight_type, weight_type>())); } /** * \overload */ template<typename Graph, typename PositionMap, typename WeightMap, typename T, bool EdgeOrSideLength, typename Done> bool kamada_kawai_spring_layout( const Graph& g, PositionMap position, WeightMap weight, detail::graph::edge_or_side<EdgeOrSideLength, T> edge_or_side_length, Done done, typename property_traits<WeightMap>::value_type spring_constant) { return kamada_kawai_spring_layout(g, position, weight, edge_or_side_length, done, spring_constant, get(vertex_index, g)); } /** * \overload */ template<typename Graph, typename PositionMap, typename WeightMap, typename T, bool EdgeOrSideLength, typename Done> bool kamada_kawai_spring_layout( const Graph& g, PositionMap position, WeightMap weight, detail::graph::edge_or_side<EdgeOrSideLength, T> edge_or_side_length, Done done) { typedef typename property_traits<WeightMap>::value_type weight_type; return kamada_kawai_spring_layout(g, position, weight, edge_or_side_length, done, weight_type(1)); } /** * \overload */ template<typename Graph, typename PositionMap, typename WeightMap, typename T, bool EdgeOrSideLength> bool kamada_kawai_spring_layout( const Graph& g, PositionMap position, WeightMap weight, detail::graph::edge_or_side<EdgeOrSideLength, T> edge_or_side_length) { typedef typename property_traits<WeightMap>::value_type weight_type; return kamada_kawai_spring_layout(g, position, weight, edge_or_side_length, layout_tolerance<weight_type>(), weight_type(1.0), get(vertex_index, g)); }} // end namespace boost#endif // BOOST_GRAPH_KAMADA_KAWAI_SPRING_LAYOUT_HPP
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?