public Graph FromStructure(Structure.Molecule molecule) { Structure.Node pivot = molecule.Nodes.First(); if (pivot == null) { return(this); } Node n = new Node(pivot.Type, new Point(0, 0)); Nodes.Add(n); visited.Add(pivot, n); DrawGraph(molecule, null, null, n, pivot); return(this); }
void DrawGraph(Structure.Molecule molecule, Bond lastBond, Structure.Bond lastInfo, Node baseNode, Structure.Node info) { List <Structure.Bond> connections = molecule.GetOther(info); if (connections.Count == 0) { return; } if (connections.Count > Structure.GetBondCount(info.Type)) { return; } List <int> availableDirs = new int[] { 1, 3, 4, 2 }.ToList(); if (lastBond != null) { availableDirs.Remove(PointToNum(lastBond.GetOther(baseNode).Location.X - baseNode.Location.X, lastBond.GetOther(baseNode).Location.Y - baseNode.Location.Y)); if (connections.Contains(lastInfo)) { connections.Remove(lastInfo); } } if (!randomStruct) { List <Structure.Bond> horizontals = connections.Where(p => p.Orientation == Structure.Orientation.Horizontal).ToList(); int horizontalCnt = (availableDirs.Contains(1) ? 1 : 0) + (availableDirs.Contains(3) ? 1 : 0); if (horizontals.Count > horizontalCnt) { horizontals = horizontals.Take(horizontalCnt).ToList(); } connections = connections.Except(horizontals).ToList(); int dir = 1; foreach (Structure.Bond bd in horizontals) { if (!availableDirs.Contains(PointToNum(dir, 0))) { dir *= -1; } Node tmpNd; if (visited.Keys.Contains(bd.GetOther(info))) { tmpNd = visited[bd.GetOther(info)]; } else { tmpNd = new Node(bd.GetOther(info).Type, new PointF(baseNode.Location.X + dir, baseNode.Location.Y)); Nodes.Add(tmpNd); } availableDirs.Remove(PointToNum(dir, 0)); dir *= -1; Bond tmpbd = new Bond(baseNode, tmpNd, bd.Type); Bonds.Add(tmpbd); if (!visited.Keys.Contains(bd.GetOther(info))) { DrawGraph(molecule, tmpbd, bd, tmpNd, bd.GetOther(info)); visited.Add(bd.GetOther(info), tmpNd); } } List <Structure.Bond> verticals = connections.Where(p => p.Orientation == Structure.Orientation.Vertical).ToList(); int verticalCnt = (availableDirs.Contains(2) ? 1 : 0) + (availableDirs.Contains(4) ? 1 : 0); if (verticals.Count > verticalCnt) { verticals = verticals.Take(verticalCnt).ToList(); } connections = connections.Except(verticals).ToList(); dir = -1; foreach (Structure.Bond bd in verticals) { if (!availableDirs.Contains(PointToNum(0, dir))) { dir *= -1; } Node tmpNd; if (visited.Keys.Contains(bd.GetOther(info))) { tmpNd = visited[bd.GetOther(info)]; } else { tmpNd = new Node(bd.GetOther(info).Type, new PointF(baseNode.Location.X, baseNode.Location.Y + dir)); Nodes.Add(tmpNd); } availableDirs.Remove(PointToNum(0, dir)); dir *= -1; Bond tmpbd = new Bond(baseNode, tmpNd, bd.Type); Bonds.Add(tmpbd); if (!visited.Keys.Contains(bd.GetOther(info))) { DrawGraph(molecule, tmpbd, bd, tmpNd, bd.GetOther(info)); visited.Add(bd.GetOther(info), tmpNd); } } } else { connections.Shuffle(); } foreach (Structure.Bond bd in connections) { PointF offset = NumToPoint(availableDirs[0]); Node tmpNd; if (visited.Keys.Contains(bd.GetOther(info))) { tmpNd = visited[bd.GetOther(info)]; } else { tmpNd = new Node(bd.GetOther(info).Type, new PointF(baseNode.Location.X + offset.X, baseNode.Location.Y + offset.Y)); Nodes.Add(tmpNd); } Bond tmpbd = new Bond(baseNode, tmpNd, bd.Type); Bonds.Add(tmpbd); if (!visited.Keys.Contains(bd.GetOther(info))) { DrawGraph(molecule, tmpbd, bd, tmpNd, bd.GetOther(info)); visited.Add(bd.GetOther(info), tmpNd); } availableDirs.RemoveAt(0); } }