Beispiel #1
0
        // ******************************************************************
        protected override void SetQuadrantLimits()
        {
            T firstPoint = this._listOfListOfPoint.First().First();

            double rightX = _xGet(firstPoint);
            double rightY = _yGet(firstPoint);

            double topX = rightX;
            double topY = rightY;

            foreach (var enumOfPoints in _listOfListOfPoint)
            {
                foreach (var point in enumOfPoints)
                {
                    if (_xGet(point).LargerOrEqualWithTol(rightX))
                    {
                        if (_xGet(point).EqualsWithTol(rightX))
                        {
                            if (_yGet(point).LargerWithTol(rightY))
                            {
                                rightY = _yGet(point);
                            }
                        }
                        else
                        {
                            rightX = _xGet(point);
                            rightY = _yGet(point);
                        }
                    }

                    if (_yGet(point).LargerOrEqualWithTol(topY))
                    {
                        if (_yGet(point).EqualsWithTol(topY))
                        {
                            if (_xGet(point).LargerWithTol(topX))
                            {
                                topX = _xGet(point);
                            }
                        }
                        else
                        {
                            topX = _xGet(point);
                            topY = _yGet(point);
                        }
                    }
                }
            }

            FirstPoint = new PointInfo <T>(_pointConstructor(rightX, rightY), _xGet, _yGet, _pointEqual);
            LastPoint  = new PointInfo <T>(_pointConstructor(topX, topY), _xGet, _yGet, _pointEqual);
            RootPoint  = _pointConstructor(topX, rightY);
        }
Beispiel #2
0
        // ******************************************************************
        protected override void SetQuadrantLimits()
        {
            T firstPoint = this._listOfListOfPoint.First().First();

            double leftX = _xGet(firstPoint);
            double leftY = _yGet(firstPoint);

            double bottomX = leftX;
            double bottomY = leftY;

            foreach (var enumOfPoints in _listOfListOfPoint)
            {
                foreach (var point in enumOfPoints)
                {
                    if (_xGet(point).SmallerOrEqualWithTol(leftX))
                    {
                        if (_xGet(point).EqualsWithTol(leftX))
                        {
                            if (_yGet(point).SmallerWithTol(leftY))
                            {
                                leftY = _yGet(point);
                            }
                        }
                        else
                        {
                            leftX = _xGet(point);
                            leftY = _yGet(point);
                        }
                    }

                    if (_yGet(point).SmallerOrEqualWithTol(bottomY))
                    {
                        if (_yGet(point).EqualsWithTol(bottomY))
                        {
                            if (_xGet(point).SmallerWithTol(bottomX))
                            {
                                bottomX = _xGet(point);
                            }
                        }
                        else
                        {
                            bottomX = _xGet(point);
                            bottomY = _yGet(point);
                        }
                    }
                }
            }

            FirstPoint = new PointInfo <T>(_pointConstructor(leftX, leftY), _xGet, _yGet, _pointEqual);
            LastPoint  = new PointInfo <T>(_pointConstructor(bottomX, bottomY), _xGet, _yGet, _pointEqual);
            RootPoint  = _pointConstructor(bottomX, leftY);
        }
Beispiel #3
0
        // ******************************************************************
        protected override void TryAdd(double x, double y)
        {
            int indexLow = 0;
            int indexMax = HullPoints.Count - 1;
            int indexHi  = indexMax;

            while (indexLow != indexHi - 1)
            {
                int index = ((indexHi - indexLow) >> 1) + indexLow;

                if (IsValueCannotBeConvexValueToAnotherOne(x, y, HullPoints[index].X, HullPoints[index].Y))
                {
                    return;
                }

                if (x.LargerWithTol(HullPoints[index].X))
                {
                    indexHi = index;
                    continue;
                }

                if (x.SmallerWithTol(HullPoints[index].X))
                {
                    indexLow = index;
                    continue;
                }

                if (x.EqualsWithTol(HullPoints[index].X))
                {
                    indexLow = index;
                    indexHi  = index + 1;
                }

                break;
            }

            PointInfo <T> ptiBefore = HullPoints[indexLow];

            if (y.SmallerOrEqualWithTol(ptiBefore.Y))
            {
                return;                 // Eliminated without slope calc
            }

            PointInfo <T> ptiAfter = HullPoints[indexHi];

            double slopeToNext = Geometry.CalcSlope(x, y, ptiAfter.X, ptiAfter.Y);

            if (slopeToNext.LargerWithTol(ptiBefore.SlopeToNext))
            {
                // We keep it (insert, or change existing one)

                int indexLowToRemove = indexHi;
                int indexHiToRemove  = indexLow;

                // Find proper value of indexHiToRemove to appropriate index (adjustement that do not require calc of slope)
                if (HullPoints[indexHi].Y.SmallerWithTol(y))                 // We can remove 1 or more points without slope calc
                {
                    indexHiToRemove = indexHi;
                    while (HullPoints[indexHiToRemove + 1].Y.SmallerWithTol(y))
                    {
                        indexHiToRemove++;
                    }
                }

                // Find proper value of indexHiToRemove to appropriate index (adjustement that require calc of slope)
                while (indexHiToRemove + 1 < indexMax)
                {
                    double slopeToNewIndexHiToRemovePlus1 = Geometry.CalcSlope(x, y, HullPoints[indexHiToRemove + 1].X,
                                                                               HullPoints[indexHiToRemove + 1].Y);

                    double slopeToNewIndexHiToRemovePlus2 = Geometry.CalcSlope(x, y, HullPoints[indexHiToRemove + 2].X,
                                                                               HullPoints[indexHiToRemove + 2].Y);

                    if (slopeToNewIndexHiToRemovePlus2.LargerWithTol(slopeToNewIndexHiToRemovePlus1))
                    {
                        break;
                    }

                    indexHiToRemove++;
                }

                // Find proper value of indexLowToRemove to appropriate index (adjustement that require calc of slope)
                while (indexLowToRemove - 1 > 0)
                {
                    double slopeToNewIndexLowToRemoveMinus1 = Geometry.CalcSlope(x, y, HullPoints[indexLowToRemove - 1].X,
                                                                                 HullPoints[indexLowToRemove - 1].Y);

                    double slopeToNewIndexLowToRemoveMinus2 = Geometry.CalcSlope(x, y, HullPoints[indexLowToRemove - 2].X,
                                                                                 HullPoints[indexLowToRemove - 2].Y);

                    if (slopeToNewIndexLowToRemoveMinus2.SmallerWithTol(slopeToNewIndexLowToRemoveMinus1))
                    {
                        break;
                    }

                    indexLowToRemove--;
                }

                PointInfo <T> newPointInfo;
                if (indexHiToRemove == indexLow)                 // No point to invalidate after, already calculated slope to next is still valid
                {
                    newPointInfo = new PointInfo <T>(_pointConstructor(x, y), _xGet, _yGet, _pointEqual, slopeToNext);
                }
                else
                {
                    newPointInfo = new PointInfo <T>(_pointConstructor(x, y), _xGet, _yGet, _pointEqual, Geometry.CalcSlope(x, y, HullPoints[indexHiToRemove + 1].X, HullPoints[indexHiToRemove + 1].Y));
                }

                if (indexHiToRemove >= indexLowToRemove)                 // Any existing hull point become invalide ?
                {
                    HullPoints[indexLowToRemove] = newPointInfo;

                    if (indexHiToRemove > indexLowToRemove)
                    {
                        HullPoints.RemoveRange(indexLowToRemove + 1, indexHiToRemove - indexLowToRemove);
                    }
                }
                else
                {
                    HullPoints.Insert(indexHi, newPointInfo);
                }

                HullPoints[indexLowToRemove - 1].SlopeToNext = Geometry.CalcSlope(x, y, HullPoints[indexLowToRemove - 1].X, HullPoints[indexLowToRemove - 1].Y);
            }
        }
Beispiel #4
0
        // ******************************************************************
        public T[] GetResultsAsArrayOfPoint()
        {
            if (_listOfListOfPoint == null || !_listOfListOfPoint.Any() || !_listOfListOfPoint.First().Any())
            {
                return(new T[0]);
            }

            int indexQ1Start;
            int indexQ2Start;
            int indexQ3Start;
            int indexQ4Start;
            int indexQ1End;
            int indexQ2End;
            int indexQ3End;
            int indexQ4End;

            PointInfo <T> lastPoint = _q4.HullPoints[_q4.HullPoints.Count - 1];

            if (_q1.HullPoints.Count == 1)
            {
                indexQ1Start = 0;
                indexQ1End   = 0;
                lastPoint    = _q1.HullPoints[0];
            }
            else
            {
                indexQ1Start = 0;
                indexQ1End   = _q1.HullPoints.Count - 1;
                lastPoint    = _q1.HullPoints[indexQ1End];
            }

            if (_q2.HullPoints.Count == 1)
            {
                if (_q2.FirstPoint.Equals(lastPoint))
                {
                    indexQ2Start = 1;
                    indexQ2End   = 0;
                }
                else
                {
                    indexQ2Start = 0;
                    indexQ2End   = 0;
                    lastPoint    = _q2.HullPoints[0];
                }
            }
            else
            {
                if (_q2.FirstPoint.Equals(lastPoint))
                {
                    indexQ2Start = 1;
                }
                else
                {
                    indexQ2Start = 0;
                }
                indexQ2End = _q2.HullPoints.Count - 1;
                lastPoint  = _q2.HullPoints[indexQ2End];
            }

            if (_q3.HullPoints.Count == 1)
            {
                if (_q3.FirstPoint.Equals(lastPoint))
                {
                    indexQ3Start = 1;
                    indexQ3End   = 0;
                }
                else
                {
                    indexQ3Start = 0;
                    indexQ3End   = 0;
                    lastPoint    = _q3.HullPoints[0];
                }
            }
            else
            {
                if (_q3.FirstPoint.Equals(lastPoint))
                {
                    indexQ3Start = 1;
                }
                else
                {
                    indexQ3Start = 0;
                }
                indexQ3End = _q3.HullPoints.Count - 1;
                lastPoint  = _q3.HullPoints[indexQ3End];
            }

            if (_q4.HullPoints.Count == 1)
            {
                if (_q4.FirstPoint.Equals(lastPoint))
                {
                    indexQ4Start = 1;
                    indexQ4End   = 0;
                }
                else
                {
                    indexQ4Start = 0;
                    indexQ4End   = 0;
                }
            }
            else
            {
                if (_q4.FirstPoint.Equals(lastPoint))
                {
                    indexQ4Start = 1;
                }
                else
                {
                    indexQ4Start = 0;
                }

                indexQ4End = _q4.HullPoints.Count - 1;
                if (_q4.HullPoints[indexQ4End].Equals(_q1.HullPoints[0]))
                {
                    indexQ4End--;
                }
            }


            int countOfFinalHullPoint = (indexQ1End - indexQ1Start) +
                                        (indexQ2End - indexQ2Start) +
                                        (indexQ3End - indexQ3Start) +
                                        (indexQ4End - indexQ4Start) + 4;

            if (countOfFinalHullPoint == 1)             // Case where there is only one point or many of only the same point. Auto closed if required.
            {
                return(new T[] { _pointConstructor(_q1.HullPoints[0].X, _q1.HullPoints[0].Y) });
            }

            if (_shouldCloseTheGraph)
            {
                countOfFinalHullPoint++;
            }

            T[] results = new T[countOfFinalHullPoint];

            int resIndex = 0;

            for (int n = indexQ1Start; n <= indexQ1End; n++)
            {
                results[resIndex] = _pointConstructor(_q1.HullPoints[n].X, _q1.HullPoints[n].Y);
                resIndex++;
            }

            for (int n = indexQ2Start; n <= indexQ2End; n++)
            {
                results[resIndex] = _pointConstructor(_q2.HullPoints[n].X, _q2.HullPoints[n].Y);
                resIndex++;
            }

            for (int n = indexQ3Start; n <= indexQ3End; n++)
            {
                results[resIndex] = _pointConstructor(_q3.HullPoints[n].X, _q3.HullPoints[n].Y);
                resIndex++;
            }

            for (int n = indexQ4Start; n <= indexQ4End; n++)
            {
                results[resIndex] = _pointConstructor(_q4.HullPoints[n].X, _q4.HullPoints[n].Y);
                resIndex++;
            }

            if (_shouldCloseTheGraph)
            {
                results[resIndex] = _pointConstructor(_q1.FirstPoint.X, _q1.FirstPoint.Y);
            }

            return(results);
        }