Пример #1
0
        private Point GetPointXY(Edge edge, double value, ValuesInCell vc, IrregularCell rect)
        {
            double lt = vc.LeftTop;
            double lb = vc.LeftBottom;
            double rb = vc.RightBottom;
            double rt = vc.RightTop;

            switch (edge)
            {
            case Edge.Left:
                return(GetPoint(value, lb, lt, rect.LeftBottom, rect.LeftTop));

            case Edge.Top:
                return(GetPoint(value, lt, rt, rect.LeftTop, rect.RightTop));

            case Edge.Right:
                return(GetPoint(value, rb, rt, rect.RightBottom, rect.RightTop));

            case Edge.Bottom:
                return(GetPoint(value, lb, rb, rect.LeftBottom, rect.RightBottom));

            default:
                throw new InvalidOperationException();
            }
        }
Пример #2
0
        private static SubCell GetSubCell(Edge inEdge, double value, ValuesInCell vc)
        {
            double lb = vc.LeftBottom;
            double rb = vc.RightBottom;
            double rt = vc.RightTop;
            double lt = vc.LeftTop;

            SubCell res = SubCell.LeftBottom;

            switch (inEdge)
            {
            case Edge.Left:
                res = (Math.Abs(value - lb) < Math.Abs(value - lt)) ? SubCell.LeftBottom : SubCell.LeftTop;
                break;

            case Edge.Top:
                res = (Math.Abs(value - lt) < Math.Abs(value - rt)) ? SubCell.LeftTop : SubCell.RightTop;
                break;

            case Edge.Right:
                res = (Math.Abs(value - rb) < Math.Abs(value - rt)) ? SubCell.RightBottom : SubCell.RightTop;
                break;

            case Edge.Bottom:
            default:
                res = (Math.Abs(value - lb) < Math.Abs(value - rb)) ? SubCell.LeftBottom : SubCell.RightBottom;
                break;
            }

            ValuesInCell subValues   = vc.GetSubCell(res);
            bool         valueInside = subValues.ValueBelongTo(value);

            if (!valueInside)
            {
                throw new IsolineGenerationException(Strings.Exceptions.IsolinesDataIsUndetailized);
            }

            return(res);
        }
Пример #3
0
        private Edge GetOutForOpposite(Edge inEdge, CellBitmask cellVal, double value, ValuesInCell cellValues, IrregularCell rect)
        {
            Edge outEdge;

            SubCell subCell = GetSubCell(inEdge, value, cellValues);

            int iters = 1000;             // max number of iterations

            do
            {
                ValuesInCell  subValues = cellValues.GetSubCell(subCell);
                IrregularCell subRect   = rect.GetSubRect(subCell);
                outEdge = GetOutEdge(inEdge, subValues, subRect, value);
                if (outEdge == Edge.None)
                {
                    return(Edge.None);
                }
                bool isAppropriate = subCell.IsAppropriate(outEdge);
                if (isAppropriate)
                {
                    ValuesInCell sValues = subValues.GetSubCell(subCell);

                    Point point = GetPointXY(outEdge, value, subValues, subRect);
                    segments.AddPoint(point);
                    return(outEdge);
                }
                else
                {
                    subCell = GetAdjacentEdge(subCell, outEdge);
                }

                byte e = (byte)outEdge;
                inEdge = (Edge)((e > 2) ? (e >> 2) : (e << 2));
                iters--;
            } while (iters >= 0);

            throw new IsolineGenerationException(Strings.Exceptions.IsolinesDataIsUndetailized);
        }
Пример #4
0
        private void TrackLineNonRecursive(Edge inEdge, double value, int x, int y)
        {
            int s = x, t = y;

            ValuesInCell vc = (missingValue.IsNaN()) ?
                              (new ValuesInCell(values[x, y],
                                                values[x + 1, y],
                                                values[x + 1, y + 1],
                                                values[x, y + 1])) :
                              (new ValuesInCell(values[x, y],
                                                values[x + 1, y],
                                                values[x + 1, y + 1],
                                                values[x, y + 1],
                                                missingValue));

            IrregularCell rect = new IrregularCell(
                grid[x, y],
                grid[x + 1, y],
                grid[x + 1, y + 1],
                grid[x, y + 1]);

            Point point = GetPointXY(inEdge, value, vc, rect);

            segments.StartLine(point, (value - minMax.Min) / (minMax.Max - minMax.Min), value);

            MakeEdgePassed(inEdge, x, y);

            //processed[x, y] = true;

            double x2, y2;

            do
            {
                inEdge = TrackLine(inEdge, value, ref s, ref t, out x2, out y2);
            } while (inEdge != Edge.None);
        }
Пример #5
0
        private Edge TrackLine(Edge inEdge, double value, ref int x, ref int y, out double newX, out double newY)
        {
            // Getting output edge
            ValuesInCell vc = (missingValue.IsNaN()) ?
                              (new ValuesInCell(values[x, y],
                                                values[x + 1, y],
                                                values[x + 1, y + 1],
                                                values[x, y + 1])) :
                              (new ValuesInCell(values[x, y],
                                                values[x + 1, y],
                                                values[x + 1, y + 1],
                                                values[x, y + 1],
                                                missingValue));

            IrregularCell rect = new IrregularCell(
                grid[x, y],
                grid[x + 1, y],
                grid[x + 1, y + 1],
                grid[x, y + 1]);

            Edge outEdge = GetOutEdge(inEdge, vc, rect, value);

            if (outEdge == Edge.None)
            {
                newX = newY = -1;                 // Impossible cell indices
                return(Edge.None);
            }

            // Drawing new segment
            Point point = GetPointXY(outEdge, value, vc, rect);

            newX = point.X;
            newY = point.Y;
            segments.AddPoint(point);
            processed[x, y] = true;

            // Whether out-edge already was passed?
            if (IsPassed(outEdge, x, y, edges))             // line is closed
            {
                //MakeEdgePassed(outEdge, x, y); // boundaries should be marked as passed too
                return(Edge.None);
            }

            // Make this edge passed
            MakeEdgePassed(outEdge, x, y);

            // Getting next cell's indices
            switch (outEdge)
            {
            case Edge.Left:
                x--;
                return(Edge.Right);

            case Edge.Top:
                y++;
                return(Edge.Bottom);

            case Edge.Right:
                x++;
                return(Edge.Left);

            case Edge.Bottom:
                y--;
                return(Edge.Top);

            default:
                throw new InvalidOperationException();
            }
        }
Пример #6
0
        private Edge GetOutEdge(Edge inEdge, ValuesInCell cv, IrregularCell rect, double value)
        {
            // value smaller than all values in corners or
            // value greater than all values in corners
            if (!cv.ValueBelongTo(value))
            {
                throw new IsolineGenerationException(Strings.Exceptions.IsolinesValueIsOutOfCell);
            }

            CellBitmask cellVal = cv.GetCellValue(value);
            var         dict    = dictChooser[(int)inEdge];

            if (dict.ContainsKey((int)cellVal))
            {
                Edge result = dict[(int)cellVal];
                switch (result)
                {
                case Edge.Left:
                    if (cv.LeftTop.IsNaN() || cv.LeftBottom.IsNaN())
                    {
                        result = Edge.None;
                    }
                    break;

                case Edge.Right:
                    if (cv.RightTop.IsNaN() || cv.RightBottom.IsNaN())
                    {
                        result = Edge.None;
                    }
                    break;

                case Edge.Top:
                    if (cv.RightTop.IsNaN() || cv.LeftTop.IsNaN())
                    {
                        result = Edge.None;
                    }
                    break;

                case Edge.Bottom:
                    if (cv.LeftBottom.IsNaN() || cv.RightBottom.IsNaN())
                    {
                        result = Edge.None;
                    }
                    break;
                }
                return(result);
            }
            else if (cellVal.IsDiagonal())
            {
                return(GetOutForOpposite(inEdge, cellVal, value, cv, rect));
            }

            const double near_zero = 0.0001;
            const double near_one  = 1 - near_zero;

            double lt = cv.LeftTop;
            double rt = cv.RightTop;
            double rb = cv.RightBottom;
            double lb = cv.LeftBottom;

            switch (inEdge)
            {
            case Edge.Left:
                if (value == lt)
                {
                    value = near_one * lt + near_zero * lb;
                }
                else if (value == lb)
                {
                    value = near_one * lb + near_zero * lt;
                }
                else
                {
                    return(Edge.None);
                }
                // Now this is possible because of missing value
                //throw new IsolineGenerationException(Strings.Exceptions.IsolinesUnsupportedCase);
                break;

            case Edge.Top:
                if (value == rt)
                {
                    value = near_one * rt + near_zero * lt;
                }
                else if (value == lt)
                {
                    value = near_one * lt + near_zero * rt;
                }
                else
                {
                    return(Edge.None);
                }
                // Now this is possibe because of missing value
                //throw new IsolineGenerationException(Strings.Exceptions.IsolinesUnsupportedCase);
                break;

            case Edge.Right:
                if (value == rb)
                {
                    value = near_one * rb + near_zero * rt;
                }
                else if (value == rt)
                {
                    value = near_one * rt + near_zero * rb;
                }
                else
                {
                    return(Edge.None);
                }
                // Now this is possibe because of missing value
                //throw new IsolineGenerationException(Strings.Exceptions.IsolinesUnsupportedCase);
                break;

            case Edge.Bottom:
                if (value == rb)
                {
                    value = near_one * rb + near_zero * lb;
                }
                else if (value == lb)
                {
                    value = near_one * lb + near_zero * rb;
                }
                else
                {
                    return(Edge.None);
                }
                // Now this is possibe because of missing value
                //throw new IsolineGenerationException(Strings.Exceptions.IsolinesUnsupportedCase);
                break;
            }

            // Recursion?
            //return GetOutEdge(inEdge, cv, rect, value);

            return(Edge.None);
        }