/Main/src/DynamicDataDisplay/Charts/Isolines/CellInfo.cs
C# | 399 lines | 294 code | 49 blank | 56 comment | 39 complexity | 56df94dfa6289290548c06decfd26880 MD5 | raw file
Possible License(s): CC-BY-SA-3.0
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Diagnostics;
- using Microsoft.Research.DynamicDataDisplay.Common.Auxiliary;
- using System.Windows;
-
- namespace Microsoft.Research.DynamicDataDisplay.Charts.Isolines
- {
- /// <summary>
- /// Isoline's grid cell
- /// </summary>
- internal interface ICell
- {
- Vector LeftTop { get; }
- Vector LeftBottom { get; }
- Vector RightTop { get; }
- Vector RightBottom { get; }
- }
-
- internal sealed class IrregularCell : ICell
- {
- public IrregularCell(Vector leftBottom, Vector rightBottom, Vector rightTop, Vector leftTop)
- {
- this.leftBottom = leftBottom;
- this.rightBottom = rightBottom;
- this.rightTop = rightTop;
- this.leftTop = leftTop;
- }
-
- public IrregularCell(Point lb, Point rb, Point rt, Point lt)
- {
- leftTop = lt.ToVector();
- leftBottom = lb.ToVector();
- rightTop = rt.ToVector();
- rightBottom = rb.ToVector();
- }
-
- #region ICell Members
-
- private readonly Vector leftTop;
- public Vector LeftTop
- {
- get { return leftTop; }
- }
-
- private readonly Vector leftBottom;
- public Vector LeftBottom
- {
- get { return leftBottom; }
- }
-
- private readonly Vector rightTop;
- public Vector RightTop
- {
- get { return rightTop; }
- }
-
- private readonly Vector rightBottom;
- public Vector RightBottom
- {
- get { return rightBottom; }
- }
-
- #endregion
-
- #region Sides
- public Vector LeftSide
- {
- get { return (leftBottom + leftTop) / 2; }
- }
-
- public Vector RightSide
- {
- get { return (rightBottom + rightTop) / 2; }
- }
- public Vector TopSide
- {
- get { return (leftTop + rightTop) / 2; }
- }
- public Vector BottomSide
- {
- get { return (leftBottom + rightBottom) / 2; }
- }
- #endregion
-
- public Point Center
- {
- get { return ((LeftSide + RightSide) / 2).ToPoint(); }
- }
-
- public IrregularCell GetSubRect(SubCell sub)
- {
- switch (sub)
- {
- case SubCell.LeftBottom:
- return new IrregularCell(LeftBottom, BottomSide, Center.ToVector(), LeftSide);
- case SubCell.LeftTop:
- return new IrregularCell(LeftSide, Center.ToVector(), TopSide, LeftTop);
- case SubCell.RightBottom:
- return new IrregularCell(BottomSide, RightBottom, RightSide, Center.ToVector());
- case SubCell.RightTop:
- default:
- return new IrregularCell(Center.ToVector(), RightSide, RightTop, TopSide);
- }
- }
- }
-
- internal enum SubCell
- {
- LeftBottom = 0,
- LeftTop = 1,
- RightBottom = 2,
- RightTop = 3
- }
-
- internal class ValuesInCell
- {
- double min = Double.MaxValue, max = Double.MinValue;
-
- /// <summary>Initializes values in four corners of cell</summary>
- /// <param name="leftBottom"></param>
- /// <param name="rightBottom"></param>
- /// <param name="rightTop"></param>
- /// <param name="leftTop"></param>
- /// <remarks>Some or all values can be NaN. That means that value is not specified (misssing)</remarks>
- public ValuesInCell(double leftBottom, double rightBottom, double rightTop, double leftTop)
- {
- this.leftTop = leftTop;
- this.leftBottom = leftBottom;
- this.rightTop = rightTop;
- this.rightBottom = rightBottom;
-
- // Find max and min values (with respect to possible NaN values)
- if (!Double.IsNaN(leftTop))
- {
- if (min > leftTop)
- min = leftTop;
- if (max < leftTop)
- max = leftTop;
- }
-
- if (!Double.IsNaN(leftBottom))
- {
- if (min > leftBottom)
- min = leftBottom;
- if (max < leftBottom)
- max = leftBottom;
- }
-
- if (!Double.IsNaN(rightTop))
- {
- if (min > rightTop)
- min = rightTop;
- if (max < rightTop)
- max = rightTop;
- }
-
- if (!Double.IsNaN(rightBottom))
- {
- if (min > rightBottom)
- min = rightBottom;
- if (max < rightBottom)
- max = rightBottom;
- }
-
- left = (leftTop + leftBottom) / 2;
- bottom = (leftBottom + rightBottom) / 2;
- right = (rightTop + rightBottom) / 2;
- top = (rightTop + leftTop) / 2;
- }
-
- public ValuesInCell(double leftBottom, double rightBottom, double rightTop, double leftTop, double missingValue)
- {
- DebugVerify.IsNotNaN(leftBottom);
- DebugVerify.IsNotNaN(rightBottom);
- DebugVerify.IsNotNaN(rightTop);
- DebugVerify.IsNotNaN(leftTop);
-
- // Copy values and find min and max with respect to possible missing values
- if (leftTop != missingValue)
- {
- this.leftTop = leftTop;
- if (min > leftTop)
- min = leftTop;
- if (max < leftTop)
- max = leftTop;
- }
- else
- this.leftTop = Double.NaN;
-
- if (leftBottom != missingValue)
- {
- this.leftBottom = leftBottom;
- if (min > leftBottom)
- min = leftBottom;
- if (max < leftBottom)
- max = leftBottom;
- }
- else
- this.leftBottom = Double.NaN;
-
- if (rightTop != missingValue)
- {
- this.rightTop = rightTop;
- if (min > rightTop)
- min = rightTop;
- if (max < rightTop)
- max = rightTop;
- }
- else
- this.rightTop = Double.NaN;
-
- if (rightBottom != missingValue)
- {
- this.rightBottom = rightBottom;
- if (min > rightBottom)
- min = rightBottom;
- if (max < rightBottom)
- max = rightBottom;
- }
- else
- this.rightBottom = Double.NaN;
-
- left = (this.leftTop + this.leftBottom) / 2;
- bottom = (this.leftBottom + this.rightBottom) / 2;
- right = (this.rightTop + this.rightBottom) / 2;
- top = (this.rightTop + this.leftTop) / 2;
-
-
- /*
- if (leftTop != missingValue && )
- {
- if (leftBottom != missingValue)
- left = (leftTop + leftBottom) / 2;
- else
- left = Double.NaN;
-
- if (rightTop != missingValue)
- top = (leftTop + rightTop) / 2;
- else
- top = Double.NaN;
- }
-
- if (rightBottom != missingValue)
- {
- if (leftBottom != missingValue)
- bottom = (leftBottom + rightBottom) / 2;
- else
- bottom = Double.NaN;
-
- if (rightTop != missingValue)
- right = (rightTop + rightBottom) / 2;
- else
- right = Double.NaN;
- }*/
- }
-
-
- /*internal bool ValueBelongTo(double value)
- {
- IEnumerable<double> values = new double[] { leftTop, leftBottom, rightTop, rightBottom };
-
- return !(values.All(v => v > value) || values.All(v => v < value));
- }*/
-
- internal bool ValueBelongTo(double value)
- {
- return (min <= value && value <= max);
- }
-
- #region Edges
- [DebuggerBrowsable(DebuggerBrowsableState.Never)]
- private readonly double leftTop;
- public double LeftTop { get { return leftTop; } }
-
- [DebuggerBrowsable(DebuggerBrowsableState.Never)]
- private readonly double leftBottom;
- public double LeftBottom { get { return leftBottom; } }
-
- [DebuggerBrowsable(DebuggerBrowsableState.Never)]
- private readonly double rightTop;
- public double RightTop
- {
- get { return rightTop; }
- }
-
- [DebuggerBrowsable(DebuggerBrowsableState.Never)]
- private readonly double rightBottom;
- public double RightBottom
- {
- get { return rightBottom; }
- }
- #endregion
-
- #region Sides & center
- [DebuggerBrowsable(DebuggerBrowsableState.Never)]
- private readonly double left;
- public double Left
- {
- get { return left; }
- }
-
- [DebuggerBrowsable(DebuggerBrowsableState.Never)]
- private readonly double right;
- public double Right
- {
- get { return right; }
- }
-
- [DebuggerBrowsable(DebuggerBrowsableState.Never)]
- private readonly double top;
- public double Top
- {
- get { return top; }
- }
-
- [DebuggerBrowsable(DebuggerBrowsableState.Never)]
- private readonly double bottom;
- public double Bottom
- {
- get { return bottom; }
- }
-
- public double Center
- {
- get { return (Left + Right) * 0.5; }
- }
- #endregion
-
- #region SubCells
- public ValuesInCell LeftTopCell
- {
- get { return new ValuesInCell(Left, Center, Top, LeftTop); }
- }
-
- public ValuesInCell RightTopCell
- {
- get { return new ValuesInCell(Center, Right, RightTop, Top); }
- }
-
- public ValuesInCell RightBottomCell
- {
- get { return new ValuesInCell(Bottom, RightBottom, Right, Center); }
- }
-
- public ValuesInCell LeftBottomCell
- {
- get { return new ValuesInCell(LeftBottom, Bottom, Center, Left); }
- }
-
- public ValuesInCell GetSubCell(SubCell subCell)
- {
- switch (subCell)
- {
- case SubCell.LeftBottom:
- return LeftBottomCell;
- case SubCell.LeftTop:
- return LeftTopCell;
- case SubCell.RightBottom:
- return RightBottomCell;
- case SubCell.RightTop:
- default:
- return RightTopCell;
- }
- }
-
- #endregion
-
- /// <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 (!Double.IsNaN(leftTop) && leftTop > value)
- n |= CellBitmask.LeftTop;
- if (!Double.IsNaN(leftBottom) && leftBottom > value)
- n |= CellBitmask.LeftBottom;
- if (!Double.IsNaN(rightBottom) && rightBottom > value)
- n |= CellBitmask.RightBottom;
- if (!Double.IsNaN(rightTop) && rightTop > value)
- n |= CellBitmask.RightTop;
-
- return n;
- }
- }
- }