156 lines
4.1 KiB
C#
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));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|