示例#1
0
		private void ShiftNode(GraphNode node, ShiftTo shiftType, bool opposite)
		{
			float sign = 1.0f; 
			if (opposite)
				sign = -1.0f;
	
			switch (shiftType)
			{

				case ShiftTo.Up:
					node.Bounds = new RectangleF(
						node.Bounds.X,
						node.Bounds.Y - sign * _moveValue,
						node.Bounds.Width,
						node.Bounds.Height);
					break;

				case ShiftTo.Down:
					node.Bounds = new RectangleF(
						node.Bounds.X,
						node.Bounds.Y + sign * _moveValue,
						node.Bounds.Width,
						node.Bounds.Height);
					break;

				case ShiftTo.Left:
					node.Bounds = new RectangleF(
						node.Bounds.X - sign * _moveValue,
						node.Bounds.Y,
						node.Bounds.Width,
						node.Bounds.Height);
					break;

				case ShiftTo.Right:
					node.Bounds = new RectangleF(
						node.Bounds.X + sign * _moveValue,
						node.Bounds.Y,
						node.Bounds.Width,
						node.Bounds.Height);
					break;

				case ShiftTo.UpLeft:
					node.Bounds = new RectangleF(
						node.Bounds.X - sign * _moveValue,
						node.Bounds.Y - sign * _moveValue,
						node.Bounds.Width,
						node.Bounds.Height);
					break;

				case ShiftTo.UpRight:
					node.Bounds = new RectangleF(
						node.Bounds.X + sign * _moveValue,
						node.Bounds.Y - sign * _moveValue,
						node.Bounds.Width,
						node.Bounds.Height);
					break;

				case ShiftTo.DownLeft:
					node.Bounds = new RectangleF(
						node.Bounds.X - sign * _moveValue,
						node.Bounds.Y + sign * _moveValue,
						node.Bounds.Width,
						node.Bounds.Height);
					break;

				case ShiftTo.DownRight:
					node.Bounds = new RectangleF(
						node.Bounds.X + sign * _moveValue,
						node.Bounds.Y + sign * _moveValue,
						node.Bounds.Width,
						node.Bounds.Height);
					break;

			}
		}
示例#2
0
		private float EvaluateGrid(GraphNode[,] grid, int maxShift)
		{
			ApplyGrid(grid);
			float eval = 0;

			// Total arrow length; shorter arrow mean nodes are closer
			// so we would like that sum to be minimal
			foreach (GraphLink link in _graph.Links)
			{
				Point gridPos1 = (Point)link.Origin.GetData(_GridPos);
				Point gridPos2 = (Point)link.Destination.GetData(_GridPos);

				int dx = Math.Abs(gridPos1.X - gridPos2.X);
				int dy = Math.Abs(gridPos1.Y - gridPos2.Y);
				if (dx + dy > 1)
					eval += (dx * dx + dy * dy);
			}

			// Nodeta koito ne sa svurzani da im davame poveche tochki ako
			// sa blizki (znachi ne ni kefjat; zelta e da sa po-malko tochkite)
			foreach (GraphNode node in _graph.Nodes)
			{
				Point gridPos = (Point)node.GetData(_GridPos);
				int col = gridPos.X;
				int row = gridPos.Y;
				float toadd = 0;

				for (int k = -1; k <= +1; k++)
				{
					for (int l = -1; l <= +1; l++)
					{
						if (k == 0 && l == 0) continue;
						if ((k + l) % 2 == 0) continue;
						int neighborCol = col + k;
						int neighborRow = row + l;
						GraphNode neighbor = grid[1 + neighborCol, 1 + neighborRow];
						if (neighbor == null) continue;
						if (!NodesLinked(node, neighbor))
							toadd += 1.0f;
					}
				}

				eval += toadd;
			}

			return eval;
		}
示例#3
0
		private void ApplyGrid(GraphNode[,] grid)
		{
			for (int i = 0; i < _gridWidth; ++i)
			{
				for (int j = 0; j < _gridHeight; ++j)
				{
					GraphNode node = grid[1 + i, 1 + j];
					if (node != null)
						node.SetData(_GridPos, new Point(i, j));
				}
			}
		}
示例#4
0
		private GraphNode[,] InitGrid()
		{
			int nodeCount = _graph.Nodes.Count;

			_gridWidth = _gridHeight = (int)Math.Ceiling(Math.Sqrt(nodeCount)) + 2;

			GraphNode[,] grid = new GraphNode[_gridWidth + 2, _gridHeight + 2];
			GraphNode node0 = _backbone[0] as GraphNode;
			node0.SetData(_GridPos, new Point(0, 0));
			grid[1, 1] = node0;

			int perRow = Math.Max(1, _backbone.Count / _gridHeight + 1);
			int curRow = 0;
			float curCol = 0;
			int c = 0;
			for (int i = 0; i < _backbone.Count - 1; i++)
			{
				int nodeCol = (int)curCol + c;
				int nodeRow = curRow;
				GraphNode node = _backbone[i] as GraphNode;
				node.SetData(_GridPos, new Point(nodeCol, nodeRow));
				grid[1 + nodeCol, 1 + nodeRow] = node;

				c++;
				if (c == perRow)
				{
					c = 0;
					curCol += ((float)_gridWidth - perRow) / _gridHeight;
					curRow++;
				}
			}

			c = 0;
			for (int i = 0; i < nodeCount; i++)
			{
				int nodeCol = i % _gridHeight;
				int nodeRow = i / _gridHeight;

				if (grid[1 + nodeCol, 1 + nodeRow] != null)
					continue;

				while (c < nodeCount && _backbone.Contains(_graph.Nodes[c]))
					c++;

				if (c == nodeCount) break;

				GraphNode node = _graph.Nodes[c] as GraphNode;
				node.SetData(_GridPos, new Point(nodeCol, nodeRow));
				grid[1 + nodeCol, 1 + nodeRow] = node;

				if (c == nodeCount - 1) break;

				c++;
			}

			GraphNode nodeN = _backbone[_backbone.Count - 1] as GraphNode;
			nodeN.SetData(_GridPos, new Point(_gridWidth - 1, _gridHeight - 1));
			grid[1 + _gridWidth - 1, 1 + _gridHeight - 1] = nodeN;

			return grid;
		}
示例#5
0
		Size CalcLinkDir(GraphNode node)
		{
			int xEval = 0, yEval = 0;
			Point gridPos1 = (Point)node.GetData(_GridPos);

			foreach (GraphLink link in node.OutLinks)
			{
				Point gridPos2 = (Point)link.Destination.GetData(_GridPos);

				xEval += gridPos2.X - gridPos1.X;
				yEval += gridPos2.Y - gridPos1.Y;
			}

			foreach (GraphLink link in node.InLinks)
			{
				Point gridPos2 = (Point)link.Origin.GetData(_GridPos);

				xEval += gridPos2.X - gridPos1.X;
				yEval += gridPos2.Y - gridPos1.Y;
			}

			if (xEval > 0) xEval = 1;
			if (xEval < 0) xEval = -1;
			if (yEval > 0) yEval = 1;
			if (yEval < 0) yEval = -1;

			return new Size(xEval, yEval);
		}
示例#6
0
		private bool MoveLeft(GraphNode node, ArrayList layer, double priority)
		{
			int index = layer.IndexOf(node);
			if (index == 0)
			{
				// This is the last node in the layer - 
				// so we can move to the left without troubles
				node.SetData(_GridPosition, (double)node.GetData(_GridPosition) - 0.5);
				return true;
			}

			GraphNode leftNode = layer[index - 1] as GraphNode;

			double leftNodePriority = ((double)leftNode.GetData(_UPriority) +
				(double)leftNode.GetData(_DPriority)) / 2;

			// Check if there is space
			// between the left and the current node
			if ((double)leftNode.GetData(_GridPosition) <
				(double)node.GetData(_GridPosition) - 1)
			{
				node.SetData(_GridPosition, (double)node.GetData(_GridPosition) - 0.5);
				return true;
			}

			// We have reached a node with higher priority - 
			// no movement is allowed
			if (leftNodePriority > priority ||
				Math.Abs(leftNodePriority - priority) < double.Epsilon)
				return false;

			// The left node has lower priority - try to move it
			if (MoveLeft(leftNode, layer, priority))
			{
				node.SetData(_GridPosition, (double)node.GetData(_GridPosition) - 0.5);
				return true;
			}

			return false;
		}
示例#7
0
		private void Dummify()
		{
			ArrayList links = new ArrayList(_graph.Links);
			foreach (GraphLink link in links)
			{
				GraphNode o = link.Origin;
				GraphNode d = link.Destination;

				int oLayer = (int)o.GetData(_Layer);
				int dLayer = (int)d.GetData(_Layer);
				double oPos = (double)o.GetData(_GridPosition);
				double dPos = (double)d.GetData(_GridPosition);

				double step = (dPos - oPos) / Math.Abs(dLayer - oLayer);

				GraphNode p = o;
				if (oLayer - dLayer > 1)
				{
					for (int i = oLayer - 1; i > dLayer; i--)
					{
						GraphNode newNode = new GraphNode(o.Bounds);
						ArrayList layer = _layers[i] as ArrayList;

						double pos = (i - dLayer) * step + oPos;

						if (pos > layer.Count)
							pos = layer.Count;

						// Check if origin and dest are both last
						if (oPos >= (_layers[oLayer] as ArrayList).Count - 1 &&
							dPos >= (_layers[dLayer] as ArrayList).Count - 1)
							pos = layer.Count;

						// Check if origin and destination are both first
						else if (oPos == 0 && dPos == 0)
							pos = 0;

						newNode.SetData(_Layer, i);
						newNode.SetData(_UBaryCenter, 0.0);
						newNode.SetData(_DBaryCenter, 0.0);
						newNode.SetData(_ULinkCount, 0);
						newNode.SetData(_DLinkCount, 0);
						newNode.SetData(_GridPosition, pos);
						newNode.SetData(_Dummy, true);
						layer.Insert((int)pos, newNode);

						// Translate rightwards nodes' positions
						for (int r = (int)pos + 1; r < layer.Count; r++)
						{
							GraphNode node = layer[r] as GraphNode;
							node.SetData(_GridPosition,
								(double)node.GetData(_GridPosition) + 1);
						}

						GraphLink newLink = new GraphLink(p, newNode);
						newLink.SetData(_DummificationLevel, 0);
						p = newNode;

						// Add the new node and the new link to the graph
						_graph.Nodes.Add(newNode);
						_graph.Links.Add(newLink);
					}

					// Set the origin of the real arrow to the last dummy
					link.Origin = p;
					link.SetData(_DummificationLevel, oLayer - dLayer - 1);
				}

				if (oLayer - dLayer < -1)
				{
					for (int i = oLayer + 1; i < dLayer; i++)
					{
						GraphNode newNode = new GraphNode(o.Bounds);
						ArrayList layer = _layers[i] as ArrayList;

						double pos = (i - oLayer) * step + oPos;

						if (pos > layer.Count)
							pos = layer.Count;

						// Check if origin and dest are both last
						if (oPos >= (_layers[oLayer] as ArrayList).Count - 1 &&
							dPos >= (_layers[dLayer] as ArrayList).Count - 1)
							pos = layer.Count;

						// Check if origin and destination are both first
						else if (oPos == 0 && dPos == 0)
							pos = 0;

						newNode.SetData(_Layer, i);
						newNode.SetData(_UBaryCenter, 0.0);
						newNode.SetData(_DBaryCenter, 0.0);
						newNode.SetData(_ULinkCount, 0);
						newNode.SetData(_DLinkCount, 0);
						newNode.SetData(_GridPosition, pos);
						newNode.SetData(_Dummy, true);
						layer.Insert((int)pos, newNode);

						// Translate rightwards nodes' positions
						for (int r = (int)pos + 1; r < layer.Count; r++)
						{
							GraphNode node = layer[r] as GraphNode;
							node.SetData(_GridPosition,
								(double)node.GetData(_GridPosition) + 1);
						}

						GraphLink newLink = new GraphLink(p, newNode);
						newLink.SetData(_DummificationLevel, 0);
						p = newNode;

						// Add the new node and the new link to the graph
						_graph.Nodes.Add(newNode);
						_graph.Links.Add(newLink);
					}

					// Set the origin of the real arrow to the last dummy
					link.Origin = p;
					link.SetData(_DummificationLevel, dLayer - oLayer - 1);
				}
			}
		}
示例#8
0
		private double evalEdgeCrossingsCost(GraphNode node)
		{
			int crossingCount = 0;

			foreach (GraphLink link in node.InLinks)
				if (link.Origin != link.Destination)
					crossingCount += countCrossings(link);

			foreach (GraphLink link in node.OutLinks)
				if (link.Origin != link.Destination)
					crossingCount += countCrossings(link);
			
			return _info.CrossingEdgesCost * crossingCount;
		}
示例#9
0
		private double evalCost(GraphNode node)
		{
			return
				evalDistributionCost(node) +
				evalBoundaryCost(node) +
				evalEdgeLengthsCost(node) +
				evalEdgeCrossingsCost(node);
		}
示例#10
0
		private double evalBoundaryCost(GraphNode node)
		{
			double l, t, r, b;

			l = node.Center.X - _drawingArea.Left;
			t = node.Center.Y - _drawingArea.Top;
			r = _drawingArea.Right - node.Center.X;
			b = _drawingArea.Bottom - node.Center.Y;

			return _info.BoundaryFactor * (1 / (r * r) + 1 / (l * l) + 1 / (t * t) + 1 / (b * b)); 
		}
示例#11
0
		private double evalEdgeLengthsCost(GraphNode node)
		{
			double sum = 0.0f;

			foreach (GraphLink link in node.InLinks)
				if (link.Origin != link.Destination)
					sum += squareDistance(link.Origin, link.Destination);

			foreach (GraphLink link in node.OutLinks)
				if (link.Origin != link.Destination)
					sum += squareDistance(link.Origin, link.Destination);

			return _info.EdgeLengthFactor * sum;
		}
示例#12
0
		private double evalDistributionCost(GraphNode node)
		{
			double sum = 0.0f;
	
			for (int i = 0; i < _nodes.Length; i++)
			{
				if (node == _nodes[i])
					continue;

				double distance = squareDistance(_nodes[i], node);
				if (distance == 0)
					distance = 0.00001f;
				sum += _info.DistributionFactor / distance;
			}

			return sum;
		}
示例#13
0
		private bool nodeInBounds(GraphNode node)
		{
			double l, t, r, b;

			l = node.Center.X - _drawingArea.Left;
			t = node.Center.Y - _drawingArea.Top;
			r = _drawingArea.Right - node.Center.X;
			b = _drawingArea.Bottom - node.Center.Y;

			return !(r < 0 || t < 0 || l < 0 || b < 0);
		}
示例#14
0
		private double squareDistance(GraphNode node1, GraphNode node2)
		{
			PointF p1 = node1.Center;
			PointF p2 = node2.Center;
			return Math.Max(0, (p1.X - p2.X) * (p1.X - p2.X) + (p1.Y - p2.Y) * (p1.Y - p2.Y)
				- Math.Pow(lengthFix(node1, node2), 2));
		}
示例#15
0
		private void RollbackMove(GraphNode node)
		{
			_glBordLinesCost = _glBordLinesCost + (double)node.GetData(BordLines) - _bordNewLocalValue;
		}
示例#16
0
		private double evalTuningCost(GraphNode node)
		{
			return evalCost(node) + nodeEdgeDistance();
		}
示例#17
0
		/// <summary>
		/// Calculates the barycenter of a node.
		/// </summary>
		internal static double CalcBaryCenter(GraphNode node)
		{
			int uLinkCount = (int)node.GetData(_ULinkCount);
			int dLinkCount = (int)node.GetData(_DLinkCount);
			double uBaryCenter = (double)node.GetData(_UBaryCenter);
			double dBaryCenter = (double)node.GetData(_DBaryCenter);

			if (uLinkCount > 0 && dLinkCount > 0)
				return (uBaryCenter + dBaryCenter) / 2;
			if (uLinkCount > 0)
				return uBaryCenter;
			if (dLinkCount > 0)
				return dBaryCenter;

			return 0;
		}
示例#18
0
		private double CostFunction(GraphNode node)
		{
			CalcNewGlobalCost(node);

			return NodeDistribution() + _glBordLinesCost + EdgeLengths() + EdgeCrossings();
		}
示例#19
0
		private void AddChildren(GraphNode node)
		{
			ArrayList next = new ArrayList();
			foreach (GraphLink link in node.OutLinks)
			{
				GraphNode child = link.Destination;
				int nodeLayer = (int)node.GetData(_Layer);
				int childLayer = (int)child.GetData(_Layer);
				if (childLayer == -1 && nodeLayer < _layers.Count - 1)
				{
					child.SetData(_Layer, nodeLayer + 1);
					(_layers[nodeLayer + 1] as ArrayList).Add(child);
					next.Add(child);
				}
				else if (childLayer == -1)
				{
					_layers.Add(new ArrayList());
					child.SetData(_Layer, nodeLayer + 1);
					(_layers[nodeLayer] as ArrayList).Add(child);
					next.Add(child);
				}
			}
			foreach (GraphLink link in node.InLinks)
			{
				GraphNode child = link.Origin;
				int nodeLayer = (int)node.GetData(_Layer);
				int childLayer = (int)child.GetData(_Layer);
				if (childLayer == -1 && nodeLayer > 0)
				{
					child.SetData(_Layer, nodeLayer - 1);
					(_layers[nodeLayer - 1] as ArrayList).Add(child);
					next.Add(child);
				}
				else if (childLayer == -1)
				{
					child.SetData(_Layer, 0);
					(_layers[0] as ArrayList).Add(child);
					next.Add(child);
				}
			}

			foreach (GraphNode child in next)
				AddChildren(child);
		}
示例#20
0
		private double RichCostFunction(GraphNode node)
		{
			return CostFunction(node) + NodeEdgeDistance2();
		}
示例#21
0
		public GraphLink(GraphNode origin, GraphNode destination)
		{
			_data = new SortedList();
			_link = null;
			_origin = origin;
			_destination = destination;

			_origin.OutLinks.Add(this);
			_destination.InLinks.Add(this);
		}
示例#22
0
		private float lengthFix(GraphNode node1, GraphNode node2)
		{
			return
				(node1.Bounds.Width + node1.Bounds.Height) / 4 +
				(node2.Bounds.Width + node2.Bounds.Height) / 4;
		}
示例#23
0
		private GraphNode[,] ScrambleGrid(GraphNode[,] grid, int maxShift, int iter)
		{
			// Da ne e savsem random ami da gleda poveche da murda boxovete s 
			// poveche linkove - i v posoka na linkovete ?
			GraphNode[,] newGrid = (GraphNode[,])grid.Clone();

			if (maxShift > 2)
			{
				for (int i = 0; i < _gridWidth; i++)
					for (int j = 0; j < _gridHeight; ++j)
						ScrambleGridStep(newGrid, maxShift, iter, i, j);
			}
			else
			{
				int c = iter % _graph.Nodes.Count;
				Point pt = (Point)(_graph.Nodes[c] as GraphNode).GetData(_GridPos);
				ScrambleGridStep(newGrid, maxShift, iter, pt.X, pt.Y);
			}

			return newGrid;
		}
示例#24
0
		private float lengthFix(GraphNode node)
		{
			return (node.Bounds.Width + node.Bounds.Height) / 4;
		}
示例#25
0
		private void ScrambleGridStep(GraphNode[,] newGrid,
			int maxShift, int iter, int i, int j)
		{
			GraphNode node1 = newGrid[1 + i, 1 + j];
			if (node1 == null) return;

			int col = i;
			int row = j;

			// Choose a new position
			Size dir = CalcLinkDir(node1);

			int newCol = maxShift > 1 ?
				col + dir.Width * _random.Next(0, maxShift + 1) + _random.Next(-1, 1 + 1) :
				col + dir.Width * _random.Next(0, 1 + 1);
			int newRow = maxShift > 1 ?
				row + dir.Height * _random.Next(0, maxShift + 1) + _random.Next(-1, 1 + 1) :
				row + dir.Height * _random.Next(0, 1 + 1);

			if (newCol < 0) newCol = 0;
			if (newCol >= _gridWidth) newCol = _gridWidth - 1;
			if (newRow < 0) newRow = 0;
			if (newRow >= _gridHeight) newRow = _gridHeight - 1;

			// Swap node1 with what's at the new pos
			GraphNode node2 = newGrid[1 + newCol, 1 + newRow];

			// Start & end nodes are static
			INode startNode = _info.StartNode;
			INode endNode = _info.EndNode;

			if (startNode != null)
			{
				if (node1.Node == startNode ||
					(node2 != null && node2.Node == startNode))
					return;
			}

			if (endNode != null)
			{
				if (node1.Node == endNode ||
					(node2 != null && node2.Node == endNode))
					return;
			}

			newGrid[1 + newCol, 1 + newRow] = node1;
			newGrid[1 + i, 1 + j] = node2;

			node1.SetData(_GridPos, new Point(newCol, newRow));
			if (node2 != null)
				node2.SetData(_GridPos, new Point(i, j));
		}
示例#26
0
		private void CalcNewGlobalCost(GraphNode node)
		{
			_bordNewLocalValue = evalBoundaryCost(node);
			_glBordLinesCost = _glBordLinesCost - (double)node.GetData(BordLines) + _bordNewLocalValue;
		}
示例#27
0
		private bool NodesLinked(GraphNode n1, GraphNode n2)
		{
			foreach (GraphLink link in n1.OutLinks)
				if (link.Destination == n2)
					return true;

			return false;
		}
示例#28
0
		private void CommitMove(GraphNode node)
		{
			node.SetData(BordLines, _bordNewLocalValue);
		}
示例#29
0
		private void PlaceObjects(GraphNode[,] grid)
		{
			for (int i = 0; i < _gridWidth; ++i)
			{
				for (int j = 0; j < _gridHeight; ++j)
				{
					GraphNode node = grid[1 + i, 1 + j];
					if (node != null)
					{
						node.Node.Bounds = 
							new RectangleF(_info.XGap + i * _info.GridSize + _info.GridSize / 2 - node.Node.Bounds.Width / 2,
								_info.YGap + j * _info.GridSize + _info.GridSize / 2 - node.Node.Bounds.Height / 2,
								node.Node.Bounds.Width, node.Node.Bounds.Height);
					}
				}
			}
		}
示例#30
0
		private void SetGraphElements()
		{
			_nodes  = new GraphNode[_tempGraph.Nodes.Count];
			_links  = new GraphLink[_tempGraph.Links.Count];
			
			for (int i = 0; i < _tempGraph.Nodes.Count; i++)
				_nodes[i] = _tempGraph.Nodes[i] as GraphNode;
			for (int i = 0; i < _tempGraph.Links.Count; i++)
				_links[i] = _tempGraph.Links[i] as GraphLink;

			_sharedNode = new bool[_links.Length, _links.Length];
			for (int i = 0; i < _links.Length; i++)
			{
				for (int j = 0; j < _links.Length; j++)
				{
					_sharedNode[i, j] = (i == j) ||
						_links[i].Origin == _links[j].Origin ||
						_links[i].Origin == _links[j].Destination ||
						_links[i].Destination == _links[j].Destination ||
						_links[i].Destination == _links[j].Origin;
					
				}
			}

			_nodeLink = new bool[_nodes.Length, _links.Length];
			for (int i = 0; i < _nodes.Length; i++)
			{
				for (int j = 0; j < _links.Length; j++)
				{
					_nodeLink[i,j] =
						_nodes[i].InLinks.Contains(_links[j]) ||
						_nodes[i].OutLinks.Contains(_links[j]);
				}
			}
		}