JD2022-TU1/main/tools/apps/PleoLab/Curve.cs

156 lines
4.1 KiB
C#

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
namespace PleoLab
{
public class Curve
{
public List<Point> points;
public Curve()
{
points = new List<Point>();
}
public Curve(Curve curve)
{
points = new List<Point>(curve.points);
}
public Curve(List<Vector2> _normalizedPoints, int _screenWidth, int _screenHeight)
{
points = new List<Point>();
foreach (Vector2 normalizedPoint in _normalizedPoints)
{
Point screenPoint = new Point(
(int)(normalizedPoint.x * _screenWidth),
(int)(_screenHeight - normalizedPoint.y * _screenHeight));
points.Add(screenPoint);
}
}
public int Count
{
get
{
return points.Count;
}
}
public Point[] ToArray()
{
return points.ToArray();
}
public Point this[int key]
{
get
{
return points[key];
}
set
{
points[key] = value;
}
}
public void RemoveAt(int index)
{
points.RemoveAt(index);
}
public void Add(Point point)
{
points.Add(point);
}
public void Insert(int index, Point point)
{
points.Insert(index, point);
}
public Point First()
{
return points.First();
}
public Point Last()
{
return points.Last();
}
public void Clear()
{
points.Clear();
}
public int FindClosestPointIndex(Point _point)
{
int closestIndex = Int32.MaxValue;
double minDistance = Int32.MaxValue;
for (int i = 0; i < points.Count; ++i)
{
double distance = EditorUtils.GetDistance(points[i], _point);
if (distance < minDistance)
{
closestIndex = i;
minDistance = distance;
}
}
return closestIndex;
}
public List<Vector2> GetNormalizedCurve(int _screenWidth, int _screenHeight)
{
List<Vector2> normalizedPoints = new List<Vector2>();
foreach (Point screenPoint in points)
{
Vector2 normalizedPoint = new Vector2(
(double)screenPoint.X / (double)_screenWidth,
((double)_screenHeight - (double)(screenPoint.Y)) / (double)_screenHeight);
normalizedPoints.Add(normalizedPoint);
}
return normalizedPoints;
}
public void Sort()
{
points = points.OrderBy(p => p.X).ToList();
}
public void AddRange(IEnumerable<Point> _points)
{
points.AddRange(_points);
}
public List<Point> FindAll(Predicate<Point> _predicate)
{
List<Point> pointsFound = points.FindAll(_predicate);
return pointsFound;
}
/// <summary>
/// Prevents list of points from containing points with the same X value
/// Finds points with the same X value and adds, to each duplicate, one to their X value for each duplicate
/// </summary>
public void PreventXDuplicates()
{
List<Point> pointsCopy = new List<Point>(points);
IEnumerable<IGrouping<int,Point>> groupsByX = pointsCopy.GroupBy(point => point.X);
points.Clear();
foreach (IGrouping<int, Point> grp in groupsByX)
{
IEnumerable<Point> groupedPoints = grp.AsEnumerable();
for (int i = 0; i < groupedPoints.Count(); i++)
{
points.Add(new Point(groupedPoints.ElementAt(i).X + i,
groupedPoints.ElementAt(i).Y));
}
}
}
}
}