/// <summary> /// 找出与元器件drawObject结点相连的直线锚点信息 /// </summary> /// <param name="drawArea"></param> /// <param name="resizedObject">输入一个要得出直线锚点的元器件</param> /// <returns>返回一个数组第一列表示该元器件的结点,第二列表示与该结点连接的直线索引,第三列表示直线的锚点编号</returns> public List <int[]> FindLineHandle(DrawArea drawArea, DrawObject drawObject) { List <int[]> temp = new List <int[]>(); int i, j, k; Point Position; double distance = 100; for (i = 0; i < drawArea.GraphicsList.Count; i++) { DrawObject temp1 = drawArea.GraphicsList[i]; if (temp1 is DrawLine) { for (j = 1; j <= drawObject.NodeCount; j++) { //得到每个结点的坐标,寻找与该结点相连的直线 Position = drawObject.GetNode(j); for (k = 1; k <= 2; k++) { Point p = temp1.GetHandle(k); distance = Math.Sqrt((Position.X - p.X) * (Position.X - p.X) + (Position.Y - p.Y) * (Position.Y - p.Y)); if (distance < 10) { DrawLine DL = temp1 as DrawLine; if (DL.FindEquipmentID[k - 1] == drawObject.ObjectID && DL.FindNodeID[k - 1] == j) { //该直线k锚点就是连接的这个结点 temp.Add(new int[] { j, i, k }); break; } else if (DL.ConncetSNodeCount() == 0) { //如果线的两端都没有连结点 temp.Add(new int[] { j, i, k }); DL.FindNodeID[k - 1] = j; DL.FindEquipmentID[k - 1] = drawObject.ObjectID; break; } else if (DL.ConncetSNodeCount() == 1 && DL.FindEquipmentID[k - 1] == 0) { //如果线只连接了一个其他元器件的结点,则可以将该线没有连接结点的锚点于结点连接 temp.Add(new int[] { j, i, k }); DL.FindNodeID[k - 1] = j; DL.FindEquipmentID[k - 1] = drawObject.ObjectID; AddEdge(drawArea, DL); break; } } } } } } return(temp); }
public override void OnMouseDown(DrawArea drawArea, System.Windows.Forms.MouseEventArgs e) { DrawLine dl; Point p = CF.OnRange(drawArea); if (p.X < 0 || p.Y < 0) { if (IsCtrlOn) //按下了Ctrl键 { dl = new DrawLine(e.X, e.Y, e.X + 10, e.Y); } else if (IsShiftOn) { dl = new DrawLine(e.X, e.Y, e.X, e.Y + 10); } else { dl = new DrawLine(e.X, e.Y, e.X + 10, e.Y + 10); } drawArea.Refresh(); } else { if (IsCtrlOn) //按下了Ctrl键 { dl = new DrawLine(p.X, p.Y, p.X + 10, p.Y); } else if (IsShiftOn) { dl = new DrawLine(p.X, p.Y, p.X, p.Y + 10); } else { dl = new DrawLine(p.X, p.Y, p.X + 10, p.Y + 10); } drawArea.Refresh(); } drawArea.Refresh(); dl.ObjectID = ComFunction.NewEquipmentNumber(); AddNewObject(drawArea, dl); //记录直线两边连接的元器件编号和结点编号 DrawLine d = (drawArea.GraphicsList[0]) as DrawLine; CF.ChangeLineLink(drawArea, d, e); }
public override void OnMouseUp(DrawArea drawArea, System.Windows.Forms.MouseEventArgs e) { //记录直线两边连接的元器件编号和结点编号 DrawLine d = (drawArea.GraphicsList[0]) as DrawLine; CF.ChangeLineLink(drawArea, d, e); if (drawArea.IsTest == true) { //进行连线测试 CF.BeginTest(drawArea); } drawArea.GraphicsList[0].Normalize(); drawArea.ActiveTool = DrawToolType.Pointer; drawArea.Capture = false; drawArea.Refresh(); }
/// <summary> /// 通过直线给首结点加边 /// </summary> /// <param name="drawArea">画图区域</param> /// <param name="drawLine">直线</param> public void AddEdge(DrawArea drawArea, DrawLine drawLine) { int StartVertexID, EndVertexID; if (drawLine.ConncetSNodeCount() == 2) { //直线两边都连着结点,可以剪边 //直线锚点1对应的首结点ID StartVertexID = FindVertextID(drawArea, drawLine.FindEquipmentID[0], drawLine.FindNodeID[0]); //直线锚点2对应的首结点ID EndVertexID = FindVertextID(drawArea, drawLine.FindEquipmentID[1], drawLine.FindNodeID[1]); //调用加边函数 drawArea.GraphicsNodeList.AddEdge(StartVertexID, EndVertexID); drawArea.GraphicsNodeList.AddEdge(EndVertexID, StartVertexID); } else { return; } }
/// <summary> /// 通过直线给结点减边 /// </summary> /// <param name="drawArea"></param> /// <param name="drawLine"></param> public void ReduceEdge(DrawArea drawArea, DrawLine drawLine) { int Firstnode, Edgenode; int count = drawLine.ConncetSNodeCount(); if (count == 2) { //直线两边都连着结点,可以剪边 //直线锚点1对应的首结点ID Firstnode = FindVertextID(drawArea, drawLine.FindEquipmentID[0], drawLine.FindNodeID[0]); //直线锚点2对应的首结点ID Edgenode = FindVertextID(drawArea, drawLine.FindEquipmentID[1], drawLine.FindNodeID[1]); //减边函数 drawArea.GraphicsNodeList.ReduceEdge(Firstnode, Edgenode); drawArea.GraphicsNodeList.ReduceEdge(Edgenode, Firstnode); } else { return; } }
/// <summary> /// 开始测试 /// </summary> /// <param name="drawAreaClient"></param> public void BeginTest(DrawArea drawAreaClient) { //将所有的元器件带电状态设为false for (int i = 0; i < drawAreaClient.GraphicsList.Count; i++) { drawAreaClient.GraphicsList[i].IsPowerOn = false; } //先进行深度优先搜索 Do_DFS(drawAreaClient); for (int j = 0; j < drawAreaClient.GraphicsList.Count; j++) { bool judge = false; if (drawAreaClient.GraphicsList[j] is DrawLine) { //如果元器件是母线,母线任意一端的元器件结点带电则该母线带点 DrawLine drawLine = drawAreaClient.GraphicsList[j] as DrawLine; for (int k = 0; k < 2; k++) { int ID = FindVertextID(drawAreaClient, drawLine.FindEquipmentID[k], drawLine.FindNodeID[k]); if (ID != -1) { int index = drawAreaClient.GraphicsNodeList.FindIndex(ID); VertexNode VNode = drawAreaClient.GraphicsNodeList[index]; if (VNode.Visited == true) { judge = true; break; } } } drawLine.IsPowerOn = judge; } else if (drawAreaClient.GraphicsList[j] is DrawBreak) { //如果是开关则需要看开关是否打开 DrawBreak DB = drawAreaClient.GraphicsList[j] as DrawBreak; //如果开关打开 if (DB.OpenOrClose) { int count = 0; //如果说某元器件里所有的首结点都带电则该元器件带电 for (int k = 1; k <= drawAreaClient.GraphicsList[j].NodeCount; k++) { int ID = FindVertextID(drawAreaClient, DB.ObjectID, k); int index = drawAreaClient.GraphicsNodeList.FindIndex(ID); VertexNode VNode = drawAreaClient.GraphicsNodeList[index]; if (VNode.Visited == true) { count += 1; } } if (count == DB.NodeCount) { judge = true; } DB.IsPowerOn = judge; } else { DB.IsPowerOn = false; } } else if (drawAreaClient.GraphicsList[j] is DrawKnife) { //如果是刀闸则需要看开关是否打开 DrawKnife DK = drawAreaClient.GraphicsList[j] as DrawKnife; //如果刀闸打开 if (DK.OpenOrClose) { int count = 0; //如果说某元器件里所有的首结点都带电则该元器件带电 for (int k = 1; k <= drawAreaClient.GraphicsList[j].NodeCount; k++) { int ID = FindVertextID(drawAreaClient, DK.ObjectID, k); int index = drawAreaClient.GraphicsNodeList.FindIndex(ID); VertexNode VNode = drawAreaClient.GraphicsNodeList[index]; if (VNode.Visited == true) { count += 1; } } if (count == DK.NodeCount) { judge = true; } DK.IsPowerOn = judge; } else { DK.IsPowerOn = false; } } else { int count = 0; DrawObject DO = drawAreaClient.GraphicsList[j]; //如果说某元器件里所有的首结点都带电则该元器件带电 for (int k = 1; k <= drawAreaClient.GraphicsList[j].NodeCount; k++) { int ID = FindVertextID(drawAreaClient, DO.ObjectID, k); int index = drawAreaClient.GraphicsNodeList.FindIndex(ID); VertexNode VNode = drawAreaClient.GraphicsNodeList[index]; if (VNode.Visited == true) { count += 1; } } if (count == DO.NodeCount) { judge = true; } DO.IsPowerOn = judge; } } drawAreaClient.Refresh(); }
/// <summary> /// 改变连线状态 /// </summary> /// <param name="drawArea"></param> /// <param name="drawLine"></param> public void ChangeLineLink(DrawArea drawArea, DrawLine drawLine, System.Windows.Forms.MouseEventArgs e) { int i, j = -1, k; for (i = 0; i < drawArea.GraphicsList.Count; i++) { j = drawArea.GraphicsList[i].Node; if (j > 0) { break; } } if (j != -1) { //在结点范围之内 Point position = drawArea.GraphicsList[i].GetNode(j); k = drawLine.HitTest(position); } else { k = drawLine.HitTest(e.Location); } if (k == 1 || k == 2) { if (j != -1) { //如果之前就有边则先减边 ReduceEdge(drawArea, drawLine); //说明有击中一个结点 drawLine.FindEquipmentID[k - 1] = drawArea.GraphicsList[i].ObjectID; drawLine.FindNodeID[k - 1] = j; //给直线连接的首结点加边 AddEdge(drawArea, drawLine); } else { //应在之前减边 ReduceEdge(drawArea, drawLine); //说明此时母线锚点没有击中结点 drawLine.FindEquipmentID[k - 1] = 0; drawLine.FindNodeID[k - 1] = 0; } } else { //如果是在母线内部 for (i = 0; i < 2; i++) { if (drawLine.FindNodeID[i] != 0) { Point p = FindPoint(drawArea, drawLine.FindEquipmentID[i], drawLine.FindNodeID[i]); Point newp = drawLine.GetHandle(i + 1); double distance = Math.Sqrt((p.X - newp.X) * (p.X - newp.X) + (p.Y - newp.Y) * (p.Y - newp.Y)); if (distance > 10) { //如果有一个锚点不连着结点了则都另一个锚点也不连着了 if (drawLine.ConncetSNodeCount() == 2) { //如果之前直线两边都连着结点则先剪边 ReduceEdge(drawArea, drawLine); } drawLine.FindNodeID = new int[2]; drawLine.FindEquipmentID = new int[2]; break; } } } } }
public override void OnMouseUp(DrawArea drawArea, System.Windows.Forms.MouseEventArgs e) { if (drawArea.GraphicsList.Selection != null) { for (int i = 0; i < drawArea.GraphicsList.Selection.Count; i++) { if (drawArea.GraphicsList.Selection[i] is DrawLine) { //如果线发生改变则需要判断线两端连接的结点状态以及重新进行深度优先搜索 DrawLine drawLine = drawArea.GraphicsList.Selection[i] as DrawLine; CF.ChangeLineLink(drawArea, drawLine, e); } else if (drawArea.GraphicsList.Selection[i] is DrawBreak) { //如果是开关 DrawBreak drawBreak = drawArea.GraphicsList.Selection[i] as DrawBreak; //根据开关开闭状态给开关对应的结点加边 if (drawBreak.OpenOrClose == true) { //给开关两端的首结点连线 CF.AddEdge(drawArea, drawBreak); } else { //断开开关两端的首结点连线 CF.ReduceEdge(drawArea, drawBreak); } } else if (drawArea.GraphicsList.Selection[i] is DrawKnife) { //如果是刀闸 DrawKnife drawKnife = drawArea.GraphicsList.Selection[i] as DrawKnife; //根据开关开闭状态给开关对应的结点加边 if (drawKnife.OpenOrClose == true) { //给开关两端的首结点连线 CF.AddEdge(drawArea, drawKnife); } else { //断开开关两端的首结点连线 CF.ReduceEdge(drawArea, drawKnife); } } } } if (drawArea.IsTest == true) { //进行测试 CF.BeginTest(drawArea); } //空画矩形 if (pointerMode == PointerMode.Net) { // 移除旧的矩形 ControlPaint.DrawReversibleFrame( drawArea.RectangleToScreen(DrawRectanlge.GetNormalizedRectangle(startPoint, lastPoint)), Color.Black, FrameStyle.Dashed); // 选择在矩形框中的图元 drawArea.GraphicsList.SelectInRectangle(DrawRectanlge.GetNormalizedRectangle(startPoint, lastPoint)); pointerMode = PointerMode.None; } if (resizedObject != null) { //改变大小之后 resizedObject.Normalize(); resizedObject = null; } drawArea.Capture = false; drawArea.Refresh(); }