namespace Mapbox.Unity.Location
{
using Mapbox.Utils;
using System;
using UnityEngine;
///
/// Base class for implementing different smoothing strategies
///
public abstract class AngleSmoothingAbstractBase : MonoBehaviour, IAngleSmoothing
{
[SerializeField]
[Tooltip("Number of measurements used for smoothing. Keep that number as low as feasible as collection of measurements depends on update time of location provider (minimum 500ms). eg 6 smoothes over the last 3 seconds.")]
[Range(5, 20)]
public int _measurements = 5;
public AngleSmoothingAbstractBase()
{
_angles = new CircularBuffer(_measurements);
}
///
/// Internal storage for latest 'n' values. Latest value at [0],
///
protected CircularBuffer _angles;
///
/// For conversions from degrees to radians needed for Math functions.
///
protected readonly double DEG2RAD = Math.PI / 180.0d;
///
/// For conversions from radians to degrees.
///
protected readonly double RAD2DEG = 180.0d / Math.PI;
///
/// Add angle to list of angles used for calculation.
///
///
public void Add(double angle)
{
// safe measures to stay within [0..<360]
angle = angle < 0 ? angle + 360 : angle >= 360 ? angle - 360 : angle;
_angles.Add(angle);
}
///
/// Calculate smoothed angle from previously added angles.
///
/// Smoothed angle
public abstract double Calculate();
[System.Diagnostics.Conditional("UNITY_EDITOR")]
protected void debugLogAngle(double raw, double smoothed)
{
double debugAngle = Math.Atan2(Math.Sin(smoothed * DEG2RAD), Math.Cos(smoothed * DEG2RAD)) * RAD2DEG;
debugAngle = debugAngle < 0 ? debugAngle + 360 : debugAngle >= 360 ? debugAngle - 360 : debugAngle;
Debug.Log(string.Format("{0:0.000} => {1:0.000}", raw, smoothed));
}
}
}