Example #1
0
        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;
            }
        }
Example #2
0
        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;
            }
        }
Example #3
0
        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;
            }
        }
Example #4
0
        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;
            }
        }
Example #5
0
        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)
                        );
                }
            }
        }
Example #7
0
    /// <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;
    }
Example #8
0
        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);
        }
Example #9
0
        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);
        }
Example #10
0
        // === 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);
            }
        }
Example #12
0
        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();
        }
Example #13
0
        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);
        }
Example #14
0
        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);
            }
        }
Example #16
0
 TestGetVertexNamePair4()
 {
     Assert.AreEqual("A\vB", EdgeUtil.GetVertexNamePair("B", "A", false));
 }
Example #17
0
    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);
        }
    }
Example #18
0
    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
    }
Example #19
0
        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);
        }
Example #20
0
        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;
            }
        }
Example #23
0
        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();
        }
Example #24
0
        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
                );
        }
Example #25
0
        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();
        }
Example #26
0
 TestGetVertexNamePair()
 {
     Assert.AreEqual("A\vB", EdgeUtil.GetVertexNamePair("A", "B", true));
 }
Example #27
0
 TestGetVertexNamePair2()
 {
     Assert.AreEqual("B\vA", EdgeUtil.GetVertexNamePair("B", "A", true));
 }
Example #28
0
        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();
        }
Example #29
0
        // ========================================
        // 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;
                    }
                }
            }
        }