Пример #1
0
        /// <summary>
        /// Converts all <see cref="VoronoiRegions"/> to a planar <see cref="Subdivision"/>.
        /// </summary>
        /// <returns>
        /// A <see cref="SubdivisionMap"/> containing a new <see cref="Subdivision"/> whose bounded
        /// <see cref="Subdivision.Faces"/> correspond to the <see cref="VoronoiRegions"/> of the
        /// <see cref="VoronoiResults"/>.</returns>
        /// <remarks><para>
        /// The returned <see cref="SubdivisionMap"/> also provides a mapping between the zero-based
        /// indices of all <see cref="GeneratorSites"/> and <see cref="VoronoiRegions"/> and the
        /// corresponding <see cref="Subdivision.Faces"/>. This mapping will become invalid as soon
        /// as the created <see cref="Subdivision"/> is changed.
        /// </para><para>
        /// <b>ToVoronoiSubdivision</b> creates all <see cref="VoronoiRegions"/> if they have not
        /// yet been calculated. Call <see cref="ClearVoronoiRegions"/> if you no longer require
        /// this property after <b>ToVoronoiSubdivision</b> has returned.</para></remarks>

        public SubdivisionMap ToVoronoiSubdivision()
        {
            var division = Subdivision.FromPolygons(VoronoiRegions);

            int regionCount = VoronoiRegions.Length;

            Debug.Assert(GeneratorSites.Length == regionCount);
            Debug.Assert(division.Faces.Count == regionCount + 1);

            var faceToSite = new int[regionCount];
            var siteToFace = new SubdivisionFace[regionCount];

            // determine equivalence of faces and VoronoiRegions indices
            // (which are in turn equivalent to GeneratorSites indices)
            for (int i = 0; i < VoronoiRegions.Length; i++)
            {
                PointD[]        polygon = VoronoiRegions[i];
                SubdivisionFace face    = division.FindFace(polygon);

                // bounded faces start at creation index one
                faceToSite[face._key - 1] = i;
                siteToFace[i]             = face;
            }

            return(new SubdivisionMap(division, this, faceToSite, siteToFace));
        }
Пример #2
0
        /// <summary>
        /// Initializes a new instance of the <see cref="SubdivisionEdge"/> class with the specified
        /// unique key, origin, incident face, twin, next and previous half-edge.</summary>
        /// <param name="key">
        /// The unique key of the <see cref="SubdivisionEdge"/> within its containing <see
        /// cref="Subdivision"/>.</param>
        /// <param name="origin">
        /// The coordinates where the <see cref="SubdivisionEdge"/> begins.</param>
        /// <param name="twin">
        /// The <see cref="SubdivisionEdge"/> that is the twin of the current instance.</param>
        /// <param name="face">
        /// The <see cref="SubdivisionFace"/> that is bounded by the <see cref="SubdivisionEdge"/>.
        /// </param>
        /// <param name="next">
        /// The next <see cref="SubdivisionEdge"/> that bounds the same <paramref name="face"/>.
        /// </param>
        /// <param name="previous">
        /// The previous <see cref="SubdivisionEdge"/> that bounds the same <paramref name="face"/>.
        /// </param>
        /// <remarks>
        /// This constructor is intended for unit testing.</remarks>

        internal SubdivisionEdge(int key, PointD origin, SubdivisionEdge twin,
                                 SubdivisionFace face, SubdivisionEdge next, SubdivisionEdge previous)
        {
            _key      = key;
            _origin   = origin;
            _twin     = twin;
            _face     = face;
            _next     = next;
            _previous = previous;
        }
Пример #3
0
        /// <summary>
        /// Sets the <see cref="Face"/> property of this <see cref="SubdivisionEdge"/> and all other
        /// half-edges in the same cycle to the specified value.</summary>
        /// <param name="face">
        /// The new value for the <see cref="Face"/> property of each <see cref="SubdivisionEdge"/>.
        /// </param>

        internal void SetAllFaces(SubdivisionFace face)
        {
            Debug.Assert(face != null);

            SubdivisionEdge cursor = this;

            do
            {
                cursor._face = face;
                cursor       = cursor._next;
            } while (cursor != this);
        }
Пример #4
0
        /// <summary>
        /// Initializes a new instance of the <see cref="SubdivisionElement"/> structure with the
        /// specified <see cref="SubdivisionFace"/>.</summary>
        /// <param name="face">
        /// The <see cref="SubdivisionFace"/> stored in the <see cref="SubdivisionElement"/>.
        /// </param>
        /// <remarks>
        /// <see cref="ElementType"/> is set to <see cref="SubdivisionElementType.Face"/>.</remarks>

        public SubdivisionElement(SubdivisionFace face)
        {
            ElementType = SubdivisionElementType.Face;
            _value      = face;
            _vertex     = PointD.Empty;
        }
Пример #5
0
            /// <summary>
            /// Converts the specified <see cref="SubdivisionFace"/> into the associated <see
            /// cref="GeneratorSites"/> index.</summary>
            /// <param name="face">
            /// The <see cref="SubdivisionFace"/> to convert.</param>
            /// <returns>
            /// The zero-based <see cref="GeneratorSites"/> index associated with <paramref
            /// name="face"/>.</returns>
            /// <exception cref="IndexOutOfRangeException">
            /// <paramref name="face"/> contains a <see cref="SubdivisionFace.Key"/> that is less
            /// than one or greater than the number of <see cref="GeneratorSites"/>.</exception>
            /// <exception cref="NullReferenceException">
            /// <paramref name="face"/> is a null reference.</exception>

            public int FromFace(SubdivisionFace face)
            {
                return(_faceToSite[face._key - 1]);
            }