コード例 #1
0
ファイル: Demo.cs プロジェクト: zj831007/unity-teddy
        List <Segment2D> BuildContourSegments(Triangulation2D triangulation)
        {
            var triangles = teddy.triangulation.Triangles;

            var contour = new List <Segment2D>();

            var table = new Dictionary <Segment2D, HashSet <Triangle2D> >();

            for (int i = 0, n = triangles.Length; i < n; i++)
            {
                var t = triangles[i];
                if (!table.ContainsKey(t.s0))
                {
                    table.Add(t.s0, new HashSet <Triangle2D>());
                }
                if (!table.ContainsKey(t.s1))
                {
                    table.Add(t.s1, new HashSet <Triangle2D>());
                }
                if (!table.ContainsKey(t.s2))
                {
                    table.Add(t.s2, new HashSet <Triangle2D>());
                }

                table[t.s0].Add(t);
                table[t.s1].Add(t);
                table[t.s2].Add(t);
            }

            contour = table.Keys.ToList().FindAll(s => {
                return(table[s].Count == 1);
            }).ToList();

            return(contour);
        }
コード例 #2
0
ファイル: UsageTest.cs プロジェクト: manifolded/GiantsSteps
    void Awake()
    {
        // input points for a polygon2D contour
        List <Vector2> points = new List <Vector2>();

        // When calling PopulateSquarePerimeter you should prefer
        // a factor of 4 for the 'res' argument.
        PopulateSquarePerimeter(points, 1000, 20);

        // construct Polygon2D
        Polygon2D polygon = Polygon2D.Contour(points.ToArray());

        // construct Triangulation2D with Polygon2D and threshold angle (18f ~ 27f recommended)
        Triangulation2D triangulation = new Triangulation2D(polygon, 22.5f);

        // build a mesh from triangles in a Triangulation2D instance
        Mesh mesh = triangulation.Build();

        // Initialize gameObject
        //   assuming it starts out as an empty object
        gameObject.AddComponent <MeshFilter>();

        // GetComponent<MeshFilter>().sharedMesh = mesh;
        //gameObject.GetComponent<MeshFilter>().sharedMesh = mesh;
        gameObject.GetComponent <MeshFilter>().mesh = mesh;
        // gameObject.AddComponent<MeshRenderer>();

        //gameObject.AddComponent<MeshCollider>();

        gameObject.SetActive(false);
    }
コード例 #3
0
        public void SetTriangulation(Triangulation2D triangulation)
        {
            var mesh = triangulation.Build();

            GetComponent <MeshFilter>().sharedMesh = mesh;
            this.triangles = triangulation.Triangle2Ds;
        }
コード例 #4
0
ファイル: Teddy.cs プロジェクト: zj831007/unity-teddy
        protected Dictionary <Vertex2D, VertexNetwork2D> BuildTable(Triangulation2D tri)
        {
            var table     = new Dictionary <Vertex2D, VertexNetwork2D>();
            var triangles = tri.Triangles;

            for (int i = 0, n = triangles.Length; i < n; i++)
            {
                var      t = triangles[i];
                Vertex2D a = t.a, b = t.b, c = t.c;
                if (!table.ContainsKey(a))
                {
                    table.Add(a, new VertexNetwork2D(a, ExternalPoint(a)));
                }
                if (!table.ContainsKey(b))
                {
                    table.Add(b, new VertexNetwork2D(b, ExternalPoint(b)));
                }
                if (!table.ContainsKey(c))
                {
                    table.Add(c, new VertexNetwork2D(c, ExternalPoint(c)));
                }
            }
            // tri.Points.ForEach(p => {
            // if(!table.ContainsKey(p)) table.Add(p, new VertexNetwork2D(p, ExternalPoint(p)));
            // });
            return(table);
        }
コード例 #5
0
ファイル: Teddy.cs プロジェクト: zj831007/unity-teddy
        public Teddy(List <Vector2> points)
        {
            var polygon = Polygon2D.Contour(points.ToArray());

            triangulation = new Triangulation2D(polygon, 0f);
            Init(triangulation);
        }
コード例 #6
0
ファイル: Teddy.cs プロジェクト: zj831007/unity-teddy
        protected void Sew(Triangulation2D triangulation, Chord2D chord, Dictionary <Vertex2D, float> heightTable, int division)
        {
            var triangles = triangulation.Triangles.ToList();

            Dictionary <Triangle2D, bool> flags = new Dictionary <Triangle2D, bool>();

            // 既にSew済みのTriangle2Dを再度Sewする必要があるケースが存在する
            //  特定のChord2DのSrcとDstを含むTriangle2Dなのに,それ以外のChord2Dと共通点を持っているがために
            //	Spineと共通エッジを持つ場合のSewの処理がかけられず適切な分割ができていないケース
            Dictionary <Triangle2D, List <Triangle2D> > sews = new Dictionary <Triangle2D, List <Triangle2D> >();

            triangles.ForEach(t => flags.Add(t, false));

            SewRoutine(triangles, flags, sews, chord, null, division);
        }
コード例 #7
0
        /// <summary>
        /// This method returns a 3D representation of this area
        /// </summary>
        /// <param name="nodesDict">List of all the nodes on the map</param>
        /// <param name="map">bounds of the map</param>
        /// <param name="brush">Color of this area</param>
        /// <returns>ModelUIElement3D of this area</returns>
        public virtual ModelUIElement3D get3DSurface(Dictionary <long, OsmSharp.Osm.Node> nodesDict, Map map, System.Windows.Media.SolidColorBrush brush)
        {
            List <PointF> ptlist = getScaledPointsSurface(nodesDict, map);

            // Divide the polygons in triangles, this is code (and these two classes) are from: https://polygontriangulation.codeplex.com/
            PolygonData     poly      = new PolygonData(ptlist);
            List <PointF[]> triangles = Triangulation2D.Triangulate(poly);

            // Surrounding tags of the mesh
            ModelUIElement3D model         = new ModelUIElement3D();
            GeometryModel3D  geometryModel = new GeometryModel3D();

            // Mesh and his his properties
            MeshGeometry3D    mesh      = new MeshGeometry3D();
            DiffuseMaterial   material  = new DiffuseMaterial((System.Windows.Media.Brush)brush);
            Point3DCollection positions = new Point3DCollection();
            Int32Collection   indices   = new Int32Collection();

            // Add points and indices to their collection
            foreach (PointF[] points in triangles)
            {
                foreach (PointF point in points)
                {
                    positions.Add(new Point3D(point.X, point.Y, height));
                }

                int count = positions.Count;
                indices.Add(count - 3);
                indices.Add(count - 2);
                indices.Add(count - 1);
            }

            // Add these collections to the mesh
            mesh.Positions       = positions;
            mesh.TriangleIndices = indices;

            // Set the color of front and back of the triangle
            geometryModel.Material     = material;
            geometryModel.BackMaterial = material;

            // Add the mesh to the model
            geometryModel.Geometry = mesh;
            model.Model            = geometryModel;

            return(model);
        }
コード例 #8
0
        void Build()
        {
            points = Utils2D.Constrain(points, threshold);
            var polygon = Polygon2D.Contour(points.ToArray());

            var vertices = polygon.Vertices;

            if (vertices.Length < 3)
            {
                return;                                 // error
            }
            var triangulation = new Triangulation2D(polygon, angle);
            var go            = Instantiate(prefab);

            go.transform.SetParent(transform, false);
            go.GetComponent <DemoMesh>().SetTriangulation(triangulation);

            Clear();
        }
コード例 #9
0
        //called when data for any output pin is requested
        public void Evaluate(int SpreadMax)
        {
            int i = 0;

            FOutput.SliceCount = FInput.SliceCount;
            foreach (var input in FInput)
            {
                if (FEnabled[i])
                {
                    if (input.Any())
                    {
                        var polygon   = new Polygon(input.ToList());
                        var triangles = Triangulation2D.Triangulate(polygon);
                        FOutput[i].AssignFrom(triangles.SelectMany(t => t));
                    }
                }
                i++;
            }

            //FLogger.Log(LogType.Debug, "hi tty!");
        }
コード例 #10
0
ファイル: Teddy.cs プロジェクト: zj831007/unity-teddy
        void Init(Triangulation2D triangulation)
        {
            contourSegments = BuildContourSegments(triangulation);

            var triangles = triangulation.Triangles.ToList();

            faces = Categorize(triangles);

            var terminal = faces.Find(f => f.Type == Face2DType.Terminal);

            chord = GetChordalAxis(terminal, faces);

            var terminalChords = Traverse(chord, null, (Chord2D c) => {
                return(c.Face.Type == Face2DType.Terminal);
            });

            var convergence = new List <Vertex2D>();

            terminalChords.ForEach(c => {
                Prune(c, convergence);
            });

            Subdivide(chord);

            // var spine = GetSpinePoints(chord);
            var networkTable = BuildTable(triangulation);

            networks = BuildNetworks(triangulation, networkTable);
            Elevate(networks);

            heightTable = new Dictionary <Vertex2D, float>();
            foreach (Vertex2D v in networkTable.Keys)
            {
                heightTable.Add(v, networkTable[v].Height);
            }

            Sew(triangulation, chord, heightTable, 3);
        }
コード例 #11
0
ファイル: Teddy.cs プロジェクト: zj831007/unity-teddy
        protected List <VertexNetwork2D> BuildNetworks(Triangulation2D tri, Dictionary <Vertex2D, VertexNetwork2D> networkTable)
        {
            var network = new Dictionary <Vertex2D, HashSet <Vertex2D> >();

            var triangles = tri.Triangles;

            for (int i = 0, n = triangles.Length; i < n; i++)
            {
                var       t = triangles[i];
                Segment2D s0 = t.s0, s1 = t.s1, s2 = t.s2;
                if (!network.ContainsKey(t.a))
                {
                    network.Add(t.a, new HashSet <Vertex2D>());
                }
                if (!network.ContainsKey(t.b))
                {
                    network.Add(t.b, new HashSet <Vertex2D>());
                }
                if (!network.ContainsKey(t.c))
                {
                    network.Add(t.c, new HashSet <Vertex2D>());
                }
                network[s0.a].Add(s0.b); network[s0.b].Add(s0.a);
                network[s1.a].Add(s1.b); network[s1.b].Add(s1.a);
                network[s2.a].Add(s2.b); network[s2.b].Add(s2.a);
            }

            return(network.Keys.Select(v => {
                var n = networkTable[v];
                foreach (Vertex2D to in network[v])
                {
                    n.Connect(networkTable[to]);
                }
                return n;
            }).ToList());
        }
コード例 #12
0
ファイル: Teddy.cs プロジェクト: zj831007/unity-teddy
        protected List <Triangle2D> Sew(Dictionary <Vertex2D, float> heightTable, Triangulation2D tri, Segment2D left, Segment2D right, int division)
        {
            Vertex2D top, lb, rb;

            if (left.a == right.a)
            {
                top = left.a; lb = left.b; rb = right.b;
            }
            else if (left.a == right.b)
            {
                top = left.a; lb = left.b; rb = right.a;
            }
            else if (left.b == right.a)
            {
                top = left.b; lb = left.a; rb = right.b;
            }
            else
            {
                top = left.b; lb = left.a; rb = right.a;
            }

            Vertex2D[] lp = new Vertex2D[division];
            Vertex2D[] rp = new Vertex2D[division];
            lp[division - 1] = lb;
            rp[division - 1] = rb;

            float   inv = 1f / division;
            Vector2 ld = lb.Coordinate - top.Coordinate, rd = rb.Coordinate - top.Coordinate;
            float   lm = ld.magnitude, rm = rd.magnitude;
            // float th = heightTable[top], lh = heightTable[lb], rh = heightTable[rb];
            float th = heightTable[top], lh = heightTable[lb] - th, rh = heightTable[rb] - th;

            for (int i = 0; i < division - 1; i++)
            {
                float r = (float)(i + 1) * inv;
                lp[i] = triangulation.CheckAndAddVertex(top.Coordinate + ld * r);
                if (!heightTable.ContainsKey(lp[i]))
                {
                    // heightTable.Add(lp[i], th + (lh - th) * inv * (i + 1));
                    heightTable.Add(lp[i], th + QuarterOval(lh, lm, inv * (i + 1)));
                }

                rp[i] = triangulation.CheckAndAddVertex(top.Coordinate + rd * r);
                if (!heightTable.ContainsKey(rp[i]))
                {
                    // heightTable.Add(rp[i], th + (rh - th) * inv * (i + 1));
                    heightTable.Add(rp[i], th + QuarterOval(rh, rm, inv * (i + 1)));
                }
            }

            var triangles = new List <Triangle2D>();

            triangles.Add(triangulation.AddTriangle(top, lp[0], rp[0]));
            for (int i = 0; i < division - 1; i++)
            {
                var tl = triangulation.AddTriangle(lp[i], rp[i], lp[i + 1]);
                var tr = triangulation.AddTriangle(rp[i], rp[i + 1], lp[i + 1]);
                triangles.Add(tl); triangles.Add(tr);
            }

            return(triangles);
        }
コード例 #13
0
ファイル: Teddy.cs プロジェクト: wlstks7/unity-teddy
        void Sew(Triangulation2D triangulation, Chord2D chord, Dictionary <Vertex2D, float> heightTable, int division)
        {
            var triangles = triangulation.Triangles.ToList();

            Dictionary <Triangle2D, bool> flags = new Dictionary <Triangle2D, bool>();

            // 既にSew済みのTriangle2Dを再度Sewする必要があるケースが存在する
            //  特定のChord2DのSrcとDstを含むTriangle2Dなのに,それ以外のChord2Dと共通点を持っているがために
            //	Spineと共通エッジを持つ場合のSewの処理がかけられず適切な分割ができていないケース
            Dictionary <Triangle2D, List <Triangle2D> > sews = new Dictionary <Triangle2D, List <Triangle2D> >();

            triangles.ForEach(t => flags.Add(t, false));

            Action <Triangle2D, Segment2D[]> SewTriangle = (Triangle2D t, Segment2D[] segments) => {
                triangulation.RemoveTriangle(t);
                var sewTriangles = Sew(heightTable, triangulation, segments[0], segments[1], division);
                sews.Add(t, sewTriangles);
                flags[t] = true;
            };

            Action <Chord2D, Chord2D> SewRoutine;

            SewRoutine = (Chord2D current, Chord2D from) => {
                if (!current.Pruned)
                {
                    triangles.FindAll(t => {
                        return(t.HasPoint(current.Src) && (t.HasPoint(current.Dst) || !sews.ContainsKey(t)));
                    }).ForEach(t => {
                        Segment2D[] segments;

                        if (sews.ContainsKey(t))
                        {
                            foreach (Triangle2D st in sews[t])
                            {
                                triangulation.RemoveTriangle(st);
                            }
                            sews.Remove(t);
                        }

                        if (t.HasPoint(current.Dst))
                        {
                            Segment2D s = t.CommonSegment(current.Src, current.Dst);
                            segments    = t.ExcludeSegment(s);
                        }
                        else
                        {
                            segments = t.CommonSegments(current.Src);
                        }

                        SewTriangle(t, segments);
                    });
                }

                var next = current.Connection.FindAll(con => con != from);

                // Prune後のSpineで末端にあたる頂点
                bool terminal = next.All(con => con.Pruned);
                if (terminal && !current.Pruned)
                {
                    triangles.FindAll(t => {
                        return(!sews.ContainsKey(t) && t.HasPoint(current.Dst));
                    }).ForEach(t => {
                        var segments = t.CommonSegments(current.Dst);
                        SewTriangle(t, segments);
                    });
                }

                next.ForEach(to => {
                    SewRoutine(to, current);
                });
            };

            SewRoutine(chord, null);
        }