/// <summary>
        /// Calculates the area above the top limit for two blood sugar points.
        /// </summary>
        /// <param name="glucoseValue1">The first blood sugar glucose value.</param>
        /// <param name="timestamp1">The timestamp of the first blood sugar.</param>
        /// <param name="glucoseValue2">The second blood sugar glucose value.</param>
        /// <param name="timestamp2">The timestamp of the second blood sugar.</param>
        /// <param name="inclusiveTopLimit">The inclusive limit of good blood sugar.</param>
        /// <returns>The area above the top limit (seconds * mmol/L).</returns>
        private static decimal calculateAreaAboveRange(decimal glucoseValue1, DateTime timestamp1, decimal glucoseValue2, DateTime timestamp2, decimal inclusiveTopLimit)
        {
            //Both values are BELOW the limit.
            if (glucoseValue1 <= inclusiveTopLimit && glucoseValue2 <= inclusiveTopLimit)
            {
                return(0);
            }

            //Both values are ABOVE the limit.
            else if (glucoseValue1 > inclusiveTopLimit && glucoseValue2 > inclusiveTopLimit)
            {
                var hoursBetween = calculateTimeDifferenceInHours(timestamp1, timestamp2);
                var minValue     = Math.Min(glucoseValue1, glucoseValue2);
                var area         = (minValue - inclusiveTopLimit) * hoursBetween;

                var maxValue     = Math.Max(glucoseValue1, glucoseValue2);
                var triangleArea = (maxValue - minValue) * hoursBetween / 2;
                area += triangleArea;

                if (area < 0)
                {
                    throw new ConstraintException("The area calculated was a negative value.");
                }
                return(area);
            }

            //One value is above the limit and the other is below.
            else
            {
                //Find the line traversing the blood sugar values.
                var hoursBetween = calculateTimeDifferenceInHours(timestamp1, timestamp2);
                var p1           = new PointF(0, (float)(glucoseValue1));
                var p2           = new PointF((float)hoursBetween, (float)(glucoseValue2));
                var line         = new MathLine(p1, p2);

                //Find where the line crosses the top limit.
                var topLimitLine = new MathLine(0, (float)inclusiveTopLimit);
                var intersection = MathLine.GetIntersectionPoint(line, topLimitLine);

                //Calculate the area above the top limit.
                var highestPoint   = p1.Y > p2.Y ? p1 : p2;
                var triangleBase   = Math.Abs(intersection.X - highestPoint.X);
                var triangleHeight = highestPoint.Y - (float)inclusiveTopLimit;
                var triangleArea   = triangleBase * triangleHeight / 2;

                //Return the area above the top limit.
                if (triangleArea < 0)
                {
                    throw new ConstraintException("The area calculated was a negative value.");
                }
                return(Convert.ToDecimal(triangleArea));
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Gets the point in which two lines intersect.
        /// </summary>
        /// <param name="lineA">The first line.</param>
        /// <param name="lineB">The second line.</param>
        /// <returns>The point in which the two lines intersect.</returns>
        public static PointF GetIntersectionPoint(MathLine lineA, MathLine lineB)
        {
            //Implemented according to:
            //https://en.wikipedia.org/w/index.php?title=Line%E2%80%93line_intersection&oldid=815048738#Given_the_equations_of_the_lines

            if (lineA.Slope == lineB.Slope)
            {
                throw new ConstraintException("The slopes are identical, meaning the lines are parallel and has no intersection point!");
            }

            float x = (lineB.Offset - lineA.Offset) / (lineA.Slope - lineB.Slope); //Will never be division by zero due to the exception above.
            float y = lineA.GetY(x);

            PointF intersection = new PointF(x, y);

            return(intersection);
        }