示例#1
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);
        }
示例#2
0
        /// <summary>
        /// Returns bitmask of comparison of values at cell corners with reference value.
        /// Corresponding bit is set to one if value at cell corner is greater than reference value.
        /// a------b
        /// | Cell |
        /// d------c
        /// </summary>
        /// <param name="a">Value at corner (see figure)</param>
        /// <param name="b">Value at corner (see figure)</param>
        /// <param name="c">Value at corner (see figure)</param>
        /// <param name="d">Value at corner (see figure)</param>
        /// <param name="value">Reference value</param>
        /// <returns>Bitmask</returns>
        public CellBitmask GetCellValue(double value)
        {
            CellBitmask n = CellBitmask.None;

            if (leftTop > value)
            {
                n |= CellBitmask.LeftTop;
            }
            if (leftBottom > value)
            {
                n |= CellBitmask.LeftBottom;
            }
            if (rightBottom > value)
            {
                n |= CellBitmask.RightBottom;
            }
            if (rightTop > value)
            {
                n |= CellBitmask.RightTop;
            }

            return(n);
        }
		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
 public static bool IsDiagonal(this CellBitmask bitmask)
 {
     return(bitmask == (CellBitmask.RightBottom | CellBitmask.LeftTop) ||
            bitmask == (CellBitmask.LeftBottom | CellBitmask.RightTop));
 }
        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);
        }
        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));
        }