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