Exemple #1
0
        public Dictionary<float, HLine> Split(List<float> Xs)
        {
            #region conditions
            // Xs can be empty, in which case this function returns the original line in the dict.
            foreach(float x in Xs)
            {
                Debug.Assert(x > Left && x < Right);
            }
            if(Xs.Count > 1)
            {
                for(int i = 1; i < Xs.Count; ++i)
                {
                    Debug.Assert(Xs[i - 1] < Xs[i]);
                }
            }
            #endregion conditions;

            Dictionary<float, HLine> lines = new Dictionary<float, HLine>();
            List<float> allXs = new List<float>();
            allXs.Add(Left);
            allXs.AddRange(Xs);
            allXs.Add(Right);
            for(int i = 1; i < allXs.Count; ++i)
            {
                HLine line = new HLine(allXs[i - 1], allXs[i], Y);
                lines.Add(line.Left, line);
            }
            return lines;
        }
Exemple #2
0
 /// <summary>
 /// Creates a TopEdge by inverting the bottomEdge
 /// </summary>
 public TopEdge(BottomEdge bottomEdge)
     : base()
 {
     foreach (HLine line in bottomEdge.Lines)
     {
         HLine fLine = new HLine(line.Left, line.Right, -line.Y);
         Lines.Add(fLine);
     }
 }
Exemple #3
0
        public Dictionary<float, HLine> Split(float x)
        {
            Debug.Assert(Left < x && Right > x);

            Dictionary<float, HLine> linesDict = new Dictionary<float, HLine>();
            HLine line1 = new HLine(Left, x, Y);
            HLine line2 = new HLine(x, Right, Y);
            linesDict.Add(line1.Left, line1);
            linesDict.Add(line2.Left, line2);
            return linesDict;
        }
Exemple #4
0
        public Dictionary <double, HLine> Split(double x)
        {
            M.Assert(Left <x && Right> x);

            Dictionary <double, HLine> linesDict = new Dictionary <double, HLine>();
            HLine line1 = new HLine(Left, x, Y);
            HLine line2 = new HLine(x, Right, Y);

            linesDict.Add(line1.Left, line1);
            linesDict.Add(line2.Left, line2);
            return(linesDict);
        }
Exemple #5
0
        public Dictionary <float, HLine> Split(float x)
        {
            Debug.Assert(Left <x && Right> x);

            Dictionary <float, HLine> linesDict = new Dictionary <float, HLine>();
            HLine line1 = new HLine(Left, x, Y);
            HLine line2 = new HLine(x, Right, Y);

            linesDict.Add(line1.Left, line1);
            linesDict.Add(line2.Left, line2);
            return(linesDict);
        }
Exemple #6
0
        /// <summary>
        /// The HLines from this edge, with the HLines at the beginning and end of the newLine split into two.
        /// The dictionary's key is the left edge of each HLine.
        /// </summary>
        private Dictionary <double, HLine> SplitEdge(HLine newLine, double leftY, double rightY)
        {
            M.Assert(Lines.Count > 0);

            Dictionary <double, HLine> splitEdge = new Dictionary <double, HLine>();

            foreach (HLine hline in Lines)
            {
                if (hline.Left < newLine.Left && hline.Right > newLine.Left && leftY > newLine.Y)
                {
                    Dictionary <double, HLine> splitLines1 = hline.Split(newLine.Left);
                    Dictionary <double, HLine> splitLines2 = new Dictionary <double, HLine>();
                    foreach (double x in splitLines1.Keys)
                    {
                        HLine line = splitLines1[x];
                        if (line.Left < newLine.Right && line.Right > newLine.Right && line.Y > newLine.Y)
                        {
                            splitLines2 = line.Split(newLine.Right);
                        }
                    }
                    foreach (double x in splitLines1.Keys)
                    {
                        if (!splitLines2.ContainsKey(x))
                        {
                            splitEdge.Add(splitLines1[x].Left, splitLines1[x]);
                        }
                    }

                    foreach (double x in splitLines2.Keys)
                    {
                        splitEdge.Add(splitLines2[x].Left, splitLines2[x]);
                    }
                }
                else if (hline.Left < newLine.Right && hline.Right > newLine.Right && rightY > newLine.Y)
                {
                    Dictionary <double, HLine> splitLines = hline.Split(newLine.Right);
                    foreach (double x in splitLines.Keys)
                    {
                        splitEdge.Add(splitLines[x].Left, splitLines[x]);
                    }
                }
                else
                {
                    splitEdge.Add(hline.Left, hline);
                }
            }

            return(splitEdge);
        }
Exemple #7
0
        public void AddLineToUpperEdge(HLine newLine)
        {
            M.Assert(newLine.Y != double.MaxValue);
            if (Lines.Count == 0)
            {
                Lines.Add(newLine);
            }
            else
            {
                double leftY  = this.YatX(newLine.Left);
                double rightY = this.YatX(newLine.Right);
                Dictionary <double, HLine> splitEdge    = SplitEdge(newLine, leftY, rightY);
                List <double> splitXsOnNewLine          = SplitXsOnNewLine(newLine);
                Dictionary <double, HLine> splitNewLine = newLine.Split(splitXsOnNewLine); // if

                List <HLine> newLines = new List <HLine>();
                double       currentX = splitEdge[0].Left;
                foreach (double x in splitEdge.Keys)
                {
                    if (splitNewLine.ContainsKey(x))
                    {
                        if (newLine.Y < splitEdge[x].Y)
                        {
                            newLines.Add(splitNewLine[x]);
                            currentX = splitNewLine[x].Right;
                        }
                        else
                        {
                            newLines.Add(splitEdge[x]);
                            currentX = splitEdge[x].Right;
                        }
                    }
                    else if (splitEdge[x].Left == currentX)
                    {
                        newLines.Add(splitEdge[x]);
                        currentX = splitEdge[x].Right;
                    }
                }

                for (int i = 1; i < newLines.Count; ++i)
                {
                    M.Assert(newLines[i - 1].Right == newLines[i].Left);
                }

                Lines = null;
                Lines = newLines;
            }
        }
Exemple #8
0
        /// <summary>
        /// If the hLine lies below any line in this bottom edge,
        /// then this bottom edge is adjusted accordingly.
        /// </summary>
        public override void Add(HLine hLine)
        {
            if (Lines.Count == 0)
            {
                Lines.Add(hLine);
            }
            else
            {
                TopEdge flippedEdge = FlipVertically();

                HLine flippedLine = new HLine(hLine.Left, hLine.Right, -hLine.Y);
                flippedEdge.AddLineToUpperEdge(flippedLine);

                Lines = flippedEdge.FlippedLines;
            }
        }
Exemple #9
0
        /// <summary>
        /// The x-coordinates on the newLine which intersect the verticals between the top Lines
        /// (The edge considered as a continuous, joined up line).
        /// This does NOT include the end points of the newLine.
        /// </summary>
        private List <double> SplitXsOnNewLine(HLine newLine)
        {
            List <double> splitXs = new List <double>();

            for (int i = 1; i < Lines.Count; ++i)
            {
                HLine leftEdgeLine  = Lines[i - 1];
                HLine rightEdgeLine = Lines[i];
                M.Assert(leftEdgeLine.Right == rightEdgeLine.Left);

                if (leftEdgeLine.Right > newLine.Left && leftEdgeLine.Right < newLine.Right)
                {
                    if ((leftEdgeLine.Y >= newLine.Y && rightEdgeLine.Y <= newLine.Y) ||
                        (leftEdgeLine.Y <= newLine.Y && rightEdgeLine.Y >= newLine.Y))
                    {
                        splitXs.Add(leftEdgeLine.Right);
                    }
                }
            }

            return(splitXs);
        }
Exemple #10
0
        /// <summary>
        /// returns the y-coordinate of this BottomEdge at X.
        /// If X greater than or equal to the leftX of an HLine, and less than the rightX of the same HLine,
        /// then the returned value is HLine.Y.
        /// Else If X is equal to the rightX of an Hline and there is another Hline to the right,
        /// {
        ///     if isTopEdge is true, then the returned value is the higher (=smaller) of the two Ys,
        ///     else the returned value is the lower (=greater) of the two Ys
        /// }
        /// </summary>
        protected double YatX(double X, bool isTopEdge)
        {
            double y = double.MaxValue;

            for (int i = 0; i < this.Lines.Count; ++i)
            {
                HLine hLine = this.Lines[i];
                if (hLine.Left <= X && hLine.Right > X)
                {
                    y = hLine.Y;
                    break;
                }
                else if (hLine.Right == X)
                {
                    if (i < this.Lines.Count - 1)
                    {
                        HLine nextHLine = this.Lines[i + 1];
                        if (isTopEdge)
                        {
                            y = nextHLine.Y < hLine.Y ? nextHLine.Y : hLine.Y;
                        }
                        else
                        {
                            y = nextHLine.Y > hLine.Y ? nextHLine.Y : hLine.Y;
                        }
                        break;
                    }
                    else
                    {
                        y = hLine.Y;
                        break;
                    }
                }
            }
            M.Assert(y != double.MaxValue);
            return(y);
        }
Exemple #11
0
        /// <summary>
        /// returns the y-coordinate of this BottomEdge at X.
        /// If X greater than or equal to the leftX of an HLine, and less than the rightX of the same HLine,
        /// then the returned value is HLine.Y.
        /// Else If X is equal to the rightX of an Hline and there is another Hline to the right,
        /// {
        ///     if isTopEdge is true, then the returned value is the higher (=smaller) of the two Ys,
        ///     else the returned value is the lower (=greater) of the two Ys
        /// }
        /// </summary>
        protected float YatX(float X, bool isTopEdge)
        {
            float y = float.MaxValue;

            for (int i = 0; i < this.Lines.Count; ++i)
            {
                HLine hLine = this.Lines[i];
                if (hLine.Left <= X && hLine.Right > X)
                {
                    y = hLine.Y;
                    break;
                }
                else if (hLine.Right == X)
                {
                    if (i < this.Lines.Count - 1)
                    {
                        HLine nextHLine = this.Lines[i + 1];
                        if (isTopEdge)
                        {
                            y = nextHLine.Y < hLine.Y ? nextHLine.Y : hLine.Y;
                        }
                        else
                        {
                            y = nextHLine.Y > hLine.Y ? nextHLine.Y : hLine.Y;
                        }
                        break;
                    }
                    else
                    {
                        y = hLine.Y;
                        break;
                    }
                }
            }
            Debug.Assert(y != float.MaxValue);
            return(y);
        }
Exemple #12
0
 /// <summary>
 /// If the bottom edge of the metrics object lies below any line in this bottom edge,
 /// then this bottom edge is adjusted accordingly.
 /// </summary>
 public override void Add(Metrics metrics)
 {
     HLine line = new HLine(metrics.Left, metrics.Right, metrics.Bottom);
     Add(line);
 }
Exemple #13
0
 /// <summary>
 /// Adds the hLine to the edge line.
 /// </summary>
 /// <param name="hLine"></param>
 public abstract void Add(HLine hLine);
Exemple #14
0
        /// <summary>
        /// If the bottom edge of the metrics object lies below any line in this bottom edge,
        /// then this bottom edge is adjusted accordingly.
        /// </summary>
        public override void Add(Metrics metrics)
        {
            HLine line = new HLine(metrics.Left, metrics.Right, metrics.Bottom);

            Add(line);
        }
Exemple #15
0
 /// <summary>
 /// Creates a TopEdge by inverting the bottomEdge
 /// </summary>
 public TopEdge(BottomEdge bottomEdge)
     : base()
 {
     foreach(HLine line in bottomEdge.Lines)
     {
         HLine fLine = new HLine(line.Left, line.Right, -line.Y);
         Lines.Add(fLine);
     }
 }
Exemple #16
0
 /// <summary>
 /// If the top edge of the metrics object lies above any line in this top edge,
 /// then this top edge is adjusted accordingly.
 /// </summary>
 public override void Add(Metrics metrics)
 {
     HLine hLine = new HLine(metrics.Left, metrics.Right, metrics.Top);
     AddLineToUpperEdge(hLine);
 }
Exemple #17
0
 /// <summary>
 /// If the line lies above any line in this top edge,
 /// then this top edge is adjusted accordingly.
 /// </summary>
 public override void Add(HLine hLine)
 {
     AddLineToUpperEdge(hLine);
 }
Exemple #18
0
 /// <summary>
 /// If the line lies above any line in this top edge,
 /// then this top edge is adjusted accordingly.
 /// </summary>
 public override void Add(HLine hLine)
 {
     AddLineToUpperEdge(hLine);
 }
Exemple #19
0
        /// <summary>
        /// If the top edge of the metrics object lies above any line in this top edge,
        /// then this top edge is adjusted accordingly.
        /// </summary>
        public override void Add(Metrics metrics)
        {
            HLine hLine = new HLine(metrics.Left, metrics.Right, metrics.Top);

            AddLineToUpperEdge(hLine);
        }
Exemple #20
0
        public void AddLineToUpperEdge(HLine newLine)
        {
            Debug.Assert(newLine.Y != float.MaxValue);
            if(Lines.Count == 0)
            {
                Lines.Add(newLine);
            }
            else
            {
                float leftY = this.YatX(newLine.Left);
                float rightY = this.YatX(newLine.Right);
                Dictionary<float, HLine> splitEdge = SplitEdge(newLine, leftY, rightY);
                List<float> splitXsOnNewLine = SplitXsOnNewLine(newLine);
                Dictionary<float, HLine> splitNewLine = newLine.Split(splitXsOnNewLine); // if

                List<HLine> newLines = new List<HLine>();
                float currentX = splitEdge[0].Left;
                foreach(float x in splitEdge.Keys)
                {
                    if(splitNewLine.ContainsKey(x))
                    {
                        if(newLine.Y < splitEdge[x].Y)
                        {
                            newLines.Add(splitNewLine[x]);
                            currentX = splitNewLine[x].Right;
                        }
                        else
                        {
                            newLines.Add(splitEdge[x]);
                            currentX = splitEdge[x].Right;
                        }
                    }
                    else if(splitEdge[x].Left == currentX)
                    {
                        newLines.Add(splitEdge[x]);
                        currentX = splitEdge[x].Right;
                    }
                }

                for(int i = 1; i < newLines.Count; ++i)
                {
                    Debug.Assert(newLines[i - 1].Right == newLines[i].Left);
                }

                Lines = null;
                Lines = newLines;
            }
        }
Exemple #21
0
 /// <summary>
 /// Adds the hLine to the edge line.
 /// </summary>
 /// <param name="hLine"></param>
 public abstract void Add(HLine hLine);
Exemple #22
0
        /// <summary>
        /// If the hLine lies below any line in this bottom edge,
        /// then this bottom edge is adjusted accordingly.
        /// </summary>
        public override void Add(HLine hLine)
        {
            if(Lines.Count == 0)
            {
                Lines.Add(hLine);
            }
            else
            {
                TopEdge flippedEdge = FlipVertically();

                HLine flippedLine = new HLine(hLine.Left, hLine.Right, -hLine.Y);
                flippedEdge.AddLineToUpperEdge(flippedLine);

                Lines = flippedEdge.FlippedLines;
            }
        }
Exemple #23
0
        /// <summary>
        /// The HLines from this edge, with the HLines at the beginning and end of the newLine split into two. 
        /// The dictionary's key is the left edge of each HLine.
        /// </summary>
        private Dictionary<float, HLine> SplitEdge(HLine newLine, float leftY, float rightY)
        {
            Debug.Assert(Lines.Count > 0);

            Dictionary<float, HLine> splitEdge = new Dictionary<float, HLine>();
            foreach(HLine hline in Lines)
            {
                if(hline.Left < newLine.Left && hline.Right > newLine.Left && leftY > newLine.Y)
                {
                    Dictionary<float, HLine> splitLines1 = hline.Split(newLine.Left);
                    Dictionary<float, HLine> splitLines2 = new Dictionary<float, HLine>();
                    foreach(float x in splitLines1.Keys)
                    {
                        HLine line = splitLines1[x];
                        if(line.Left < newLine.Right && line.Right > newLine.Right && line.Y > newLine.Y)
                        {
                            splitLines2 = line.Split(newLine.Right);
                        }
                    }
                    foreach(float x in splitLines1.Keys)
                    {
                        if(!splitLines2.ContainsKey(x))
                            splitEdge.Add(splitLines1[x].Left, splitLines1[x]);
                    }

                    foreach(float x in splitLines2.Keys)
                    {
                        splitEdge.Add(splitLines2[x].Left, splitLines2[x]);
                    }

                }
                else if(hline.Left < newLine.Right && hline.Right > newLine.Right && rightY > newLine.Y)
                {
                    Dictionary<float, HLine> splitLines = hline.Split(newLine.Right);
                    foreach(float x in splitLines.Keys)
                    {
                        splitEdge.Add(splitLines[x].Left, splitLines[x]);
                    }
                }
                else
                {
                    splitEdge.Add(hline.Left, hline);
                }
            }

            return splitEdge;
        }
Exemple #24
0
        /// <summary>
        /// The x-coordinates on the newLine which intersect the verticals between the top Lines
        /// (The edge considered as a continuous, joined up line).
        /// This does NOT include the end points of the newLine.
        /// </summary>
        private List<float> SplitXsOnNewLine(HLine newLine)
        {
            List<float> splitXs = new List<float>();
            for(int i = 1; i < Lines.Count; ++i)
            {
                HLine leftEdgeLine = Lines[i - 1];
                HLine rightEdgeLine = Lines[i];
                Debug.Assert(leftEdgeLine.Right == rightEdgeLine.Left);

                if(leftEdgeLine.Right > newLine.Left && leftEdgeLine.Right < newLine.Right)
                {
                    if((leftEdgeLine.Y >= newLine.Y && rightEdgeLine.Y <= newLine.Y)
                        || (leftEdgeLine.Y <= newLine.Y && rightEdgeLine.Y >= newLine.Y))
                    {
                        splitXs.Add(leftEdgeLine.Right);
                    }
                }
            }

            return splitXs;
        }