Ejemplo n.º 1
0
 /// <summary>
 /// Join two polygones by an edge.
 /// </summary>
 /// <param name="other">the other polygone</param>
 /// <param name="edgeStart">the start of the edge that joines</param>
 /// <param name="edgeStart">the end of the edge that joines</param>
 /// <returns>-1: the polygone is closed. Otherwise the start/end key that was changed</returns>
 public int Join(PolygonLine other, int edgeStart, int edgeEnd)
 {
     return(this.JoinAndClose(other)
            ?? this.JoinSameDirection(other, edgeStart, edgeEnd)
            ?? this.JoinWithEdgeInInverseDirection(other, edgeStart, edgeEnd)
            ?? this.JoinReversingOtherPolygon(other, edgeStart, edgeEnd)
            ?? throw new InvalidOperationException($"Can't join s:{edgeStart} e:{edgeEnd}, ts: {this.StartKey} te: {this.EndKey}, os: {other.StartKey} oe: {other.EndKey}"));
 }
Ejemplo n.º 2
0
            /// <summary>
            /// Join and close the polygon if this and other is the same instance
            /// </summary>
            /// <param name="other">the other polygon line</param>
            /// <returns>-1 if the polygon was joined, null else</returns>
            private int?JoinAndClose(PolygonLine other)
            {
                if (ReferenceEquals(this, other))
                {
                    this.Closed = true;
                    return(-1);
                }

                return(null);
            }
Ejemplo n.º 3
0
            /// <summary>
            /// The connecting edge fits one start and one end. Join with consistent direction.
            /// </summary>
            /// <param name="other">the other polygon line</param>
            /// <param name="edgeStart">the start of the joining edge</param>
            /// <param name="edgeEnd">the end of the joining edge</param>
            /// <returns>The start/end key that was changed or null if it doesn't fit</returns>
            private int?JoinSameDirection(PolygonLine other, int edgeStart, int edgeEnd)
            {
                if (CompareEdgeToKeys(edgeStart, edgeEnd, this.EndKey, other.StartKey))
                {
                    return(this.AppendRange(other.vertexIds, other.EndKey));
                }

                if (CompareEdgeToKeys(edgeStart, edgeEnd, other.EndKey, this.StartKey))
                {
                    return(this.InsertRange(other.vertexIds, other.StartKey));
                }

                return(null);
            }
Ejemplo n.º 4
0
            /// <summary>
            /// Add a new edge to the polygon line. Either join two polygon lines, creates a new or adds the edge to the neighboring line
            /// </summary>
            /// <param name="start"></param>
            /// <param name="end"></param>
            private void AddEdge(int start, int end)
            {
                var startFits = this.openPolygones.TryGetValue(start, out var firstSegment);

                if (startFits)
                {
                    this.openPolygones.Remove(start);
                }

                var endFits = this.openPolygones.TryGetValue(end, out var lastSegment);

                if (endFits)
                {
                    this.openPolygones.Remove(end);
                }

                if (!startFits && !endFits)
                {
                    var segment = new PolygonLine(start, end);
                    this.openPolygones.Add(start, segment);
                    this.openPolygones.Add(end, segment);
                }
                else if (startFits && endFits)
                {
                    var remainingKeyOfOther = firstSegment.Join(lastSegment, start, end);
                    if (remainingKeyOfOther < 0)
                    {
                        this.closedPolygones.Add(firstSegment);
                    }
                    else
                    {
                        this.openPolygones[remainingKeyOfOther] = firstSegment;
                    }
                }
                else if (startFits)
                {
                    firstSegment.AddMatchingStart(start, end);
                    this.openPolygones[end] = firstSegment;
                }
                else
                {
                    lastSegment.AddMatchingEnd(start, end);
                    this.openPolygones[start] = lastSegment;
                }
            }
Ejemplo n.º 5
0
            /// <summary>
            /// new edge connects at both start or both end points, reverse the other segment and join
            /// </summary>
            /// <param name="other">the other polygon line</param>
            /// <param name="edgeStart">the start of the joining edge</param>
            /// <param name="edgeEnd">the end of the joining edge</param>
            /// <returns>The start/end key that was changed or null if it doesn't fit</returns>
            private int?JoinReversingOtherPolygon(PolygonLine other, int edgeStart, int edgeEnd)
            {
                var reversedOther = new List <int>(other.vertexIds);

                reversedOther.Reverse();

                if (CompareEdgeToKeysOrSwappedKeys(edgeStart, edgeEnd, this.StartKey, other.StartKey))
                {
                    this.Dirty = true;
                    return(this.InsertRange(reversedOther, other.EndKey));
                }

                if (CompareEdgeToKeysOrSwappedKeys(edgeStart, edgeEnd, this.EndKey, other.EndKey))
                {
                    this.Dirty = true;
                    return(this.AppendRange(reversedOther, other.StartKey));
                }

                return(null);
            }