Пример #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 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);
        }
Пример #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);
                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 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 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);
        }
Пример #6
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);
        }
Пример #7
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();
			}
		}
Пример #8
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;
		}
Пример #9
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);
		}
Пример #10
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;
		}
Пример #11
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);
        }
Пример #12
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);
		}
Пример #13
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();
			}
		}
Пример #14
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);
		}
        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));
        }