diff --git a/Sources/Polygon+CSG.swift b/Sources/Polygon+CSG.swift index d6325914..9d13d632 100644 --- a/Sources/Polygon+CSG.swift +++ b/Sources/Polygon+CSG.swift @@ -87,21 +87,7 @@ public extension Polygon { /// - 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() + mapVertices { $0.reflect(along: plane) }.inverted() } } diff --git a/Sources/Vertex.swift b/Sources/Vertex.swift index 0a911883..6f191491 100644 --- a/Sources/Vertex.swift +++ b/Sources/Vertex.swift @@ -214,6 +214,25 @@ public extension Vertex { vertex.color = color ?? .white return vertex } + + /// Reflects the vertex along a plane. + /// - Parameter plane: The ``Plane`` against which the vertices are to be reflected. + /// - Returns: A ``Vertex`` representing the reflected vertex. + func reflect(along plane: Plane) -> Self { + let p = position.project(onto: plane) + let d = position - p + + // https://math.stackexchange.com/questions/13261/how-to-get-a-reflection-vector + // 𝑟=𝑑−2(𝑑⋅𝑛)𝑛 + let n = plane.normal - 2.0 * plane.normal.dot(normal) * normal + + return Self( + p - d, + n, + texcoord, + color + ) + } } extension Vertex { diff --git a/Tests/MeshTests.swift b/Tests/MeshTests.swift index 4229c566..0b2aeb9a 100644 --- a/Tests/MeshTests.swift +++ b/Tests/MeshTests.swift @@ -361,23 +361,22 @@ class MeshTests: XCTestCase { // MARK: Reflection func testQuadReflectionAlongPlane() { - let quad = Polygon(unchecked: [ Vertex(Vector(-0.5, 1.0, 0.5), .unitY, Vector(0.0, 1.0), .black), Vertex(Vector(0.5, 1.0, 0.5), .unitY, Vector(1.0, 1.0), .black), Vertex(Vector(0.5, 1.0, -0.5), .unitY, Vector(1.0, 0.0), .white), Vertex(Vector(-0.5, 1.0, -0.5), .unitY, Vector(0.0, 0.0), .white), ]) - + let expected = Polygon(unchecked: [ Vertex(Vector(-0.5, -1.0, -0.5), -.unitY, Vector(0.0, 0.0), .white), Vertex(Vector(0.5, -1.0, -0.5), -.unitY, Vector(1.0, 0.0), .white), Vertex(Vector(0.5, -1.0, 0.5), -.unitY, Vector(1.0, 1.0), .black), Vertex(Vector(-0.5, -1.0, 0.5), -.unitY, Vector(0.0, 1.0), .black), ]) - + let reflection = quad.reflect(along: .xz) - + XCTAssertEqual(reflection.plane.normal, -.unitY) XCTAssertEqual(reflection.vertices, expected.vertices) }