diff --git a/Sources/Mesh+CSG.swift b/Sources/Mesh+CSG.swift index 54003543..c76f07f7 100644 --- a/Sources/Mesh+CSG.swift +++ b/Sources/Mesh+CSG.swift @@ -511,6 +511,11 @@ public extension Mesh { } return edges } + + /// Reflects each polygon of the mesh along a plane. + /// - Parameter plane: The ``Plane`` against which the vertices are to be reflected. + /// - Returns: A ``Mesh`` representing the reflected mesh. + func reflect(along plane: Plane) -> Self { Self(polygons.map { $0.reflect(along: plane) }) } } private func boundsTest( diff --git a/Sources/Polygon+CSG.swift b/Sources/Polygon+CSG.swift index da7b3a3c..d6325914 100644 --- a/Sources/Polygon+CSG.swift +++ b/Sources/Polygon+CSG.swift @@ -82,6 +82,27 @@ public extension Polygon { intersect(with: plane, edges: &edges) return edges } + + /// Reflects each vertex of the polygon along a plane. + /// - Parameter plane: The ``Plane`` against which the vertices are to be reflected. + /// - Returns: A ``Polygon`` representing the reflected vertices. + func reflect(along plane: Plane) -> Self { + mapVertices { + let p = $0.position.project(onto: plane) + let d = $0.position - p + + //https://math.stackexchange.com/questions/13261/how-to-get-a-reflection-vector + //𝑟=𝑑−2(𝑑⋅𝑛)𝑛 + let n = plane.normal - 2.0 * plane.normal.dot($0.normal) * $0.normal + + return Vertex( + p - d, + n, + $0.texcoord, + $0.color + ) + }.inverted() + } } extension Polygon {