// smooth vertices, but don't move further than max_move protected void smooth_pass(DGraph2 graph, int passes, double smooth_alpha, double max_move) { double max_move_sqr = max_move * max_move; int NV = graph.MaxVertexID; DVector <Vector2d> smoothedV = offset_cache; if (smoothedV.size < NV) { smoothedV.resize(NV); } if (position_cache.size < NV) { position_cache.resize(NV); } for (int pi = 0; pi < passes; ++pi) { gParallel.ForEach(Interval1i.Range(NV), (vid) => { if (!graph.IsVertex(vid)) { return; } Vector2d v = graph.GetVertex(vid); Vector2d c = Vector2d.Zero; int n = 0; foreach (int vnbr in graph.VtxVerticesItr(vid)) { c += graph.GetVertex(vnbr); n++; } if (n >= 2) { c /= n; Vector2d dv = (smooth_alpha) * (c - v); if (dv.LengthSquared > max_move_sqr) { /*double d = */ dv.Normalize(); dv *= max_move; } v += dv; } smoothedV[vid] = v; }); if (pi == 0) { for (int vid = 0; vid < NV; ++vid) { if (graph.IsVertex(vid)) { position_cache[vid] = graph.GetVertex(vid); graph.SetVertex(vid, smoothedV[vid]); } } } else { for (int vid = 0; vid < NV; ++vid) { if (graph.IsVertex(vid)) { graph.SetVertex(vid, smoothedV[vid]); } } } } for (int vid = 0; vid < NV; ++vid) { if (graph.IsVertex(vid)) { graph_cache.UpdatePointUnsafe(vid, position_cache[vid], smoothedV[vid]); } } }