/// <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)); }
/// <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; }
/// <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); }
/// <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; }
/// <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]); }