コード例 #1
0
ファイル: Maths.cs プロジェクト: Vanaheimr/Aegir
        /// <summary>
        /// Calculate a delaunay triangulation for the given enumeration of pixels.
        /// </summary>
        /// <typeparam name="T">The type of the pixels.</typeparam>
        /// <param name="VoronoiFeatures">An enumeration of pixels of type T.</param>
        /// <returns>An enumeration of triangles of type T.</returns>
        public static IEnumerable<TriCircle> DelaunayTriangulation(this IEnumerable<VoronoiFeature> VoronoiFeatures)
        {
            #region Initial Checks

            var _VoronoiFeatures  = VoronoiFeatures.ToList();
            var _NumberOfFeatures = _VoronoiFeatures.Count;

            //if (_NumberOfFeatures < 3)
            //    throw new ArgumentException("Need at least three pixels for triangulation!");

            var TriCircles = new List<TriCircle>();

            #endregion

            #region Set up the first triangle

            var j = 0;
            VoronoiFeature[] tri1;
            TriCircle triangle = null;

            do
            {
                tri1     = _VoronoiFeatures.Skip(j++).Take(3).ToArray();
                triangle = new TriCircle(new GeoTriangle(tri1[0].GeoCoordinate, tri1[1].GeoCoordinate, tri1[2].GeoCoordinate));
            }
            while (triangle.Circle.Radius == 0);

            TriCircles.Add(triangle);
            _VoronoiFeatures = _VoronoiFeatures.Where(vf => !tri1.Contains(vf)).ToList();

            #endregion

            #region Include each point one at a time into the existing mesh

            for (int i = 0; i < _VoronoiFeatures.Count; i++)
            {

                var Found = false;

                #region The new voronoi feature lies inside an existing triangle

                var TriCircleList = TriCircles.Where(TriCircle => TriCircle.Deleted == false).
                                               OrderBy(TriCircle => TriCircle.Circle.Radius).ToArray();

                foreach (var TriCircle in TriCircleList)
                {

                    if (TriCircle.Triangle.Contains(_VoronoiFeatures[i].GeoCoordinate))
                    {

                        var Edges = new List<GeoLine>();

                        Edges.Add(new GeoLine(TriCircle.Triangle.P1, TriCircle.Triangle.P2));
                        Edges.Add(new GeoLine(TriCircle.Triangle.P2, TriCircle.Triangle.P3));
                        Edges.Add(new GeoLine(TriCircle.Triangle.P3, TriCircle.Triangle.P1));

                        // Add three new triangles for the current point
                        foreach (var _Edge in Edges)
                            TriCircles.Add(new TriCircle(new GeoTriangle(_Edge.P1, _Edge.P2, _VoronoiFeatures[i].GeoCoordinate)));

                        TriCircle.Deleted = true;
                        Found = true;
                        break;

                    }

                }

                #endregion

                #region An external feature

                if (!Found)
                {

                    var PointList1 = (TriCircles.Select(TriCircle => new
                    {
                        point = TriCircle.Triangle.P1,
                        distance = TriCircle.Triangle.P1.DistanceTo(_VoronoiFeatures[i].GeoCoordinate)
                    }).

                                     Union(
                                     TriCircles.Select(TriCircle => new
                                     {
                                         point = TriCircle.Triangle.P2,
                                         distance = TriCircle.Triangle.P2.DistanceTo(_VoronoiFeatures[i].GeoCoordinate)
                                     })).

                                     Union(
                                     TriCircles.Select(TriCircle => new
                                     {
                                         point = TriCircle.Triangle.P3,
                                         distance = TriCircle.Triangle.P3.DistanceTo(_VoronoiFeatures[i].GeoCoordinate)
                                     }))).

                                     OrderBy(agg => agg.distance).ToArray();

                    var PointList2 = PointList1.
                                     Where(v =>
                                     {

                                         var newLine = new GeoLine(_VoronoiFeatures[i].GeoCoordinate, v.point);

                                         foreach (var edges in TriCircles.Select(v2 => v2.Triangle.Borders))
                                         {
                                             foreach (var edge in edges)
                                             {
                                                 if (edge.IntersectsWith(newLine, false, true))
                                                 {
                                                     return false;
                                                 }
                                             }
                                         }

                                         return true;

                                     }).

                                     ToArray();

                    TriCircles.Add(new TriCircle(new GeoTriangle(PointList2[0].point, PointList2[1].point, _VoronoiFeatures[i].GeoCoordinate)));

                }

                #endregion

            }

            #endregion

            return TriCircles.Where(tc => tc.Deleted == false);//.Select(tc => tc.Triangle);
        }
コード例 #2
0
        /// <summary>
        /// Calculate a delaunay triangulation for the given enumeration of pixels.
        /// </summary>
        /// <typeparam name="T">The type of the pixels.</typeparam>
        /// <param name="VoronoiFeatures">An enumeration of pixels of type T.</param>
        /// <returns>An enumeration of triangles of type T.</returns>
        public static IEnumerable <TriCircle> DelaunayTriangulation(this IEnumerable <VoronoiFeature> VoronoiFeatures)
        {
            #region Initial Checks

            var _VoronoiFeatures  = VoronoiFeatures.ToList();
            var _NumberOfFeatures = _VoronoiFeatures.Count;

            //if (_NumberOfFeatures < 3)
            //    throw new ArgumentException("Need at least three pixels for triangulation!");

            var TriCircles = new List <TriCircle>();

            #endregion

            #region Set up the first triangle

            var j = 0;
            VoronoiFeature[] tri1;
            TriCircle        triangle = null;

            do
            {
                tri1     = _VoronoiFeatures.Skip(j++).Take(3).ToArray();
                triangle = new TriCircle(new GeoTriangle(tri1[0].GeoCoordinate, tri1[1].GeoCoordinate, tri1[2].GeoCoordinate));
            }while (triangle.Circle.Radius == 0);

            TriCircles.Add(triangle);
            _VoronoiFeatures = _VoronoiFeatures.Where(vf => !tri1.Contains(vf)).ToList();

            #endregion

            #region Include each point one at a time into the existing mesh

            for (int i = 0; i < _VoronoiFeatures.Count; i++)
            {
                var Found = false;

                #region The new voronoi feature lies inside an existing triangle

                var TriCircleList = TriCircles.Where(TriCircle => TriCircle.Deleted == false).
                                    OrderBy(TriCircle => TriCircle.Circle.Radius).ToArray();

                foreach (var TriCircle in TriCircleList)
                {
                    if (TriCircle.Triangle.Contains(_VoronoiFeatures[i].GeoCoordinate))
                    {
                        var Edges = new List <GeoLine>();

                        Edges.Add(new GeoLine(TriCircle.Triangle.P1, TriCircle.Triangle.P2));
                        Edges.Add(new GeoLine(TriCircle.Triangle.P2, TriCircle.Triangle.P3));
                        Edges.Add(new GeoLine(TriCircle.Triangle.P3, TriCircle.Triangle.P1));

                        // Add three new triangles for the current point
                        foreach (var _Edge in Edges)
                        {
                            TriCircles.Add(new TriCircle(new GeoTriangle(_Edge.P1, _Edge.P2, _VoronoiFeatures[i].GeoCoordinate)));
                        }

                        TriCircle.Deleted = true;
                        Found             = true;
                        break;
                    }
                }

                #endregion

                #region An external feature

                if (!Found)
                {
                    var PointList1 = (TriCircles.Select(TriCircle => new
                    {
                        point = TriCircle.Triangle.P1,
                        distance = TriCircle.Triangle.P1.DistanceTo(_VoronoiFeatures[i].GeoCoordinate)
                    }).

                                      Union(
                                          TriCircles.Select(TriCircle => new
                    {
                        point = TriCircle.Triangle.P2,
                        distance = TriCircle.Triangle.P2.DistanceTo(_VoronoiFeatures[i].GeoCoordinate)
                    })).

                                      Union(
                                          TriCircles.Select(TriCircle => new
                    {
                        point = TriCircle.Triangle.P3,
                        distance = TriCircle.Triangle.P3.DistanceTo(_VoronoiFeatures[i].GeoCoordinate)
                    }))).

                                     OrderBy(agg => agg.distance).ToArray();

                    var PointList2 = PointList1.
                                     Where(v =>
                    {
                        var newLine = new GeoLine(_VoronoiFeatures[i].GeoCoordinate, v.point);

                        foreach (var edges in TriCircles.Select(v2 => v2.Triangle.Borders))
                        {
                            foreach (var edge in edges)
                            {
                                if (edge.IntersectsWith(newLine, false, true))
                                {
                                    return(false);
                                }
                            }
                        }

                        return(true);
                    }).

                                     ToArray();

                    TriCircles.Add(new TriCircle(new GeoTriangle(PointList2[0].point, PointList2[1].point, _VoronoiFeatures[i].GeoCoordinate)));
                }

                #endregion
            }

            #endregion

            return(TriCircles.Where(tc => tc.Deleted == false));//.Select(tc => tc.Triangle);
        }