Пример #1
0
            /// <summary>
            ///     Compares two segments
            /// </summary>
            /// <param name="other"></param>
            /// <returns></returns>
            public int CompareTo(ISurfaceSegment other)
            {
                int retVal = 0;

                if (Start < other.Start)
                {
                    retVal = -1;
                }
                else if (Start > other.Start)
                {
                    retVal = 1;
                }
                else
                {
                    // Same start, compare the ends
                    if (End < other.End)
                    {
                        retVal = -1;
                    }
                    else if (End > other.End)
                    {
                        retVal = 1;
                    }
                }

                return(retVal);
            }
Пример #2
0
        /// <summary>
        ///     Reduces the graph to the boundaries provided as parameter
        /// </summary>
        /// <param name="boundaries"></param>
        /// <returns>The reduced graph</returns>
        public void Reduce(List <ISegment> boundaries)
        {
            List <ISurfaceSegment> tmp = new List <ISurfaceSegment>();

            int i = 0;

            while (i < Segments.Count)
            {
                ISurfaceSegment segment = Segments[i];
                foreach (Segment newSegment in segment.Reduce(boundaries))
                {
                    tmp.Add(newSegment);
                }
                i += 1;
            }

            Segments = tmp;
        }
Пример #3
0
        /// <summary>
        ///     Performs an operation based on two surfaces.
        /// </summary>
        /// <param name="first">the first surface</param>
        /// <param name="second">the second surface</param>
        /// <param name="operation">the operation to perform on these graphs</param>
        /// <returns>the new graph</returns>
        private static Surface CombineTwoSurfaces(Surface first, Surface second, Segment.Op operation)
        {
            Surface retVal = new Surface(first.XParameter, first.YParameter);

            if (retVal.XParameter == null)
            {
                retVal.XParameter = second.XParameter;
            }
            if (retVal.YParameter == null)
            {
                retVal.YParameter = second.YParameter;
            }

            int i = 0;
            int j = 0;

            double start = 0;

            while (i < first.Segments.Count && j < second.Segments.Count)
            {
                ISurfaceSegment segment_i = first.Segments[i];
                ISurfaceSegment segment_j = second.Segments[j];

                if (segment_i.Start != segment_j.Start && start <= segment_i.Start && start <= segment_j.Start)
                {
                    if (segment_i.Start < segment_j.Start)
                    {
                        // First consider segment_i where no segment_j is available
                        if (segment_i.End <= segment_j.Start)
                        {
                            // No overlap
                            IGraph val = operation(segment_i.Graph, null);
                            retVal.AddSegment(new Segment(start, segment_i.End, val));
                            start = segment_i.End;
                            i     = i + 1;
                        }
                        else
                        {
                            // Overlap between segment_i and segment_j, segment_i is before segment_j
                            IGraph val = operation(segment_i.Graph, null);
                            retVal.AddSegment(new Segment(start, segment_j.Start, val));
                            start = segment_j.Start;
                        }
                    }
                    else
                    {
                        // First consider segment_j where no segment_i is available
                        if (segment_j.End <= segment_i.Start)
                        {
                            // No overlap
                            IGraph val = operation(segment_j.Graph, null);
                            retVal.AddSegment(new Segment(start, segment_j.End, val));
                            start = segment_j.End;
                            j     = j + 1;
                        }
                        else
                        {
                            // Overlap between segment_i and segment_j, segment_j is before segment_i
                            IGraph val = operation(segment_j.Graph, null);
                            retVal.AddSegment(new Segment(start, segment_i.Start, val));
                            start = segment_i.Start;
                        }
                    }
                }
                else
                {
                    double end;
                    if (segment_i.End < segment_j.End)
                    {
                        end = segment_i.End;
                        i   = i + 1;
                    }
                    else
                    {
                        if (segment_i.End == segment_j.End)
                        {
                            i = i + 1;
                        }
                        end = segment_j.End;
                        j   = j + 1;
                    }
                    IGraph val = operation(segment_i.Graph, segment_j.Graph);
                    retVal.AddSegment(new Segment(start, end, val));
                    start = end;
                }
            }

            while (i < first.Segments.Count)
            {
                ISurfaceSegment segment_i = first.Segments[i];

                IGraph val = operation(segment_i.Graph, null);
                retVal.AddSegment(new Segment(start, segment_i.End, val));

                start = segment_i.End;
                i     = i + 1;
            }

            while (j < second.Segments.Count)
            {
                ISurfaceSegment segment_j = second.Segments[j];

                IGraph val = operation(null, segment_j.Graph);
                retVal.AddSegment(new Segment(start, segment_j.End, val));

                start = segment_j.End;
                j     = j + 1;
            }

            retVal.MergeDuplicates();

            return(retVal);
        }
Пример #4
0
        /// <summary>
        ///     Merges a surface within this one, using the X axis as the merge orientation
        /// </summary>
        /// <param name="otherSurface"></param>
        public void MergeX(Surface otherSurface)
        {
            List <ISurfaceSegment> toProcess = new List <ISurfaceSegment>(otherSurface.Segments);
            List <ISurfaceSegment> toAdd     = new List <ISurfaceSegment>();

            while (toProcess.Count > 0)
            {
                ISurfaceSegment segment = toProcess[0];
                toProcess.Remove(segment);

                // Reduce this segment according to the existing segments
                foreach (Segment existingSegment in Segments)
                {
                    if (existingSegment.Start <= segment.Start)
                    {
                        if (existingSegment.End < segment.End)
                        {
                            if (existingSegment.End > segment.Start)
                            {
                                // The existing segment reduces the start of this segment
                                segment.Start = existingSegment.End;
                            }
                        }
                        else
                        {
                            // This segment is completely overriden by the existing segment;
                            segment = null;
                            break;
                        }
                    }
                    else
                    {
                        // existingSegment.Start > segment.Start
                        if (existingSegment.Start < segment.End)
                        {
                            if (existingSegment.End < segment.End)
                            {
                                // This segment splits the current segment in two.
                                Segment newSegment = new Segment(existingSegment.End, segment.End, segment.Graph);
                                toProcess.Insert(0, newSegment);
                            }
                            segment.End = existingSegment.Start;
                        }
                        else
                        {
                            // the existing segment does not impact this segment
                        }
                    }
                }

                if (segment != null)
                {
                    if (segment.Start < segment.End)
                    {
                        toAdd.Add(segment);
                    }
                }
            }

            Segments.AddRange(toAdd);
            Segments.Sort();
        }
Пример #5
0
 /// <summary>
 ///     Constructor
 /// </summary>
 /// <param name="other">The other segment to copy</param>
 public Segment(ISurfaceSegment other)
 {
     Start = other.Start;
     End   = other.End;
     Graph = other.Graph;
 }