using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace friction { public class TrendLine { public struct POINT { public float X; public float Y; } private readonly List AxisValues; private int count; private float xAxisValuesSum; private float xxSum; private float xySum; private float yAxisValuesSum; //public TrendLine(IList xAxisValues, IList yAxisValues) //{ // this.xAxisValues = xAxisValues; // this.yAxisValues = yAxisValues; // this.Initialize(); //} public TrendLine(List points) { AxisValues = points; AxisValues.Sort((POINT a, POINT b) => (a.X == b.X) ? 0 : (a.X < b.X) ? -1 : 1); this.Initialize(); } public float Slope { get; private set; } public float Intercept { get; private set; } public float Start { get; private set; } public float End { get; private set; } private void Initialize() { this.count = this.AxisValues.Count; this.yAxisValuesSum = this.AxisValues.Sum(e => e.Y); this.xAxisValuesSum = this.AxisValues.Sum(e => e.X); this.xxSum = 0; this.xySum = 0; for (int i = 0; i < this.count; i++) { this.xySum += (this.AxisValues[i].X * this.AxisValues[i].Y); this.xxSum += (this.AxisValues[i].X * this.AxisValues[i].X); } this.Slope = this.CalculateSlope(); this.Intercept = this.CalculateIntercept(); this.Start = this.CalculateStart(); this.End = this.CalculateEnd(); } private float CalculateSlope() { try { return ((this.count * this.xySum) - (this.xAxisValuesSum * this.yAxisValuesSum)) / ((this.count * this.xxSum) - (this.xAxisValuesSum * this.xAxisValuesSum)); } catch (DivideByZeroException) { return 0; } } private float CalculateIntercept() { return (this.yAxisValuesSum - (this.Slope * this.xAxisValuesSum)) / this.count; } private float CalculateStart() { return (this.Slope * this.AxisValues.First().X) + this.Intercept; } private float CalculateEnd() { return (this.Slope * this.AxisValues.Last().X) + this.Intercept; } public float GetY(float fX) { return (this.Slope * fX) + this.Intercept; } } }