예제 #1
0
        private void TrackLineNonRecursive(Edge inEdge, double value, int x, int y)
        {
            int s = x, t = y;

            ValuesInCell vc = new ValuesInCell(
                values[x, y],
                values[x + 1, y],
                values[x + 1, y + 1],
                values[x, y + 1]);

            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, currentRatio, value);

            MakeEdgePassed(inEdge, x, y);

            double x2, y2;

            do
            {
                inEdge = TrackLine(inEdge, value, ref s, ref t, out x2, out y2);
            } while (s != -1);
        }
예제 #2
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);
                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(Properties.Resources.IsolinesDataIsUndetailized);
        }
예제 #3
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();
            }
        }
예제 #4
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 = new ValuesInCell(
                values[x, y],
                values[x + 1, y],
                values[x + 1, y + 1],
                values[x, y + 1]);

            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);

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

            newX = point.X;
            newY = point.Y;
            segments.AddPoint(point);

            // 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
                x = y = -1;
                return(Edge.Bottom);
            }

            // 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();
            }
        }
예제 #5
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(Properties.Resources.IsolinesValueIsOutOfCell);
            }

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

            if (dict.ContainsKey((int)cellVal))
            {
                return(dict[(int)cellVal]);
            }
            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 * rt;
                }
                else if (value == rt)
                {
                    value = near_one * rt + near_zero * lt;
                }
                else
                {
                    throw new IsolineGenerationException(Properties.Resources.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
                {
                    throw new IsolineGenerationException(Properties.Resources.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
                {
                    throw new IsolineGenerationException(Properties.Resources.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
                {
                    throw new IsolineGenerationException(Properties.Resources.IsolinesUnsupportedCase);
                }
                break;
            }

            return(GetOutEdge(inEdge, cv, rect, value));
        }