Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
…-layout into master
  • Loading branch information
levnach committed May 27, 2021
2 parents 6c1171d + ddd1357 commit d1377fe
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 63 deletions.
102 changes: 39 additions & 63 deletions GraphLayout/MSAGL/Layout/Layered/SmoothedPolylineCalculator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ internal class SmoothedPolylineCalculator {
PolyIntEdge edgePath;
Anchor[] anchors;
GeometryGraph originalGraph;
ParallelogramNode rightHierarchy;
ParallelogramNode leftHierarchy;
ParallelogramNode thinRightHierarchy;
ParallelogramNode thinLeftHierarchy;
ParallelogramNode eastHierarchy;
ParallelogramNode westHierarchy;
ParallelogramNode thinEastHierarchy;
ParallelogramNode thinWestHierarchy;
List<ParallelogramNode> thinRightNodes = new List<ParallelogramNode>();
List<ParallelogramNode> thinLefttNodes = new List<ParallelogramNode>();
Database database;
Expand All @@ -41,33 +41,33 @@ internal SmoothedPolylineCalculator(PolyIntEdge edgePathPar, Anchor[] anchorsP,
this.originalGraph = origGraph;
this.settings = settings;
this.layeredGraph = layerGraph;
rightHierarchy = BuildRightHierarchy();
leftHierarchy = BuildLeftHierarchy();
eastHierarchy = BuildEastHierarchy();
westHierarchy = BuildWestHierarchy();
}

private ParallelogramNode BuildRightHierarchy() {
List<Polyline> boundaryAnchorsCurves = FindRightBoundaryAnchorCurves();
private ParallelogramNode BuildEastHierarchy() {
List<Polyline> boundaryAnchorsCurves = FindEastBoundaryAnchorCurves();
List<ParallelogramNode> l = new List<ParallelogramNode>();
foreach (Polyline c in boundaryAnchorsCurves)
l.Add(c.ParallelogramNodeOverICurve);

this.thinRightHierarchy = HierarchyCalculator.Calculate(thinRightNodes, this.settings.GroupSplit);
this.thinEastHierarchy = HierarchyCalculator.Calculate(thinRightNodes, this.settings.GroupSplit);

return HierarchyCalculator.Calculate(l, this.settings.GroupSplit);
}

private ParallelogramNode BuildLeftHierarchy() {
List<Polyline> boundaryAnchorCurves = FindLeftBoundaryAnchorCurves();
private ParallelogramNode BuildWestHierarchy() {
List<Polyline> boundaryAnchorCurves = FindWestBoundaryAnchorCurves();
List<ParallelogramNode> l = new List<ParallelogramNode>();
foreach (Polyline a in boundaryAnchorCurves)
l.Add(a.ParallelogramNodeOverICurve);

this.thinLeftHierarchy = HierarchyCalculator.Calculate(thinLefttNodes, this.settings.GroupSplit);
this.thinWestHierarchy = HierarchyCalculator.Calculate(thinLefttNodes, this.settings.GroupSplit);

return HierarchyCalculator.Calculate(l, this.settings.GroupSplit);
}

List<Polyline> FindRightBoundaryAnchorCurves() {
List<Polyline> FindEastBoundaryAnchorCurves() {
List<Polyline> ret = new List<Polyline>();
int uOffset = 0;

Expand Down Expand Up @@ -101,7 +101,7 @@ List<Polyline> FindRightBoundaryAnchorCurves() {
return ret;
}

private List<Polyline> FindLeftBoundaryAnchorCurves() {
private List<Polyline> FindWestBoundaryAnchorCurves() {
List<Polyline> ret = new List<Polyline>();
int uOffset = 0;

Expand Down Expand Up @@ -320,61 +320,35 @@ internal SmoothedPolyline GetPolyline {

bool LineSegIntersectBound(Point a, Point b) {
var l = new LineSegment(a, b);
return CurveIntersectsHierarchy(l, leftHierarchy) || CurveIntersectsHierarchy(l, thinLeftHierarchy) ||
CurveIntersectsHierarchy(l, rightHierarchy) || CurveIntersectsHierarchy(l, thinRightHierarchy);
return CurveIntersectsHierarchy(l, westHierarchy) || CurveIntersectsHierarchy(l, thinWestHierarchy) ||
CurveIntersectsHierarchy(l, eastHierarchy) || CurveIntersectsHierarchy(l, thinEastHierarchy);
}

bool SegIntersectRightBound(Site a, Site b) {
return SegIntersectsBound(a, b, leftHierarchy) || SegIntersectsBound(a, b, this.thinLeftHierarchy);
bool SegIntersectEastBound(Site a, Site b) {
return SegIntersectsBound(a, b, westHierarchy) || SegIntersectsBound(a, b, this.thinWestHierarchy);
}

bool SegIntersectLeftBound(Site a, Site b) {
return SegIntersectsBound(a, b, rightHierarchy) || SegIntersectsBound(a, b, this.thinRightHierarchy);
bool SegIntersectWestBound(Site a, Site b) {
return SegIntersectsBound(a, b, eastHierarchy) || SegIntersectsBound(a, b, this.thinEastHierarchy);
}

private bool TryToRemoveInflectionEdge(ref Site s) {
if (s.Next.Next == null)
return false;
if (s.Previous == null)
return false;
private Site TryToRemoveInflectionEdge(Site s, out bool cut) {

if (s.Turn < 0) {//left turn at s
if (!SegIntersectRightBound(s, s.Next.Next) && !SegIntersectLeftBound(s, s.Next.Next)) {
Site n = s.Next.Next;
s.Next = n; //forget about s.next
n.Previous = s;
s = n;
return true;
}

if (!SegIntersectLeftBound(s.Previous, s.Next) && !SegIntersectRightBound(s.Previous, s.Next)) {
Site a = s.Previous; //forget s
Site b = s.Next;
a.Next = b;
b.Previous = a;
s = b;
return true;
}
if (s.Next == null || s.Previous == null) {
cut = false;
return s.Next;
}
else {//right turn at s
if (!SegIntersectLeftBound(s, s.Next.Next) && !SegIntersectRightBound(s, s.Next.Next)) {
Site n = s.Next.Next;
s.Next = n; //forget about s.next
n.Previous = s;
s = n;
return true;
}

if (!SegIntersectRightBound(s.Previous, s.Next) && SegIntersectLeftBound(s.Previous, s.Next)) {
Site a = s.Previous; //forget s
Site b = s.Next;
a.Next = b;
b.Previous = a;
s = b;
return true;
}
if ((s.Turn > 0 && SegIntersectEastBound(s.Previous, s.Next)) || (s.Turn < 0 && SegIntersectWestBound(s.Previous, s.Next))) {
cut = false;
return s.Next;
}
return false;
Site ret = s.Next;
s.Previous.Next = s.Next; //forget about s
s.Next.Previous = s.Previous;
cut = true;
return ret;

}


Expand Down Expand Up @@ -630,8 +604,10 @@ private void TryToRemoveInflections() {
bool progress = true;
while (progress) {
progress = false;
for (Site s = this.headSite; s != null && s.Next != null; s = s.Next) {
progress = TryToRemoveInflectionEdge(ref s) || progress;
for (Site s = this.headSite; s != null; ) {
bool cut;
s = TryToRemoveInflectionEdge(s, out cut);
progress |= cut;
}
}
}
Expand Down Expand Up @@ -760,9 +736,9 @@ private void AddSmoothedCorner(Site a, Site b, Site c, Curve curve) {
private bool BezierSegIntersectsBoundary(CubicBezierSegment seg) {
double side = Point.SignedDoubledTriangleArea(seg.B(0), seg.B(1), seg.B(2));
if (side > 0)
return BezierSegIntersectsTree(seg, thinLeftHierarchy) || BezierSegIntersectsTree(seg, leftHierarchy);
return BezierSegIntersectsTree(seg, thinWestHierarchy) || BezierSegIntersectsTree(seg, westHierarchy);
else
return BezierSegIntersectsTree(seg, thinRightHierarchy) || BezierSegIntersectsTree(seg, rightHierarchy);
return BezierSegIntersectsTree(seg, thinEastHierarchy) || BezierSegIntersectsTree(seg, eastHierarchy);
}

private bool BezierSegIntersectsTree(CubicBezierSegment seg, ParallelogramNode tree) {
Expand Down
15 changes: 15 additions & 0 deletions GraphLayout/Test/MSAGLTests/Layout/Layered/SugiyamaLayoutTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using System.Collections.Generic;
using System.IO;
using Dot2Graph;
using Microsoft.Msagl.Core.Geometry;
using Microsoft.Msagl.Core.Geometry.Curves;
using Microsoft.Msagl.Core.Layout;
using Microsoft.Msagl.Layout.Incremental;
Expand Down Expand Up @@ -109,6 +110,20 @@ public void RandomDotFileTests()
}
}

[TestMethod]
[Description("Generate one simple graph and do Sugiyam layout testing")]
public void OnlyNodes() {
// GraphViewerGdi.DisplayGeometryGraph.SetShowFunctions();
var graph = new GeometryGraph();
graph.Nodes.Add(new Node() { BoundaryCurve = CurveFactory.CreateCircle(80, new Point(0, 0)) });
graph.Nodes.Add(new Node() { BoundaryCurve = CurveFactory.CreateCircle(20, new Point(0, 0)) });
graph.Nodes.Add(new Node() { BoundaryCurve = CurveFactory.CreateCircle(100, new Point(0, 0)) });
SugiyamaLayoutSettings settings = new SugiyamaLayoutSettings();
WriteLine("Trying nodes only graph with ");
LayoutAndValidate(graph, settings);

}

[TestMethod]
[Description("Generate one simple graph and do Sugiyam layout testing")]
public void SimpleGraphTests()
Expand Down

0 comments on commit d1377fe

Please sign in to comment.