inz-00/Assets/Scripts/Common/PointUtils.cs
2019-11-17 16:23:29 +01:00

81 lines
2.3 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
namespace Assets.Common
{
public static class PointUtils
{
public static Point Mean(IEnumerable<Point> points)
{
var result = new Point(0, 0);
var i = 0;
foreach (var point in points)
{
result.x = (result.x * i + point.x) / (i + 1);
result.y = (result.y * i + point.y) / (i + 1);
i++;
}
return result;
}
public static IEnumerable<Point> CalculateNormals(IEnumerable<Point> points)
{
var pairs = points.RotateRight().Zip(points, (a, b) => (a, b));
var thirds = pairs.Zip(points.RotateLeft(), (pair, c) => (pair.a, pair.b, c));
return thirds.Select(third =>
{
var left = (third.a - third.b).Direction;
var right = (third.c - third.b).Direction;
return ((left + right) / 2).Direction * (IsClockwise(third.a, third.b, third.c) ? -1 : 1);
});
}
public static double AngleBetween(Point center, Point a, Point b)
{
a = a - center;
b = b - center;
var dot = a.x * b.x + a.y * b.y;
var det = a.x * b.y - a.y * b.x;
var angle = Math.Atan2(det, dot);
return angle > 0 ? angle : 2*Math.PI + angle;
}
public static bool IsClockwise(Point center, Point a, Point b)
{
var xa = a.x - center.x;
var xb = b.x - center.x;
var ya = a.y - center.y;
var yb = b.y - center.y;
return xa * yb - xb * ya < 0;
}
public static bool IsPointInside(Point point, Point[] polygon)
{
var j = polygon.Length - 1;
var inside = false;
for (int i = 0; i < polygon.Length; j = i++)
{
var pi = polygon[i];
var pj = polygon[j];
if (((pi.y <= point.y && point.y < pj.y) || (pj.y <= point.y && point.y < pi.y)) &&
(point.x < (pj.x - pi.x) * (point.y - pi.y) / (pj.y - pi.y) + pi.x))
inside = !inside;
}
return inside;
}
}
}