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)
}
}