Exemple #1
0
        /// <summary>
        /// The menu items for this tree node
        /// </summary>
        /// <returns></returns>
        protected override List <MenuItem> GetMenuItems()
        {
            List <MenuItem> retVal = base.GetMenuItems();

            retVal.Add(new MenuItem("-"));
            retVal.Add(new MenuItem("Add parameter", new EventHandler(AddParameterHandler)));
            retVal.Add(new MenuItem("Add case", new EventHandler(AddCaseHandler)));
            retVal.Add(new MenuItem("-"));

            DataDictionary.Interpreter.InterpretationContext context = new DataDictionary.Interpreter.InterpretationContext(Item);
            if (Item.FormalParameters.Count == 1)
            {
                Parameter parameter = (Parameter)Item.FormalParameters[0];
                DataDictionary.Functions.Graph graph = Item.createGraph(context, parameter);
                if (graph != null && graph.Segments.Count != 0)
                {
                    retVal.Add(new MenuItem("Display", new EventHandler(DisplayHandler)));
                    retVal.Add(new MenuItem("-"));
                }
            }
            else if (Item.FormalParameters.Count == 2)
            {
                DataDictionary.Functions.Surface surface = Item.createSurface(context);
                if (surface != null && surface.Segments.Count != 0)
                {
                    retVal.Add(new MenuItem("Display", new EventHandler(DisplayHandler)));
                    retVal.Add(new MenuItem("-"));
                }
            }

            retVal.Add(new MenuItem("Delete", new EventHandler(DeleteHandler)));

            return(retVal);
        }
 /// <summary>
 /// Combines two surfaces by replacing in this the value of second
 /// on each segment of this == def
 /// </summary>
 /// <param name="second"></param>
 /// <param name="def"></param>
 /// <returns></returns>
 public Surface Override(Surface second)
 {
     return(CombineTwoSurfaces(this, second, Segment.Override));
 }
 /// <summary>
 /// Selects the minimum surface
 /// </summary>
 /// <param name="second"></param>
 /// <param name="def"></param>
 /// <returns></returns>
 public Surface Min(Surface second)
 {
     return(CombineTwoSurfaces(this, second, Segment.Min));
 }
 /// <summary>
 /// Multiplies two surfaces
 /// </summary>
 /// <param name="other"></param>
 /// <returns></returns>
 public Surface MultiplySurface(Surface other)
 {
     return(CombineTwoSurfaces(this, other, Segment.Mult));
 }
 /// <summary>
 /// Divides two surfaces
 /// </summary>
 /// <param name="other"></param>
 /// <returns></returns>
 public Surface DivideSurface(Surface other)
 {
     return(CombineTwoSurfaces(this, other, Segment.Divide));
 }
 /// <summary>
 /// Substract two surfaces
 /// </summary>
 /// <param name="other"></param>
 /// <returns></returns>
 public Surface SubstractSurface(Surface other)
 {
     return(CombineTwoSurfaces(this, other, Segment.Substract));
 }
 /// <summary>
 /// Adds two surfaces
 /// </summary>
 /// <param name="other"></param>
 /// <returns></returns>
 public Surface AddSurface(Surface other)
 {
     return(CombineTwoSurfaces(this, other, Segment.Add));
 }
        /// <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
        /// <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)
            {
                Segment segment_i = first.Segments[i];
                Segment 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
                            Graph 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
                            Graph 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
                            Graph 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
                            Graph 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;
                    }
                    Graph val = operation(segment_i.Graph, segment_j.Graph);
                    retVal.AddSegment(new Segment(start, end, val));
                    start = end;
                }
            }

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

                Graph 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)
            {
                Segment segment_j = second.Segments[j];

                Graph 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);
        }
 /// <summary>
 /// Merges tow surfaces, using the Y axis as the merge orientation
 /// </summary>
 /// <param name="otherSurface"></param>
 public static Surface MergeY(Surface first, Surface second)
 {
     return(CombineTwoSurfaces(first, second, Segment.Merge));
 }
        /// <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 <Segment> toProcess = new List <Segment>(otherSurface.Segments);
            List <Segment> toAdd     = new List <Segment>();

            while (toProcess.Count > 0)
            {
                Segment 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();
        }