TestEdgeToVerticesBad3() { // Edge.Vertices contains 1 vertex only. try { IEdge oEdge = new MockEdge(null, null, false, false, 1); IVertex oVertexA, oVertexB; EdgeUtil.EdgeToVertices(oEdge, ClassName, MethodOrPropertyName, out oVertexA, out oVertexB); } catch (ApplicationException oApplicationException) { Assert.AreEqual( "TheClass.TheMethodOrProperty: The edge does not connect two" + " vertices." , oApplicationException.Message ); throw oApplicationException; } }
TestEdgeToVerticesBad() { // Null Edge.Vertices. try { IEdge oEdge = new MockEdge(null, null, false, true, 0); IVertex oVertexA, oVertexB; EdgeUtil.EdgeToVertices(oEdge, ClassName, MethodOrPropertyName, out oVertexA, out oVertexB); } catch (ApplicationException ApplicationException) { Assert.AreEqual( "TheClass.TheMethodOrProperty: The edge's Vertices property is" + " null." , ApplicationException.Message ); throw ApplicationException; } }
TestEdgeToVerticesBad7() { // Second vertex has no parent. try { MockVertex oVertex1 = new MockVertex(); MockVertex oVertex2 = new MockVertex(); IGraph oGraph = new Graph(); oVertex1.ParentGraph = oGraph; // oVertex2.ParentGraph = oGraph; IEdge oEdge = new MockEdge(oVertex1, oVertex2, false, false, 2); IVertex oVertexA, oVertexB; EdgeUtil.EdgeToVertices(oEdge, ClassName, MethodOrPropertyName, out oVertexA, out oVertexB); } catch (ApplicationException oApplicationException) { Assert.AreEqual( "TheClass.TheMethodOrProperty: The edge's second vertex does" + " not belong to a graph." , oApplicationException.Message ); throw oApplicationException; } }
TestEdgeToVerticesBad8() { // Vertices not part of the same graph. try { MockVertex oVertex1 = new MockVertex(); MockVertex oVertex2 = new MockVertex(); IGraph oGraph1 = new Graph(GraphDirectedness.Mixed); IGraph oGraph2 = new Graph(GraphDirectedness.Mixed); oVertex1.ParentGraph = oGraph1; oVertex2.ParentGraph = oGraph2; IEdge oEdge = new MockEdge(oVertex1, oVertex2, false, false, 2); IVertex oVertexA, oVertexB; EdgeUtil.EdgeToVertices(oEdge, ClassName, MethodOrPropertyName, out oVertexA, out oVertexB); } catch (ApplicationException oApplicationException) { Assert.AreEqual( "TheClass.TheMethodOrProperty: The edge connects vertices not" + " in the same graph." , oApplicationException.Message ); throw oApplicationException; } }
TestEdgeToVerticesBad5() { // Second vertex is null. try { IEdge oEdge = new MockEdge( new MockVertex(), null, false, false, 2); IVertex oVertexA, oVertexB; EdgeUtil.EdgeToVertices(oEdge, ClassName, MethodOrPropertyName, out oVertexA, out oVertexB); } catch (ApplicationException oApplicationException) { Assert.AreEqual( "TheClass.TheMethodOrProperty: The edge's second vertex is" + " null." , oApplicationException.Message ); throw oApplicationException; } }
public override void UpdateFeedback(IRequest request, IFigure feedback) { var req = request as CreateEdgeRequest; if (req == null) { return; } var edge = feedback as IEdge; _feedback = edge; edge.IsVisible = true; if (req.EdgeSourceEditor != null && req.EdgeSourceEditor == req.EdgeTargetEditor) { /// 同じ図形に両端をつなごうとしている場合はループする形にする var pts = EdgeUtil.GetLoopPoints(req.EdgeSourceEditor.Figure.Bounds); edge.SetEdgePoints(pts); } else { // todo: is CentralRouterで調べるのではなく,ClearBendPoints()が必要かどうかをIRouterに聞く if ((edge.Router == null || edge.Router is CentralRouter) && edge.EdgePointCount > 2) { edge.ClearBendPoints(); } if (req.EdgeSourceEditor == null) { edge.SourceAnchor.Disconnect(); edge.SourceAnchor.Location = GetGridAdjustedPoint(req.StartPoint); } else { var srcFigClone = req.EdgeSourceEditor.Figure.CloneFigure() as INode; edge.SourceAnchor.Connect(srcFigClone); edge.SourceAnchor.Location = edge.GetConnectionPoint( edge.SourceAnchor, srcFigClone, GetGridAdjustedPoint(req.StartPoint) ); } if (req.EdgeTargetEditor == null) { edge.TargetAnchor.Disconnect(); edge.TargetAnchor.Location = GetGridAdjustedPoint(req.EndPoint); } else { var tgtFigClone = req.EdgeTargetEditor.Figure.CloneFigure() as INode; edge.TargetAnchor.Connect(tgtFigClone); edge.TargetAnchor.Location = edge.GetConnectionPoint( edge.TargetAnchor, tgtFigClone, GetGridAdjustedPoint(req.EndPoint) ); } } }
/// <summary> /// 求两个多边形差集 /// </summary> /// <param name="poly1"></param> /// <param name="poly2"></param> /// <param name="interPoly"></param> /// <returns></returns> public static bool PolygonClip(List<Vector2> poly1, List<Vector2> poly2, out List<Vector2> interPoly) { interPoly = new List<Vector2>(); if (poly1.Count < 3 || poly2.Count < 3) { return false; } Vector2 point; //计算多边形交点 for (int i = 0; i < poly1.Count; i++) { int poly1_next_idx = (i + 1) % poly1.Count; for (int j = 0; j < poly2.Count; j++) { int poly2_next_idx = (j + 1) % poly2.Count; if (ImageUtil.GetIntersection(poly1[i], poly1[poly1_next_idx], poly2[j], poly2[poly2_next_idx], out point)) { interPoly.Add(point); } } } //计算多边形内部点 for (int i = 0; i < poly1.Count; i++) { if (ImageUtil.Contains(poly1[i], poly2)) { interPoly.Add(poly1[i]); } } for (int i = 0; i < poly2.Count; i++) { if (ImageUtil.Contains(poly2[i], poly1)) { interPoly.Add(poly2[i]); } } if (interPoly.Count <= 0) return false; //点集排序 interPoly = EdgeUtil.CreateConvexOutside(interPoly); return true; }
TryGetEdgeKey ( Int32 iRowOneBased, Object [,] aoVertex1NameValues, Object [,] aoVertex2NameValues, Object [,] aoThirdColumnValues, Boolean bGraphIsDirected, out String sEdgeKey ) { Debug.Assert(iRowOneBased >= 1); Debug.Assert(aoVertex1NameValues != null); Debug.Assert(aoVertex2NameValues != null); AssertValid(); sEdgeKey = null; String sVertex1Name, sVertex2Name; if ( !ExcelUtil.TryGetNonEmptyStringFromCell(aoVertex1NameValues, iRowOneBased, 1, out sVertex1Name) || !ExcelUtil.TryGetNonEmptyStringFromCell(aoVertex2NameValues, iRowOneBased, 1, out sVertex2Name) ) { return(false); } sEdgeKey = EdgeUtil.GetVertexNamePair(sVertex1Name, sVertex2Name, bGraphIsDirected); String sThirdColumnValue; if ( aoThirdColumnValues != null && ExcelUtil.TryGetNonEmptyStringFromCell(aoThirdColumnValues, iRowOneBased, 1, out sThirdColumnValue) ) { sEdgeKey += EdgeUtil.VertexNamePairSeparator; sEdgeKey += sThirdColumnValue; } return(true); }
TestGetVertexIDPair6() { // Undirected graph, useDirectedness = false. IGraph oUndirectedGraph = new Graph(GraphDirectedness.Undirected); IVertexCollection oUndirectedVertices = oUndirectedGraph.Vertices; IVertex oUndirectedVertexA = oUndirectedVertices.Add(); IVertex oUndirectedVertexB = oUndirectedVertices.Add(); IVertex oUndirectedVertexC = oUndirectedVertices.Add(); IVertex oUndirectedVertexD = oUndirectedVertices.Add(); IEdgeCollection oEdges = oUndirectedGraph.Edges; IEdge oEdge1 = oEdges.Add(oUndirectedVertexA, oUndirectedVertexB, false); IEdge oEdge2 = oEdges.Add(oUndirectedVertexA, oUndirectedVertexB, false); IEdge oEdge3 = oEdges.Add(oUndirectedVertexB, oUndirectedVertexA, false); IEdge oEdge4 = oEdges.Add(oUndirectedVertexA, oUndirectedVertexC, false); Int64 i64VertexIDPair1 = EdgeUtil.GetVertexIDPair(oEdge1, false); Int64 i64VertexIDPair2 = EdgeUtil.GetVertexIDPair(oEdge2, false); Int64 i64VertexIDPair3 = EdgeUtil.GetVertexIDPair(oEdge3, false); Int64 i64VertexIDPair4 = EdgeUtil.GetVertexIDPair(oEdge4, false); // Make sure that the left-shift worked. Assert.IsTrue(i64VertexIDPair1 > Int32.MaxValue); Assert.IsTrue(i64VertexIDPair2 > Int32.MaxValue); Assert.IsTrue(i64VertexIDPair3 > Int32.MaxValue); Assert.IsTrue(i64VertexIDPair4 > Int32.MaxValue); Assert.AreEqual(i64VertexIDPair1, i64VertexIDPair2); Assert.AreEqual(i64VertexIDPair1, i64VertexIDPair3); Assert.AreNotEqual(i64VertexIDPair1, i64VertexIDPair4); Assert.AreEqual(i64VertexIDPair2, i64VertexIDPair3); Assert.AreNotEqual(i64VertexIDPair2, i64VertexIDPair4); Assert.AreNotEqual(i64VertexIDPair3, i64VertexIDPair4); }
// === AbstractConnection ========== protected override void OnConnectableChanged(ConnectableChangedEventArgs e) { base.OnConnectableChanged(e); if (e.OldValue != null) { e.OldValue.BoundsChanged -= HandleConnectableBoundsChanged; var oldNode = e.OldValue as INode; if (oldNode != null) { oldNode.MaxSizeChanged -= HandleNodeMaxSizeChanged; } } if (e.NewValue != null) { e.NewValue.BoundsChanged += HandleConnectableBoundsChanged; var newNode = e.NewValue as INode; if (newNode != null) { newNode.MaxSizeChanged += HandleNodeMaxSizeChanged; } } if ( _router == null && e.NewValue != null && ( (e.Kind == ConnectionAnchorKind.Source && e.NewValue == Target) || (e.Kind == ConnectionAnchorKind.Target && e.NewValue == Source) ) ) { SetEdgePoints(EdgeUtil.GetLoopPoints(Source.Bounds)); } if (_router != null && IsValidEdge) { using (DirtManager.BeginDirty()) { _router.Route(this); } } }
CountIncidentEdge ( IEdge oIntergroupEdge, Int32 iGroup1Index, Int32 iGroup2Index, IList <IntergroupEdgeInfo> oIntergroupEdges, Dictionary <Int32, IntergroupEdgeInfo> oIntergroupEdgeIndexes ) { Debug.Assert(oIntergroupEdge != null); Debug.Assert(iGroup1Index >= 0); Debug.Assert(iGroup2Index >= 0); Debug.Assert(oIntergroupEdges != null); Debug.Assert(oIntergroupEdgeIndexes != null); AssertValid(); Double dPositiveEdgeWeight = EdgeUtil.GetPositiveEdgeWeight( oIntergroupEdge); // Does an object already exist for the iGroup1Index/iGroup2Index pair? IntergroupEdgeInfo oIntergroupEdgeInfo; if (oIntergroupEdgeIndexes.TryGetValue(iGroup2Index, out oIntergroupEdgeInfo)) { // Yes. oIntergroupEdgeInfo.Edges++; oIntergroupEdgeInfo.EdgeWeightSum += dPositiveEdgeWeight; } else { // No. Create one. oIntergroupEdgeInfo = new IntergroupEdgeInfo( iGroup1Index, iGroup2Index, 1, dPositiveEdgeWeight); oIntergroupEdges.Add(oIntergroupEdgeInfo); oIntergroupEdgeIndexes.Add(iGroup2Index, oIntergroupEdgeInfo); } }
SaveGraphCore ( IGraph graph, Stream stream ) { Debug.Assert(graph != null); Debug.Assert(graph.Directedness == GraphDirectedness.Directed); Debug.Assert(stream != null); AssertValid(); const String MethodName = "SaveGraph"; StreamWriter oStreamWriter = new StreamWriter(stream, StreamEncoding); // Loop through the graph's edges. foreach (IEdge oEdge in graph.Edges) { // Retrieve the edge's vertices. IVertex oVertex1, oVertex2; EdgeUtil.EdgeToVertices(oEdge, this.ClassName, MethodName, out oVertex1, out oVertex2); // Retrieve and format the edge names. String sVertex1Name = VertexToVertexName(oVertex1); String sVertex2Name = VertexToVertexName(oVertex2); oStreamWriter.WriteLine( "{0}\t{1}" , sVertex1Name, sVertex2Name ); } oStreamWriter.Flush(); }
TestGetVertexIDPair() { // Directed graph. IGraph oDirectedGraph = new Graph(GraphDirectedness.Directed); IVertexCollection oDirectedVertices = oDirectedGraph.Vertices; IVertex oDirectedVertexA = oDirectedVertices.Add(); IVertex oDirectedVertexB = oDirectedVertices.Add(); IVertex oDirectedVertexC = oDirectedVertices.Add(); IVertex oDirectedVertexD = oDirectedVertices.Add(); IEdgeCollection oEdges = oDirectedGraph.Edges; IEdge oEdge1 = oEdges.Add(oDirectedVertexA, oDirectedVertexB, true); IEdge oEdge2 = oEdges.Add(oDirectedVertexA, oDirectedVertexB, true); IEdge oEdge3 = oEdges.Add(oDirectedVertexB, oDirectedVertexA, true); IEdge oEdge4 = oEdges.Add(oDirectedVertexA, oDirectedVertexC, true); Int64 i64VertexIDPair1 = EdgeUtil.GetVertexIDPair(oEdge1); Int64 i64VertexIDPair2 = EdgeUtil.GetVertexIDPair(oEdge2); Int64 i64VertexIDPair3 = EdgeUtil.GetVertexIDPair(oEdge3); Int64 i64VertexIDPair4 = EdgeUtil.GetVertexIDPair(oEdge4); // Make sure that the left-shift worked. Assert.IsTrue(i64VertexIDPair1 > Int32.MaxValue); Assert.IsTrue(i64VertexIDPair2 > Int32.MaxValue); Assert.IsTrue(i64VertexIDPair3 > Int32.MaxValue); Assert.IsTrue(i64VertexIDPair4 > Int32.MaxValue); Assert.AreEqual(i64VertexIDPair1, i64VertexIDPair2); Assert.AreNotEqual(i64VertexIDPair1, i64VertexIDPair3); Assert.AreNotEqual(i64VertexIDPair1, i64VertexIDPair4); Assert.AreNotEqual(i64VertexIDPair2, i64VertexIDPair3); Assert.AreNotEqual(i64VertexIDPair2, i64VertexIDPair4); Assert.AreNotEqual(i64VertexIDPair3, i64VertexIDPair4); }
TestEdgeToVertices() { // Valid vertices. MockVertex oVertex1 = new MockVertex(); MockVertex oVertex2 = new MockVertex(); IGraph oGraph = new Graph(); oVertex1.ParentGraph = oGraph; oVertex2.ParentGraph = oGraph; IEdge oEdge = new MockEdge(oVertex1, oVertex2, false, false, 2); IVertex oVertexA, oVertexB; EdgeUtil.EdgeToVertices(oEdge, ClassName, MethodOrPropertyName, out oVertexA, out oVertexB); Assert.AreEqual(oVertex1, oVertexA); Assert.AreEqual(oVertex2, oVertexB); }
InitializeMetadata ( IGraph oGraph, ICollection <IVertex> oVerticesToLayOut ) { Debug.Assert(oGraph != null); Debug.Assert(oVerticesToLayOut != null); AssertValid(); foreach (IVertex oVertex in oVerticesToLayOut) { // Create an object that will store all calculated values for the // vertex. FruchtermanReingoldVertexInfo oFruchtermanReingoldVertexInfo = new FruchtermanReingoldVertexInfo(oVertex.Location); // The object could be stored in a metadata key, but because the // number of retrievals can be very large, it's more efficient to // store it in the Tag. If a Tag already exists, save it in a // metadata key. SaveTag(oVertex); oVertex.Tag = oFruchtermanReingoldVertexInfo; } foreach (IEdge oEdge in oGraph.Edges) { // Do the same for edges. In this case, each edge has just one // piece of information, the edge weight. SaveTag(oEdge); oEdge.Tag = (Single)EdgeUtil.GetPositiveEdgeWeight(oEdge); } }
TestGetVertexNamePair4() { Assert.AreEqual("A\vB", EdgeUtil.GetVertexNamePair("B", "A", false)); }
public override void OnInspectorGUI() { base.OnInspectorGUI(); dirty = false; rect = m_Img.rectTransform.rect; EditorGUILayout.PropertyField(m_keepOriginSize, true); curSize = m_Img.path.Count; showPath = EditorGUILayout.Foldout(showPath, "Path"); if (showPath) { EditorGUI.BeginChangeCheck(); EditorGUILayout.BeginHorizontal(); EditorGUI.indentLevel = 1; EditorGUILayout.LabelField("size", GUILayout.MaxWidth(200)); int newSize = EditorGUILayout.IntField(curSize); if (EditorGUI.EndChangeCheck()) { OnChange(); if (newSize < 0) { newSize = 0; } if (newSize < curSize) { m_Img.path.RemoveRange(newSize, curSize - newSize); } else if (newSize > curSize) { if (newSize > m_Img.path.Capacity) { m_Img.path.Capacity = newSize; } m_Img.path.AddRange(Enumerable.Repeat(new RectPoint(), newSize - curSize)); } } EditorGUILayout.EndHorizontal(); curSize = m_Img.path.Count; float f = EditorGUIUtility.labelWidth; EditorGUIUtility.labelWidth = 30; for (int i = 0; i < curSize; i++) { RectPointField(i, m_Img.path[i]); } EditorGUIUtility.labelWidth = f; } //EditorGUI.EndProperty(); EditorGUI.indentLevel = 0; m_Img.doPolygonUpdate = true; //EditorGUILayout.PropertyField(m_edgeTex, true); Texture2D tex = EditorGUILayout.ObjectField("EdgeTexture", texMull, typeof(Texture2D), true) as Texture2D; if (tex != null) { string path = AssetDatabase.GetAssetPath(tex.GetInstanceID()); TextureImporter textureImporter = AssetImporter.GetAtPath(path) as TextureImporter; TextureImporterSettings cacheSettings = new TextureImporterSettings(); textureImporter.ReadTextureSettings(cacheSettings); TextureImporterSettings tmp = new TextureImporterSettings(); textureImporter.ReadTextureSettings(tmp); tmp.readable = true; textureImporter.SetTextureSettings(tmp); AssetDatabase.ImportAsset(path); SobelEdgeDetection sobel = new SobelEdgeDetection(); var targetT2d = sobel.Detect(tex); //Rect rect = rectTransform.rect; m_Img.path = EdgeUtil.GetPoints(targetT2d, tex.width, tex.height).Select(v => { return(new RectPoint(v.x - tex.width * 0.5f, v.y - tex.height * 0.5f)); }).ToList(); textureImporter.SetTextureSettings(cacheSettings); AssetDatabase.ImportAsset(path); AssetDatabase.Refresh(); Debug.Log("Edge Detect Done"); dirty = true; } this.serializedObject.ApplyModifiedProperties(); if (dirty) { EditorUtility.SetDirty(target); } }
private void CreateMeshMaskByImage() { #if UNITY_EDITOR GameObject o = Selection.activeGameObject; if (o != null && o.GetComponent <Image>() != null) { Image img = o.GetComponent <Image>(); string path = AssetDatabase.GetAssetPath(img.mainTexture); if (!string.IsNullOrEmpty(path)) { TextureImporter textureImporter = AssetImporter.GetAtPath(path) as TextureImporter; TextureImporterSettings cacheSettings = new TextureImporterSettings(); textureImporter.ReadTextureSettings(cacheSettings); //将Texture临时设置为可读写 TextureImporterSettings tmp = new TextureImporterSettings(); textureImporter.ReadTextureSettings(tmp); tmp.readable = true; textureImporter.SetTextureSettings(tmp); AssetDatabase.ImportAsset(path); SobelEdgeDetection sobel = new SobelEdgeDetection(); Texture2D targetT2d = sobel.Detect(img.mainTexture as Texture2D); List <Vector2> vertices = EdgeUtil.GetPoints(targetT2d); for (int i = 0; i < vertices.Count; i++) { Vector3 vec = vertices[i]; vec.x -= targetT2d.width * 0.5f; vec.y -= targetT2d.height * 0.5f; vertices[i] = vec; } //恢复Texture设置 textureImporter.SetTextureSettings(cacheSettings); AssetDatabase.ImportAsset(path); MeshMask mm = o.GetComponent <MeshMask>(); PolygonCollider2D polygon2d = o.GetComponent <PolygonCollider2D>(); if (mm == null) { mm = o.AddComponent <MeshMask>(); } if (polygon2d == null) { polygon2d = o.AddComponent <PolygonCollider2D>(); } vertices = vertices.Select(p => { return(new Vector2(p.x / img.mainTexture.width * image.rectTransform.rect.width, p.y / img.mainTexture.height * image.rectTransform.rect.height)); }).ToList(); polygon2d.SetPath(0, vertices.ToArray()); mm.vertices = polygon2d.GetPath(0).ToList(); if (mm.vertices[0] == mm.vertices[vertices.Count - 1]) { mm.vertices.RemoveAt(mm.vertices.Count - 1); } Stopwatch sw = new Stopwatch(); sw.Start(); Triangulator tr = new Triangulator(mm.vertices.ToArray()); mm.triangles = tr.Triangulate().ToList(); sw.Stop(); Debug.Log("三角化耗时:" + sw.ElapsedMilliseconds + "ms"); AssetDatabase.Refresh(); } else { Debug.LogError("Image组件还没设置图片"); } } else { Debug.LogError("选中物体没有Image组件,请添加"); } #endif }
ExportToNewMatrixWorkbook() { AssertValid(); // Merge duplicate edges and add an edge weight column. (new DuplicateEdgeMerger()).MergeDuplicateEdges(m_oWorkbookToExport); // Read the workbook, including the edge weight column. ReadWorkbookContext oReadWorkbookContext = new ReadWorkbookContext(); oReadWorkbookContext.ReadEdgeWeights = true; IGraph oGraph = (new WorkbookReader()).ReadWorkbook( m_oWorkbookToExport, oReadWorkbookContext); IVertexCollection oVertices = oGraph.Vertices; Int32 iVertices = oVertices.Count; if (iVertices == 0) { throw new ExportWorkbookException( "There are no vertices to export." ); } Workbook oNewWorkbook = m_oWorkbookToExport.Application.Workbooks.Add(Missing.Value); Worksheet oNewWorksheet = (Worksheet)oNewWorkbook.ActiveSheet; // Fill in row 1 and column A with the vertex names, starting at B1 and // A2, respectively. String [,] asVertexNamesForRow1 = ExcelUtil.GetSingleRow2DStringArray( iVertices); String [,] asVertexNamesForColumnA = ExcelUtil.GetSingleColumn2DStringArray(iVertices); Int32 i = 0; foreach (IVertex oVertexI in oVertices) { asVertexNamesForRow1[1, i + 1] = asVertexNamesForColumnA[i + 1, 1] = oVertexI.Name; i++; } ExcelUtil.SetRangeValues((Range)oNewWorksheet.Cells[1, 2], asVertexNamesForRow1); ExcelUtil.SetRangeValues((Range)oNewWorksheet.Cells[2, 1], asVertexNamesForColumnA); asVertexNamesForRow1 = asVertexNamesForColumnA = null; // Now fill in the edge weights, row by row. Range oFirstColumnCell = (Range)oNewWorksheet.Cells[2, 2]; foreach (IVertex oVertexI in oVertices) { Object [,] aoEdgeWeights = ExcelUtil.GetSingleRow2DArray(iVertices); Int32 j = 0; foreach (IVertex oVertexJ in oVertices) { aoEdgeWeights[1, j + 1] = EdgeUtil.GetEdgeWeightSum(oVertexI, oVertexJ); j++; } ExcelUtil.SetRangeValues(oFirstColumnCell, aoEdgeWeights); oFirstColumnCell = oFirstColumnCell.get_Offset(1, 0); } return(oNewWorkbook); }
public override void UpdateFeedback(IRequest request, IFigure feedback) { var req = request as ConnectRequest; var edgeFeedback = feedback as IEdge; if (req == null || edgeFeedback == null) { return; } var anchor = req.ConnectingAnchor; var edge = req.ConnectingAnchor.Owner as IEdge; var srcClone = edge.Source == null? null: edge.Source.CloneFigure() as INode; var tgtClone = edge.Target == null? null: edge.Target.CloneFigure() as INode; if (srcClone != null) { edgeFeedback.Source = srcClone; } if (tgtClone != null) { edgeFeedback.Target = tgtClone; } if (req.IsDisconnect) { if (anchor.Kind == ConnectionAnchorKind.Source) { edgeFeedback.SourceAnchor.Disconnect(); edgeFeedback.SourceAnchor.Location = GetGridAdjustedPoint(req.NewLocation); } else { edgeFeedback.TargetAnchor.Disconnect(); edgeFeedback.TargetAnchor.Location = GetGridAdjustedPoint(req.NewLocation); } } else { edgeFeedback.ClearBendPoints(); if (edge.BendPoints.Count() > 0) { edgeFeedback.SetEdgePoints(edge.EdgePoints); } if (anchor.Kind == ConnectionAnchorKind.Source) { if (edge.Target == req.NewConnectableEditor.Figure && edge.EdgePointCount == 2) { var pts = EdgeUtil.GetLoopPoints(edge.Target.Bounds); edgeFeedback.SourceAnchor.Disconnect(); edgeFeedback.SetEdgePoints(pts); } else { var srcFig = req.NewConnectableEditor.Figure.CloneFigureOnly() as IConnectable; edgeFeedback.SourceAnchor.Connect(srcFig); edgeFeedback.SourceAnchor.Location = GetConnectionPoint(req); } } else { if (edge.Source == req.NewConnectableEditor.Figure && edge.EdgePointCount == 2) { var pts = EdgeUtil.GetLoopPoints(edge.Source.Bounds); edgeFeedback.TargetAnchor.Disconnect(); edgeFeedback.SetEdgePoints(pts); } else { var tgtFig = req.NewConnectableEditor.Figure.CloneFigure() as IConnectable; edgeFeedback.TargetAnchor.Connect(tgtFig); edgeFeedback.TargetAnchor.Location = GetConnectionPoint(req); } } } }
public override ICommand CreateCommand(IRequest request) { var req = request as CreateEdgeRequest; if (req == null) { return(null); } var edgePoints = default(Point[]); if (req.EdgeSourceEditor != null && req.EdgeSourceEditor == req.EdgeTargetEditor) { /// 同じ図形に両端をつなごうとしている場合はループ edgePoints = EdgeUtil.GetLoopPoints(req.EdgeSourceEditor.Figure.Bounds); } else if (req.EdgeSourceEditor != null && req.EdgeSourceEditor.Figure.ContainsPoint(req.EndPoint)) { /// StartもEndoも同じ図形だけどループにできない場合 // todo: 実装 return(null); } else { var edge = _feedback; edge.ClearBendPoints(); if (req.EdgeSourceEditor == null) { edge.SourceAnchor.Disconnect(); edge.SourceAnchor.Location = GetGridAdjustedPoint(req.StartPoint); } else { var srcFigClone = req.EdgeSourceEditor.Figure.CloneFigure() as INode; edge.SourceAnchor.Connect(srcFigClone); edge.SourceAnchor.Location = edge.GetConnectionPoint( edge.SourceAnchor, srcFigClone, GetGridAdjustedPoint(req.StartPoint) ); } if (req.EdgeTargetEditor == null) { edge.TargetAnchor.Disconnect(); edge.TargetAnchor.Location = GetGridAdjustedPoint(req.EndPoint); } else { var tgtFigClone = req.EdgeTargetEditor.Figure.CloneFigure() as INode; edge.TargetAnchor.Connect(tgtFigClone); edge.TargetAnchor.Location = edge.GetConnectionPoint( edge.TargetAnchor, tgtFigClone, GetGridAdjustedPoint(req.EndPoint) ); } edgePoints = new Point[2]; edgePoints[0] = edge.SourceAnchor.Location; edgePoints[1] = edge.TargetAnchor.Location; } return(new CreateEdgeCommand( _Host, req.ModelFactory, edgePoints, req.EdgeSourceEditor, req.EdgeTargetEditor )); }
CalculateAttractiveForces ( ICollection <IEdge> edgesToLayOut, Single k ) { Debug.Assert(edgesToLayOut != null); Debug.Assert(k != 0); AssertValid(); const String MethodName = "CalculateAttractiveForces"; foreach (IEdge oEdge in edgesToLayOut) { if (oEdge.IsSelfLoop) { // A vertex isn't attracted to itself. continue; } // Get the edge's vertices. IVertex oVertexV, oVertexU; EdgeUtil.EdgeToVertices(oEdge, this.ClassName, MethodName, out oVertexV, out oVertexU); // Retrieve the objects that store calculated values for the // vertices. FruchtermanReingoldVertexInfo oVertexInfoV = (FruchtermanReingoldVertexInfo)oVertexV.Tag; FruchtermanReingoldVertexInfo oVertexInfoU = (FruchtermanReingoldVertexInfo)oVertexU.Tag; TMathType tDeltaX = (TMathType)oVertexInfoV.UnboundedLocationX - (TMathType)oVertexInfoU.UnboundedLocationX; TMathType tDeltaY = (TMathType)oVertexInfoV.UnboundedLocationY - (TMathType)oVertexInfoU.UnboundedLocationY; TMathType tDelta = (TMathType)Math.Sqrt( (tDeltaX * tDeltaX) + (tDeltaY * tDeltaY) ); // Use the edge weight, which InitializeMetadata() stored in the // Tag. tDelta *= (Single)oEdge.Tag; TMathType tDisplacementV_X = (TMathType)oVertexInfoV.DisplacementX; TMathType tDisplacementV_Y = (TMathType)oVertexInfoV.DisplacementY; TMathType tDisplacementU_X = (TMathType)oVertexInfoU.DisplacementX; TMathType tDisplacementU_Y = (TMathType)oVertexInfoU.DisplacementY; // (Note that there is an obvious typo in the Fruchterman-Reingold // paper for computing the attractive force. The function fa(z) at // the top of Figure 1 is defined as x squared over k. It should // read z squared over k.) TMathType fa = (tDelta * tDelta) / (TMathType)k; if (tDelta == 0) { // TODO: Is this the correct way to handle vertices in the same // location? See the notes in CalculateRepulsiveForces(). continue; } Debug.Assert(tDelta != 0); TMathType faOverDelta = fa / tDelta; TMathType tFactorX = tDeltaX * faOverDelta; TMathType tFactorY = tDeltaY * faOverDelta; tDisplacementV_X -= tFactorX; tDisplacementV_Y -= tFactorY; tDisplacementU_X += tFactorX; tDisplacementU_Y += tFactorY; oVertexInfoV.DisplacementX = (Single)tDisplacementV_X; oVertexInfoV.DisplacementY = (Single)tDisplacementV_Y; oVertexInfoU.DisplacementX = (Single)tDisplacementU_X; oVertexInfoU.DisplacementY = (Single)tDisplacementU_Y; } }
CountEdges() { AssertValid(); if (m_bEdgesCounted) { return; } m_iUniqueEdges = 0; m_iEdgesWithDuplicates = 0; IEdgeCollection oEdges = m_oGraph.Edges; Boolean bGraphIsDirected = (m_oGraph.Directedness == GraphDirectedness.Directed); // Create a dictionary of vertex ID pairs. The key is the vertex ID // pair and the value is true if the edge has duplicates or false if it // doesn't. Dictionary <Int64, Boolean> oVertexIDPairs = new Dictionary <Int64, Boolean>(oEdges.Count); foreach (IEdge oEdge in oEdges) { Int64 i64VertexIDPair = EdgeUtil.GetVertexIDPair(oEdge); Boolean bEdgeHasDuplicate; if (oVertexIDPairs.TryGetValue(i64VertexIDPair, out bEdgeHasDuplicate)) { if (!bEdgeHasDuplicate) { // This is the edge's first duplicate. m_iUniqueEdges--; m_iEdgesWithDuplicates++; oVertexIDPairs[i64VertexIDPair] = true; } m_iEdgesWithDuplicates++; } else { m_iUniqueEdges++; oVertexIDPairs.Add(i64VertexIDPair, false); } } m_iTotalEdgesAfterMergingDuplicatesNoSelfLoops = 0; foreach (Int64 i64VertexIDPair in oVertexIDPairs.Keys) { Int32 iVertexID1 = (Int32)(i64VertexIDPair >> 32); Int32 iVertexID2 = (Int32)i64VertexIDPair; if (iVertexID1 != iVertexID2) { m_iTotalEdgesAfterMergingDuplicatesNoSelfLoops++; } } m_bEdgesCounted = true; AssertValid(); }
WriteEdge ( IEdge oEdge, Dictionary <Int32, Int32> oVertexIDToNumber, StreamWriter oStreamWriter ) { Debug.Assert(oEdge != null); Debug.Assert(oVertexIDToNumber != null); Debug.Assert(oStreamWriter != null); AssertValid(); const String MethodName = "SaveGraph"; // Retrieve the edge's vertices. IVertex oVertex1, oVertex2; EdgeUtil.EdgeToVertices(oEdge, this.ClassName, MethodName, out oVertex1, out oVertex2); Int32 iVertex1ID = oVertex1.ID; Int32 iVertex2ID = oVertex2.ID; // Retrieve the vertex numbers. Int32 iVertex1Number, iVertex2Number; if (!oVertexIDToNumber.TryGetValue(iVertex1ID, out iVertex1Number) || !oVertexIDToNumber.TryGetValue(iVertex2ID, out iVertex2Number) ) { throw new InvalidOperationException(String.Format( "The edge with the ID {0} has a vertex that is not in the" + " graph's Vertices collection." , oEdge.ID.ToString(NodeXLBase.Int32Format) )); } // Retrieve the edge weight, if it exists. Object oWeight = null; Double dWeight = DefaultEdgeWeight; if (oEdge.TryGetValue( ReservedMetadataKeys.EdgeWeight, typeof(Double), out oWeight)) { dWeight = (Double)oWeight; } // Format: // // Vi Vj weight oStreamWriter.WriteLine( "{0} {1} {2}" , iVertex1Number, iVertex2Number, dWeight ); }
SaveGraphCore ( IGraph graph, Stream stream ) { Debug.Assert(graph != null); Debug.Assert(stream != null); AssertValid(); // Get an array of non-isolated vertices. Isolated vertices don't get // saved. List <IVertex> oNonIsolatedVertices = GraphUtil.GetNonIsolatedVertices(graph); Int32 iNonIsolatedVertices = oNonIsolatedVertices.Count; if (oNonIsolatedVertices.Count == 0) { OnSaveError("There are no edges to export."); } StreamWriter oStreamWriter = new StreamWriter(stream, StreamEncoding); // Write the graph metadata. oStreamWriter.WriteLine( "DL" + "\r\nN={0}" + "\r\nFORMAT = FULLMATRIX DIAGONAL PRESENT" , iNonIsolatedVertices.ToString(CultureInfo.InvariantCulture) ); foreach (String sLabelHeader in new String [] { "ROW LABELS:", "COLUMN LABELS:" }) { oStreamWriter.WriteLine(sLabelHeader); foreach (IVertex oVertex in oNonIsolatedVertices) { oStreamWriter.WriteLine("\"" + oVertex.Name + "\""); } } // Now fill in the edge weights, row by row. oStreamWriter.WriteLine("DATA:"); for (Int32 i = 0; i < iNonIsolatedVertices; i++) { IVertex oVertexI = oNonIsolatedVertices[i]; for (Int32 j = 0; j < iNonIsolatedVertices; j++) { Double dEdgeWeight = EdgeUtil.GetEdgeWeight(oVertexI, oNonIsolatedVertices[j]); oStreamWriter.Write(dEdgeWeight.ToString( CultureInfo.InvariantCulture) + " "); } oStreamWriter.WriteLine(); } oStreamWriter.Flush(); }
TestGetVertexNamePair() { Assert.AreEqual("A\vB", EdgeUtil.GetVertexNamePair("A", "B", true)); }
TestGetVertexNamePair2() { Assert.AreEqual("B\vA", EdgeUtil.GetVertexNamePair("B", "A", true)); }
SaveGraphCore ( IGraph graph, Stream stream ) { Debug.Assert(graph != null); Debug.Assert(stream != null); AssertValid(); IVertexCollection oVertices = graph.Vertices; Int32 iVertices = oVertices.Count; if (oVertices.Count == 0) { OnSaveError("There are no vertices to export."); } StreamWriter oStreamWriter = new StreamWriter(stream, StreamEncoding); // Write the graph metadata. oStreamWriter.WriteLine( "DL" + "\r\nN={0}" + "\r\nFORMAT = FULLMATRIX DIAGONAL PRESENT" , iVertices.ToString(CultureInfo.InvariantCulture) ); foreach (String sLabelHeader in new String [] { "ROW LABELS:", "COLUMN LABELS:" }) { oStreamWriter.WriteLine(sLabelHeader); foreach (IVertex oVertex in oVertices) { oStreamWriter.WriteLine("\"" + oVertex.Name + "\""); } } // Now fill in the edge weights, row by row. oStreamWriter.WriteLine("DATA:"); foreach (IVertex oVertexI in oVertices) { foreach (IVertex oVertexJ in oVertices) { Double dEdgeWeightSum = EdgeUtil.GetEdgeWeightSum(oVertexI, oVertexJ); oStreamWriter.Write(dEdgeWeightSum.ToString( CultureInfo.InvariantCulture) + " "); } oStreamWriter.WriteLine(); } oStreamWriter.Flush(); }
// ======================================== // field // ======================================== // ======================================== // constructor // ======================================== // ======================================== // property // ======================================== // ======================================== // method // ======================================== public void Route(IEdge edge) { if (edge.Source == edge.Target) { if (edge.Source != null) { /// 同じ図形に両端がつながっている場合はループ var pts = EdgeUtil.GetLoopPoints(edge.Source.Bounds); edge.SetEdgePoints(pts); } return; } if (edge.EdgePointCount == 2) { /// first,lastしか点がない if (edge.IsSourceConnected && edge.IsTargetConnected) { /// Sourceの中心点とTargetの中心点を結ぶ var src = edge.Source as INode; var tgt = edge.Target as INode; var srcCenter = RectUtil.GetCenter(src.Bounds); var tgtCenter = RectUtil.GetCenter(tgt.Bounds); var line = new Line(tgtCenter, srcCenter); if (src.OuterFrame.IntersectsWith(line)) { edge.First = src.OuterFrame.GetIntersectionPoint(line); } else { edge.First = srcCenter; } line = new Line(srcCenter, tgtCenter); if (tgt.OuterFrame.IntersectsWith(line)) { edge.Last = tgt.OuterFrame.GetIntersectionPoint(line); } else { edge.Last = tgtCenter; } } else if (edge.IsSourceConnected) { /// Sourceの中心点とLastを結ぶ var src = edge.Source as INode; var srcCenter = RectUtil.GetCenter(src.Bounds); var line = new Line(edge.Last, srcCenter); if (src.OuterFrame.IntersectsWith(line)) { edge.First = src.OuterFrame.GetIntersectionPoint(line); } else { edge.First = srcCenter; } } else if (edge.IsTargetConnected) { /// Targetの中心点とFirstを結ぶ var tgt = edge.Target as INode; var tgtCenter = RectUtil.GetCenter(tgt.Bounds); var line = new Line(edge.First, tgtCenter); if (tgt.OuterFrame.IntersectsWith(line)) { edge.Last = tgt.OuterFrame.GetIntersectionPoint(line); } else { edge.Last = tgtCenter; } } else { /// 何もしない } } else if (edge.EdgePointCount > 2) { if (edge.IsSourceConnected) { /// SourceがつながっているのでFirstを調整 var src = edge.Source as INode; var srcCenter = RectUtil.GetCenter(src.Bounds); var line = new Line(edge.FirstRef.Next.EdgePoint, srcCenter); if (src.OuterFrame.IntersectsWith(line)) { edge.First = src.OuterFrame.GetIntersectionPoint(line); } else { edge.First = srcCenter; } } if (edge.IsTargetConnected) { /// TargetがつながっているのでLastを調整 var tgt = edge.Target as INode; var tgtCenter = RectUtil.GetCenter(tgt.Bounds); var line = new Line(edge.LastRef.Prev.EdgePoint, tgtCenter); if (tgt.OuterFrame.IntersectsWith(line)) { edge.Last = tgt.OuterFrame.GetIntersectionPoint(line); } else { edge.Last = tgtCenter; } } } }