/// <summary>
        /// Calculator delegate for input from mouse input
        /// Calculates the path point properties based on pointer input.
        /// </summary>
        /// <param name="previous"></param>
        /// <param name="current"></param>
        /// <param name="next"></param>
        /// <returns>PathPoint with calculated properties</returns>
        protected PathPoint CalculatorForMouseAndTouch(PointerData previous, PointerData current, PointerData next)
        {
            var size = current.ComputeValueBasedOnSpeed(previous, next, SizeConfig.minValue, SizeConfig.maxValue, SizeConfig.initValue, SizeConfig.finalValue, SizeConfig.minSpeed, SizeConfig.maxSpeed, SizeConfig.remap);

            if (size.HasValue)
            {
                PreviousSize = size.Value;
            }
            else
            {
                size = PreviousSize;
            }

            var alpha = current.ComputeValueBasedOnSpeed(previous, next, AlphaConfig.minValue, AlphaConfig.maxValue, AlphaConfig.initValue, AlphaConfig.finalValue, AlphaConfig.minSpeed, AlphaConfig.maxSpeed, AlphaConfig.remap);

            if (alpha.HasValue)
            {
                PreviousAlpha = alpha.Value;
            }
            else
            {
                alpha = PreviousAlpha;
            }
            PathPoint pp = new PathPoint(current.X, current.Y)
            {
                Size  = size,
                Alpha = alpha
            };

            return(pp);
        }
        /// <summary>
        /// Calculator delegate for input from a stylus (pen)
        /// Calculates the path point properties based on pointer input.
        /// </summary>
        /// <param name="previous"></param>
        /// <param name="current"></param>
        /// <param name="next"></param>
        /// <returns>PathPoint with calculated properties</returns>
        protected override PathPoint CalculatorForStylus(PointerData previous, PointerData current, PointerData next)
        {
            var size = (!current.Force.HasValue)
                ? current.ComputeValueBasedOnSpeed(previous, next, 30f, 80f, null, null, 0f, 3500f, v => (float)Math.Pow(v, 1.17f))
                : ComputeValueBasedOnPressure(current, 30f, 80f, 0.0f, 1.0f, false, v => (float)Math.Pow(v, 1.17));

            if (!size.HasValue)
            {
                size = PreviousSize;
            }
            else
            {
                PreviousSize = size.Value;
            }

            // Change the intensity of alpha value by pressure or speed
            var alpha = (!current.Force.HasValue)
                ? current.ComputeValueBasedOnSpeed(previous, next, MinAlpha, MaxAlpha, null, null, 0f, 3500f, v => (float)Math.Pow(v, 1.17))
                : ComputeValueBasedOnPressure(current, MinAlpha, MaxAlpha, 0.0f, 1.0f, false, v => (float)Math.Pow(v, 1.17));

            if (!alpha.HasValue)
            {
                alpha = PreviousAlpha;
            }
            else
            {
                PreviousAlpha = alpha.Value;
            }
            var cosAltitudeAngle = (float)Math.Cos(current.AltitudeAngle.Value);
            var sinAzimuthAngle  = (float)Math.Sin(current.AzimuthAngle.Value);
            var cosAzimuthAngle  = (float)Math.Cos(current.AzimuthAngle.Value);
            // calculate the offset of the pencil tip due to tilted position
            var x       = sinAzimuthAngle * cosAltitudeAngle;
            var y       = cosAltitudeAngle * cosAzimuthAngle;
            var offsetY = 5 * -x;
            var offsetX = 5 * -y;

            var       rotation = current.ComputeNearestAzimuthAngle(previous);
            PathPoint pp       = new PathPoint(current.X, current.Y)
            {
                Size     = size,
                Alpha    = alpha,
                Rotation = rotation,
                OffsetX  = offsetX,
                OffsetY  = offsetY
            };

            return(pp);
        }
        /// <summary>
        /// Calculator delegate for input from a stylus (pen)
        /// Calculates the path point properties based on pointer input.
        /// </summary>
        /// <param name="previous"></param>
        /// <param name="current"></param>
        /// <param name="next"></param>
        /// <returns>PathPoint with calculated properties</returns>
        protected override PathPoint CalculatorForStylus(PointerData previous, PointerData current, PointerData next)
        {
            // calculate the offset of the pencil tip due to tilted position
            var cosAltitudeAngle = (float)Math.Cos(current.AltitudeAngle.Value);
            var sinAzimuthAngle  = (float)Math.Sin(current.AzimuthAngle.Value);
            var cosAzimuthAngle  = (float)Math.Cos(current.AzimuthAngle.Value);
            var x       = sinAzimuthAngle * cosAltitudeAngle;
            var y       = cosAltitudeAngle * cosAzimuthAngle;
            var offsetY = 5f * -x;
            var offsetX = 5f * -y;
            // compute the rotation
            var rotation = current.ComputeNearestAzimuthAngle(previous);
            // Normalize the tilt be minimum seen altitude angle and the maximum with the pen straight up
            const float piBy2     = (float)(Math.PI / 2);
            var         tiltScale = Math.Min(1f, (piBy2 - current.AltitudeAngle.Value) / (piBy2 - MinAltitudeAngle));


            var size = Math.Max(MinSize, MinSize + (MaxSize - MinSize) * tiltScale);

            //var rotation = current.ComputeNearestAzimuthAngle(previous);
            // Change the intensity of alpha value by pressure of speed
            var alpha = (!current.Force.HasValue)
                ? current.ComputeValueBasedOnSpeed(previous, next, MinAlpha, MaxAlpha, null, null, 0f, 3500f, v => 1 - v)
                : ComputeValueBasedOnPressure(current, 0.1f, 0.7f, 0.0f, 1.0f);

            if (!alpha.HasValue)
            {
                alpha = PreviousAlpha;
            }
            else
            {
                PreviousAlpha = alpha.Value;
            }
            PathPoint pp = new PathPoint(current.X, current.Y)
            {
                Size     = size,
                Alpha    = alpha,
                Rotation = rotation,
                OffsetX  = offsetX,
                OffsetY  = offsetY
            };

            return(pp);
        }
        /// <summary>
        /// Calculator delegate for input from a stylus (pen)
        /// Calculates the path point properties based on pointer input.
        /// </summary>
        /// <param name="previous"></param>
        /// <param name="current"></param>
        /// <param name="next"></param>
        /// <returns>PathPoint with calculated properties</returns>
        private PathPoint CalculatorForStylus(PointerData previous, PointerData current, PointerData next)
        {
            float?size;

            if (!current.Force.HasValue)
            {
                size = current.ComputeValueBasedOnSpeed(previous, next, 1.5f, 10.2f, null, null, 0, 3500, v => (float)Math.Pow(v, 1.17f));
            }
            else
            {
                size = ComputeValueBasedOnPressure(current, 1.5f, 10.2f, 0, 1, false, v => (float)Math.Pow(v, 1.17f));
            }
            if (size.HasValue)
            {
                PreviousSize = size.Value;
            }
            else
            {
                size = PreviousSize;
            }


            var cosAltitudeAngle = (float)Math.Abs(Math.Cos(current.AltitudeAngle.Value));

            var tiltScale = 1.5f * cosAltitudeAngle;
            var scaleX    = 1.0f + tiltScale;
            var offsetX   = size * tiltScale;
            var rotation  = current.ComputeNearestAzimuthAngle(previous);

            PathPoint pp = new PathPoint(current.X, current.Y)
            {
                Size     = size,
                Rotation = rotation,
                ScaleX   = scaleX,
                OffsetX  = offsetX
            };

            return(pp);
        }