-
Notifications
You must be signed in to change notification settings - Fork 1
/
Subtraction2Parametric.swift
79 lines (70 loc) · 2.74 KB
/
Subtraction2Parametric.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
import Geometria
/// A Union boolean parametric that joins two shapes into a single shape, if they
/// intersect in space.
public struct Subtraction2Parametric<Vector: Vector2Real & Hashable>: Boolean2Parametric {
public typealias Contour = Parametric2Contour<Vector>
public let lhsContours: [Contour]
public let rhsContours: [Contour]
public let tolerance: Scalar
public init<T1: ParametricClip2Geometry, T2: ParametricClip2Geometry>(
_ lhs: T1,
_ rhs: T2,
tolerance: T1.Scalar = .leastNonzeroMagnitude
) where T1.Vector == T2.Vector, T1.Vector == Vector, T1.Vector: Hashable {
self.init(
lhsContours: lhs.allContours(),
rhsContours: rhs.allContours(),
tolerance: tolerance
)
}
public init(
lhsContours: [Contour],
rhsContours: [Contour],
tolerance: Scalar = .leastNonzeroMagnitude
) {
self.lhsContours = lhsContours
self.rhsContours = rhsContours
self.tolerance = tolerance
}
@inlinable
public func allContours() -> [Contour] {
let rhsReversed = rhsContours.map({ $0.reversed() })
// A subtraction is a union of a geometry and a reverse-wound input geometry
let union = Union2Parametric(
contours: lhsContours + rhsReversed,
tolerance: tolerance
)
return union.allContours()
}
@inlinable
public static func subtraction<T1: ParametricClip2Geometry, T2: ParametricClip2Geometry>(
tolerance: Vector.Scalar = .leastNonzeroMagnitude,
_ lhs: T1,
_ rhs: T2
) -> Compound2Parametric<Vector> where T1.Vector == T2.Vector, T1.Vector == Vector, T1.Vector: Hashable {
let op = Self(lhs, rhs, tolerance: tolerance)
return .init(contours: op.allContours())
}
}
/// Performs a subtraction operation by removing all given parametric geometries
/// from `shape1`.
@inlinable
public func subtraction<Vector: Hashable>(
tolerance: Vector.Scalar = .leastNonzeroMagnitude,
_ shape1: some ParametricClip2Geometry<Vector>,
_ shapes: [some ParametricClip2Geometry<Vector>]
) -> Compound2Parametric<Vector> {
let shapes = shapes.map({ Compound2Parametric($0.reversed()) })
return union(tolerance: tolerance, [Compound2Parametric(shape1)] + shapes)
}
/// Performs a subtraction operation by removing all given parametric geometries
/// from `contour`.
@inlinable
public func subtraction<Vector: Hashable>(
tolerance: Vector.Scalar = .leastNonzeroMagnitude,
contour1: Parametric2Contour<Vector>,
contours: [Parametric2Contour<Vector>]
) -> Compound2Parametric<Vector> {
let contours = contours.map({ $0.reversed() })
return union(tolerance: tolerance, contours: [contour1] + contours)
}