Clipper.Minkowski.cs 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. 
  2. #nullable enable
  3. using System;
  4. namespace Clipper2Lib
  5. {
  6. public class Minkowski
  7. {
  8. private static Paths64 MinkowskiInternal(Path64 pattern, Path64 path, bool isSum, bool isClosed)
  9. {
  10. int delta = isClosed ? 0 : 1;
  11. int patLen = pattern.Count, pathLen = path.Count;
  12. Paths64 tmp = new Paths64(pathLen);
  13. foreach (Point64 pathPt in path)
  14. {
  15. Path64 path2 = new Path64(patLen);
  16. if (isSum)
  17. {
  18. foreach (Point64 basePt in pattern)
  19. {
  20. path2.Add(pathPt + basePt);
  21. }
  22. }
  23. else
  24. {
  25. foreach (Point64 basePt in pattern)
  26. {
  27. path2.Add(pathPt - basePt);
  28. }
  29. }
  30. tmp.Add(path2);
  31. }
  32. Paths64 result = new Paths64((pathLen - delta) * patLen);
  33. int g = isClosed ? pathLen - 1 : 0;
  34. int h = patLen - 1;
  35. for (int i = delta; i < pathLen; i++)
  36. {
  37. for (int j = 0; j < patLen; j++)
  38. {
  39. Path64 quad = new Path64(4)
  40. {
  41. tmp[g][h], tmp[i][h], tmp[i][j], tmp[g][j]
  42. };
  43. if (!Clipper.IsPositive(quad))
  44. {
  45. result.Add(Clipper.ReversePath(quad));
  46. }
  47. else
  48. {
  49. result.Add(quad);
  50. }
  51. h = j;
  52. }
  53. g = i;
  54. }
  55. return result;
  56. }
  57. public static Paths64 Sum(Path64 pattern, Path64 path, bool isClosed)
  58. {
  59. return Clipper.Union(MinkowskiInternal(pattern, path, true, isClosed), FillRule.NonZero);
  60. }
  61. public static PathsD Sum(PathD pattern, PathD path, bool isClosed, int decimalPlaces = 2)
  62. {
  63. double scale = Math.Pow(10, decimalPlaces);
  64. Paths64 tmp = Clipper.Union(MinkowskiInternal(Clipper.ScalePath64(pattern, scale),
  65. Clipper.ScalePath64(path, scale), true, isClosed), FillRule.NonZero);
  66. return Clipper.ScalePathsD(tmp, 1 / scale);
  67. }
  68. public static Paths64 Diff(Path64 pattern, Path64 path, bool isClosed)
  69. {
  70. return Clipper.Union(MinkowskiInternal(pattern, path, false, isClosed), FillRule.NonZero);
  71. }
  72. public static PathsD Diff(PathD pattern, PathD path, bool isClosed, int decimalPlaces = 2)
  73. {
  74. double scale = Math.Pow(10, decimalPlaces);
  75. Paths64 tmp = Clipper.Union(MinkowskiInternal(Clipper.ScalePath64(pattern, scale),
  76. Clipper.ScalePath64(path, scale), false, isClosed), FillRule.NonZero);
  77. return Clipper.ScalePathsD(tmp, 1 / scale);
  78. }
  79. }
  80. } // namespace