96 lines
3.2 KiB
C#
96 lines
3.2 KiB
C#
/*******************************************************************************
|
|
* Author : Angus Johnson *
|
|
* Version : Clipper2 - ver.1.0.0 *
|
|
* Date : 3 August 2022 *
|
|
* Website : http://www.angusj.com *
|
|
* Copyright : Angus Johnson 2010-2022 *
|
|
* Purpose : Minkowski Sum and Difference *
|
|
* License : http://www.boost.org/LICENSE_1_0.txt *
|
|
*******************************************************************************/
|
|
|
|
#nullable enable
|
|
using System;
|
|
using System.Collections.Generic;
|
|
|
|
namespace Unity.Cinemachine
|
|
{
|
|
using Path64 = List<Point64>;
|
|
using Paths64 = List<List<Point64>>;
|
|
using PathD = List<PointD>;
|
|
using PathsD = List<List<PointD>>;
|
|
class Minkowski
|
|
{
|
|
private static Paths64 MinkowskiInternal(Path64 pattern, Path64 path, bool isSum, bool isClosed)
|
|
{
|
|
int delta = isClosed ? 0 : 1;
|
|
int patLen = pattern.Count, pathLen = path.Count;
|
|
Paths64 tmp = new Paths64(pathLen);
|
|
|
|
foreach (Point64 pathPt in path)
|
|
{
|
|
Path64 path2 = new Path64(patLen);
|
|
if (isSum)
|
|
{
|
|
foreach (Point64 basePt in pattern)
|
|
path2.Add(pathPt + basePt);
|
|
}
|
|
else
|
|
{
|
|
foreach (Point64 basePt in pattern)
|
|
path2.Add(pathPt - basePt);
|
|
}
|
|
tmp.Add(path2);
|
|
}
|
|
|
|
Paths64 result = new Paths64((pathLen - delta) * patLen);
|
|
int g = isClosed ? pathLen - 1 : 0;
|
|
|
|
int h = patLen - 1;
|
|
for (int i = delta; i < pathLen; i++)
|
|
{
|
|
for (int j = 0; j < patLen; j++)
|
|
{
|
|
Path64 quad = new Path64(4)
|
|
{
|
|
tmp[g][h], tmp[i][h], tmp[i][j], tmp[g][j]
|
|
};
|
|
if (!Clipper.IsPositive(quad))
|
|
result.Add(Clipper.ReversePath(quad));
|
|
else
|
|
result.Add(quad);
|
|
h = j;
|
|
}
|
|
g = i;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
public static Paths64 Sum(Path64 pattern, Path64 path, bool isClosed)
|
|
{
|
|
return Clipper.Union(MinkowskiInternal(pattern, path, true, isClosed), FillRule.NonZero);
|
|
}
|
|
|
|
public static PathsD Sum(PathD pattern, PathD path, bool isClosed, int decimalPlaces = 2)
|
|
{
|
|
double scale = Math.Pow(10, decimalPlaces);
|
|
Paths64 tmp = Clipper.Union(MinkowskiInternal(Clipper.ScalePath64(pattern, scale),
|
|
Clipper.ScalePath64(path, scale), true, isClosed), FillRule.NonZero);
|
|
return Clipper.ScalePathsD(tmp, 1 / scale);
|
|
}
|
|
|
|
public static Paths64 Diff(Path64 pattern, Path64 path, bool isClosed)
|
|
{
|
|
return Clipper.Union(MinkowskiInternal(pattern, path, false, isClosed), FillRule.NonZero);
|
|
}
|
|
|
|
public static PathsD Diff(PathD pattern, PathD path, bool isClosed, int decimalPlaces = 2)
|
|
{
|
|
double scale = Math.Pow(10, decimalPlaces);
|
|
Paths64 tmp = Clipper.Union(MinkowskiInternal(Clipper.ScalePath64(pattern, scale),
|
|
Clipper.ScalePath64(path, scale), false, isClosed), FillRule.NonZero);
|
|
return Clipper.ScalePathsD(tmp, 1 / scale);
|
|
}
|
|
|
|
}
|
|
|
|
} // namespace |