public clsEdge(clsNode objNode1, clsNode objNode2, Double dblSpeed, Double dblCost) { mobjStartNode = objNode1; mobjEndNode = objNode2; mdblSpeed = dblSpeed; mdblCost = dblCost; }
private void AnimateShortestPath() { Bitmap objSnapShotBitmap; bool blnFinished = false; double dblTime = 0; double dblEdgeStartTime; int intPathEdgeIndex; int intEdgeStartNodeIndex; int intEdgeEndNodeIndex; int intX1; int intY1; int intX2; int intY2; int intX; int intY; intEdgeStartNodeIndex = mobjGraphStartNode.Index; mobjGraphStartNode = null; RefreshDisplay(); objSnapShotBitmap = new Bitmap(mobjFormBitmap); intPathEdgeIndex = mlstShortestPath.Count - 1; dblEdgeStartTime = 0; if (intEdgeStartNodeIndex == mlstShortestPath[intPathEdgeIndex].StartNode.Index) { intX1 = mlstShortestPath[intPathEdgeIndex].StartNode.X; intY1 = mlstShortestPath[intPathEdgeIndex].StartNode.Y; intX2 = mlstShortestPath[intPathEdgeIndex].EndNode.X; intY2 = mlstShortestPath[intPathEdgeIndex].EndNode.Y; intEdgeEndNodeIndex = mlstShortestPath[intPathEdgeIndex].EndNode.Index; } else { intX1 = mlstShortestPath[intPathEdgeIndex].EndNode.X; intY1 = mlstShortestPath[intPathEdgeIndex].EndNode.Y; intX2 = mlstShortestPath[intPathEdgeIndex].StartNode.X; intY2 = mlstShortestPath[intPathEdgeIndex].StartNode.Y; intEdgeEndNodeIndex = mlstShortestPath[intPathEdgeIndex].StartNode.Index; } while (!blnFinished && !mblnClosing) { intX = (int)((Double)intX1 + ((((Double)intX2 - (Double)intX1) * (dblTime - dblEdgeStartTime)) / mlstShortestPath[intPathEdgeIndex].Cost)); intY = (int)((Double)intY1 + ((((Double)intY2 - (Double)intY1) * (dblTime - dblEdgeStartTime)) / mlstShortestPath[intPathEdgeIndex].Cost)); mobjBitmapGraphics.DrawImage(objSnapShotBitmap, 0, 0); mobjBitmapGraphics.FillEllipse(Brushes.Black, intX - 10, intY - 10, 20, 20); this.Invalidate(); Application.DoEvents(); Thread.Sleep(10); dblTime += 0.01; while (dblEdgeStartTime + mlstShortestPath[intPathEdgeIndex].Cost < dblTime) { dblEdgeStartTime += mlstShortestPath[intPathEdgeIndex].Cost; if (intPathEdgeIndex > 0) { intPathEdgeIndex -= 1; intEdgeStartNodeIndex = intEdgeEndNodeIndex; if (intEdgeStartNodeIndex == mlstShortestPath[intPathEdgeIndex].StartNode.Index) { intX1 = mlstShortestPath[intPathEdgeIndex].StartNode.X; intY1 = mlstShortestPath[intPathEdgeIndex].StartNode.Y; intX2 = mlstShortestPath[intPathEdgeIndex].EndNode.X; intY2 = mlstShortestPath[intPathEdgeIndex].EndNode.Y; intEdgeEndNodeIndex = mlstShortestPath[intPathEdgeIndex].EndNode.Index; } else { intX1 = mlstShortestPath[intPathEdgeIndex].EndNode.X; intY1 = mlstShortestPath[intPathEdgeIndex].EndNode.Y; intX2 = mlstShortestPath[intPathEdgeIndex].StartNode.X; intY2 = mlstShortestPath[intPathEdgeIndex].StartNode.Y; intEdgeEndNodeIndex = mlstShortestPath[intPathEdgeIndex].StartNode.Index; } } else { blnFinished = true; } } } }
private bool FindShortestPath(clsNode objStartNode, clsNode objEndNode) { Double[,] arrCosts; int[,] arrShortestPath; Double dblCost1; Double dblCost2; Double dblCostTotal; int intCurrentNodeIndex; arrCosts = new Double[mlstNodes.Count, mlstNodes.Count]; arrShortestPath = new int[mlstNodes.Count, mlstNodes.Count]; for (int intCount1 = 0; intCount1 < mlstNodes.Count; intCount1++) { for (int intCount2 = 0; intCount2 < mlstNodes.Count; intCount2++) { arrShortestPath[intCount1, intCount2] = intCount1; if (intCount1 == intCount2) { arrCosts[intCount1, intCount2] = 0; } else { arrCosts[intCount1, intCount2] = -1; } } } foreach (clsEdge objEdge in mlstEdges) { arrCosts[objEdge.StartNode.Index, objEdge.EndNode.Index] = objEdge.Cost; arrCosts[objEdge.EndNode.Index, objEdge.StartNode.Index] = objEdge.Cost; } for (int intNodeThrough = 0; intNodeThrough < mlstNodes.Count; intNodeThrough++) { for (int intNodeFrom = 0; intNodeFrom < mlstNodes.Count; intNodeFrom++) { dblCost1 = arrCosts[intNodeFrom, intNodeThrough]; if (dblCost1 != -1 && intNodeFrom != intNodeThrough) { for (int intNodeTo = 0; intNodeTo < mlstNodes.Count; intNodeTo++) { dblCost2 = arrCosts[intNodeThrough, intNodeTo]; dblCostTotal = arrCosts[intNodeFrom, intNodeTo]; if (dblCost2 != -1 && intNodeThrough != intNodeTo) { if ((dblCost1 + dblCost2 < dblCostTotal) | dblCostTotal == -1) { arrCosts[intNodeFrom, intNodeTo] = dblCost1 + dblCost2; arrShortestPath[intNodeFrom, intNodeTo] = arrShortestPath[intNodeThrough, intNodeTo]; } } } } } } mlstShortestPath = new List <clsEdge>(); intCurrentNodeIndex = objEndNode.Index; while (true) { if (intCurrentNodeIndex == objStartNode.Index) { return(true); } else if (arrCosts[objStartNode.Index, intCurrentNodeIndex] == -1) { return(false); } else { mlstShortestPath.Add(FindEdge(intCurrentNodeIndex, arrShortestPath[objStartNode.Index, intCurrentNodeIndex])); intCurrentNodeIndex = arrShortestPath[objStartNode.Index, intCurrentNodeIndex]; } } }
private void frmMain_MouseDown(object sender, MouseEventArgs e) { switch (mintMode) { case 1: if (e.Button == MouseButtons.Left) { mlstNodes.Add(new clsNode(e.X, e.Y, mlstNodes.Count)); RefreshDisplay(); } break; case 2: if (e.Button == MouseButtons.Left) { foreach (clsNode objNode in mlstNodes) { if (Math.Abs(e.X - objNode.X) + Math.Abs(e.Y - objNode.Y) < 20) { if (mobjEdgeStartNode == null) { mobjEdgeStartNode = objNode; } else { Double dblSpeed = Convert.ToDouble(InputBox.Show("Enter speed in pixels/second", "Speed", "100").Text); Double dblCost = (Math.Sqrt(Math.Pow(mobjEdgeStartNode.X - objNode.X, 2) + Math.Pow(mobjEdgeStartNode.Y - objNode.Y, 2))) / dblSpeed; mlstEdges.Add(new clsEdge(mobjEdgeStartNode, objNode, dblSpeed, dblCost)); mobjEdgeStartNode = null; } RefreshDisplay(); break; } } } break; case 3: if (e.Button == MouseButtons.Left) { foreach (clsNode objNode in mlstNodes) { if (Math.Abs(e.X - objNode.X) + Math.Abs(e.Y - objNode.Y) < 20) { if (mobjGraphStartNode == null) { mobjGraphStartNode = objNode; RefreshDisplay(); } else { if (FindShortestPath(mobjGraphStartNode, objNode)) { AnimateShortestPath(); } else { MessageBox.Show("No Path between start and end nodes"); mobjGraphStartNode = null; RefreshDisplay(); } } break; } } } break; } }