From Test-Scratch-Wiki

Translate: - English 

Reflection, within the context of this article, is flipping something's velocity/direction over the normal direction of a wall. This kind of calculation has a number of uses, including simulating a particle colliding with its environment (for instance, in the game Pong, a ball reflects off a paddle) and bouncing light rays off of mirrors in raytracing.

Formula

Normal vector.png

This process takes in two inputs, the slope of the wall (m) and the velocity of the particle (xv and yv). It first calculates the unit normal vector of the wall (see picture) as normal x and normal y. Vectors are mathematical representations of arrows —arrows with direction and length. A "unit vector" is a vector whose length is 1. It is important that we use the unit vector of the normal because otherwise the input velocity and output velocity will not have the same speed.

set [normal x v] to ((m) / ([sqrt v] of ((1) + ((m) * (m)))))
set [normal y v] to ((-1) / ([sqrt v] of ((1) + ((m) * (m)))))

But this script fails when the slope of a wall is zero (which is quite often!). To fix this we have to catch it:

if<(m) = [0]>
set [normal x v] to [0]
set [normal y v] to [1]
else
set [normal x v] to ((m) / ([sqrt v] of ((1) + ((m) * (m)))))
set [normal y v] to ((-1) / ([sqrt v] of ((1) + ((m) * (m)))))
end

After calculating this, we take the dot product of the normal vector and the incoming vector (this is vector-math speak, it is fine if you do not understand it) and double it.

set [dot product v] to (((normal x) * (xv))+((normal y) * (yv)))
set [dot product v] to ((2) * (dot product))

Then we scale the normal vector by this double-dot product and subtract this from the original vector. The resulting vector is the new velocity vector.

set [ax v] to ((dot product) * (normal x))
set [ay v] to ((dot product) * (normal y))
change [xv v] by ((0) - (ax))
change [yv v] by ((0) - (ay))

All together, with a few code tweaks:

if<(m) = [0]>
set [normal x v] to [0]
set [normal y v] to [1]
else
set [normal x v] to ((m) / ([sqrt v] of ((1) + ((m) * (m)))))
set [normal y v] to ((-1) / ([sqrt v] of ((1) + ((m) * (m)))))
end
set [dot product v] to (((normal x) * (xv))+((normal y) * (yv)))
set [dot product v] to ((-2) * (dot product))
change [xv v] by ((dot product) * (normal x))
change [yv v] by ((dot product) * (normal y))

See Also

— elaborates on finding the slope of a line