Retornar raios com enumerateBodies alongRayStart

Quero traçar o caminho para onde uma bala se moverá no meu SpriteKit GameScene. Estou usando "enumerateBodies (alongRayStart", posso calcular facilmente a primeira colisão com um corpo de física.

Não sei como calcular o ângulo de reflexão, dado o ponto de contato e o contato normal.

Eu quero calcular o caminho, mais de 5 reflexões / saltos, então primeiro eu:

Lance um raio, obtenha todos os corpos com os quais se cruza e obtenha o mais próximo.Eu então uso esse ponto de contato como o início da minha próxima reflexão / rejeição .... mas estou lutando com o que o ponto final deve ser definido como ....

O que eupensar Eu deveria estar conseguindo obter o ângulo entre o ponto de contato e o contato normal e, em seguida, calcular um novo ponto oposto a isso ...

    var points: [CGPoint] = []
    var start: CGPoint = renderComponent.node.position
    var end: CGPoint = crossHairComponent.node.position

    points.append(start)

    var closestNormal: CGVector = .zero

    for i in 0...5 {

        closestNormal = .zero
        var closestLength: CGFloat? = nil
        var closestContact: CGPoint!

        // Get the closest contact point.
        self.physicsWorld.enumerateBodies(alongRayStart: start, end: end) { (physicsBody, contactPoint, contactNormal, stop) in

            let len = start.distance(point: contactPoint)

            if closestContact == nil {
                closestNormal = contactNormal
                closestLength = len
                closestContact = contactPoint
            } else {
                if len <= closestLength! {
                    closestLength = len
                    closestNormal = contactNormal
                    closestContact = contactPoint
                }
            }
        }


        // This is where the code is just plain wrong and my math fails me.
        if closestContact != nil {

            // Calculate intersection angle...doesn't seem right?
            let v1: CGVector = (end - start).normalized().toCGVector()
            let v2: CGVector = closestNormal.normalized()
            var angle = acos(v1.dot(v2)) * (180 / .pi)

            let v1perp = CGVector(dx: -v1.dy, dy: v1.dx)
            if(v2.dot(v1perp) > 0) {
                angle = 360.0 - angle
            }

            angle = angle.degreesToRadians


            // Set the new start point
            start = closestContact

            // Calculate a new end point somewhere in the distance to cast a ray to, so we can repeat the process again
            let x = closestContact.x + cos(angle)*100
            let y = closestContact.y + sin(-angle)*100
            end = CGPoint(x: x, y: y)  

            // Add points to array to draw them on the screen
            points.append(closestContact)
            points.append(end)
        }

    }

questionAnswers(1)

yourAnswerToTheQuestion