in GraphLayout/MSAGL/GraphmapsWithMesh/MeshCreator.cs [253:415]
public static void CreateCompetitionMesh(Tiling g, Dictionary<int, Node> idToNode, int maxX, int maxY)
{
//for each node, create four line segments
CreateFourRaysPerVertex(g, maxX, maxY);
Dictionary<LineSegment, int> removeList = new Dictionary<LineSegment, int>();
Dictionary<LineSegment, int> addList = new Dictionary<LineSegment, int>();
for (int iteration = 0; iteration <= Math.Max(maxX, maxY); iteration++)
{
//for each line segment check whether it hits any other segment or point
//if so then create a new junction at that point
for (int nodeIndex1 = 0; nodeIndex1 < g.N; nodeIndex1++)
{
foreach (LineSegment ls1 in g.VList[nodeIndex1].SegmentList.Keys)
{
if (g.VList[nodeIndex1].SegmentList[ls1] == false) continue;
for (int nodeIndex2 = 0; nodeIndex2 < g.N; nodeIndex2++)
{
if (nodeIndex1 == nodeIndex2) continue;
foreach (LineSegment ls2 in g.VList[nodeIndex2].SegmentList.Keys)
{
if (MsaglUtilities.PointIsOnAxisAlignedSegment(ls2, ls1.End))
{
//if they are parallel then create an edge
if (((int)ls1.Start.X == (int)ls1.End.X && (int)ls2.Start.X == (int)ls2.End.X)
|| ((int)ls1.Start.Y == (int)ls1.End.Y && (int)ls2.Start.Y == (int)ls2.End.Y))
{
if ((int)ls1.End.X == (int)ls2.Start.X && (int)ls1.End.Y == (int)ls2.Start.Y) continue;
int a = FindVertexClosestToSegmentEnd(g, ls1);
int b = FindVertexClosestToSegmentEnd(g, ls2);
if (a == b)
{
// degenerate parallel collision
//Point coordinates multiplied by 4 so that this condition does not arise.
}
if (g.AddEdge(a, b))
{
LineSegment l = new LineSegment(ls1.Start, ls2.Start);
if (!addList.ContainsKey(l)) addList.Add(l, -1);
l = new LineSegment(ls2.Start, ls1.Start);
if (!addList.ContainsKey(l)) addList.Add(l, -1);
if (!removeList.ContainsKey(ls1)) removeList.Add(ls1, nodeIndex1);
if (!removeList.ContainsKey(ls2)) removeList.Add(ls2, nodeIndex2);
}
}
//create a new node at the intersection point
else
{
if (MsaglUtilities.PointIsOnAxisAlignedSegment(ls2, ls1.End) &&
MsaglUtilities.PointIsOnAxisAlignedSegment(ls1, ls2.End) &&
nodeIndex1 > nodeIndex2) continue;
if (g.GetNode((int)ls1.End.X, (int)ls1.End.Y) == -1)
{
//create the edges
int a = FindClosestVertexWhileWalkingToStart(g, ls2, ls1.End);
int b = FindClosestVertexWhileWalkingToEnd(g, ls2, ls1.End);
int c = FindVertexClosestToSegmentEnd(g, ls1);
int d = g.NumOfnodes;
g.VList[d] = new Vertex((int)ls1.End.X, (int)ls1.End.Y) { Id = d };
g.NumOfnodes++;
if (a >= 0) g.AddEdge(a, d);
if (b >= 0) g.AddEdge(b, d);
if (c >= 0) g.AddEdge(c, d);
if (a == b)
System.Diagnostics.Debug.WriteLine("degenerate orthogonal collision");
if (a >= 0 && b >= 0) g.RemoveEdge(a, b);
if (!removeList.ContainsKey(ls1))
{
removeList.Add(ls1, nodeIndex1);
if (!addList.ContainsKey(ls1)) addList.Add(ls1, -1);
}
}
else
{
int a = g.GetNode((int)ls1.End.X, (int)ls1.End.Y);
int b = FindVertexClosestToSegmentEnd(g, ls1);
if (b == -1)
System.Diagnostics.Debug.WriteLine("vertex not found error");
g.AddEdge(a, b);
if (!removeList.ContainsKey(ls1))
{
removeList.Add(ls1, nodeIndex1);
if (!addList.ContainsKey(ls1)) addList.Add(ls1, -1);
}
}
}
}
}
}
}
}
foreach (var s in removeList)
{
g.VList[s.Value].SegmentList.Remove(s.Key);
}
removeList.Clear();
foreach (var s in addList)
{
if (s.Value >= 0) g.VList[s.Value].SegmentList.Add(s.Key, true);
else g.VList[g.GetNode((int)s.Key.Start.X, (int)s.Key.Start.Y)].SegmentList.Add(s.Key, false);
}
addList.Clear();
int nodeIndex;
for (nodeIndex = 0; nodeIndex < g.N; nodeIndex++)
{
foreach (LineSegment ls in g.VList[nodeIndex].SegmentList.Keys)
{
if (g.VList[nodeIndex].SegmentList[ls] == false) continue;
Core.Geometry.Point nextPoint = GrowOneUnit(ls, maxX + 1, maxY + 1);
if (nextPoint.X >= 0)
{
LineSegment l_new = new LineSegment(ls.Start, nextPoint);
if (!addList.ContainsKey(l_new)) addList.Add(l_new, nodeIndex);
if (!removeList.ContainsKey(ls)) removeList.Add(ls, nodeIndex);
}
}
}
foreach (var s in removeList)
{
g.VList[s.Value].SegmentList.Remove(s.Key);
}
removeList.Clear();
foreach (var s in addList)
{
if (s.Value >= 0) g.VList[s.Value].SegmentList.Add(s.Key, true);
else g.VList[g.GetNode((int)s.Key.Start.X, (int)s.Key.Start.Y)].SegmentList.Add(s.Key, false);
}
addList.Clear();
}
FixMesh(g);
}