var a = Vector2(-1, 1)
var n = Vector2(0,1)
var b = a.reflect(n)
var c = a.bounce(n)
print(b) #(1,1)
print(c) #(-1,-1)

Which do not corresponds with

  • You guys are confused because you're mentally conceptualizing this in a kinda wrong manner. The way things are visualized on that reflect/bounce image doesn't help either. Here, I made a hopefully better diagram:

    Think of reflect as making a mirror image (reflection) of the input vector in respect to normal. This is what GLSL reflect() also does because this exact operation is commonly used in lighting calculations. Mathematically it's calulated likle this: R = I - 2.0 * dot(n, I) * n, where I is the input vector.

    Bounce on the other hand can be visualized precisely like what happens to a ball's movement direction vector when bounced off a wall defined by the normal vector.

Well if image is different than the code output then the image is wrong 🙂

I'd say reflect() should do precisely what is depicted on the left image, i.e. reflecting from surface defined by a normal. Which is consistent with what reflect() does in GLSL for example. Having both in the api is confusing and redundant since bounce(a) = -reflect(a)

It works exactly as the picture shows. Maybe your confusion is that the y-axis points down?

Based on the documentation, it appears reflect and bounce have different meanings for the parameter (and that matches my tests).
For bounce, the parameter n is the normal to the line. For reflect, the parameter n is the direction of the line (so not a normal).
For a line going in the direction (1,0) with a normal of (0,1), giving (1,0) to reflect or (0,1) to bounce will give the same result.

Actually, it makes no sense. Both functions seem to define the same thing but give different results.

Vector2 reflect(n: Vector2) const
Returns the result of reflecting the vector from a line defined by the given direction vector n.

Vector2 bounce(n: Vector2) const
Returns a new vector "bounced off" from a plane defined by the given normal.

extends Node2D

func _ready():
	var a = Vector2(1, 1)
	var n = Vector2(0,-1)
	var b = a.reflect(n)
	var c = a.bounce(n)
	print(b) # (-1, 1)
	print(c) # (1, -1)

Reflect appears to function the same as reflect in GLSL. I don't understand what "bounced off" could mean.

Here's what's happening. (Using Godot's 2D coords: y down)

As I said above, bounce's n is the line's normal. But reflect's n is the line's direction, not normal. The red line shows what the vector bounces/reflects off of if you give it an n of (0,-1).
This exactly matches the results returned by godot:
Vector2(1,1).bounce(Vector2(0,-1)) gives (1,-1)
Vector2(1,1).reflect(Vector2(0,-1)) gives (-1,1)

Ah, okay. I understand now. But the documentation is very confusing (using the variable n and not being a normal).

Also the words "bounce" and "reflect" could mean the same thing (as does the description in the docs) and there does not appear to be a need for 2 functions.

So, yes, it works, but still doesn't really make sense to me.

    Two functions walk into a saloon. "You know what stranger, I reflected up on it and realized Vector Gulch is too small for both of us. Someone will have to bounce."

    Thankyou. I'm here all week [/runs away] 😮 🫣

    cybereality Yep, using n for both is confusing, the docs should have used d or dir (or similar).

    From what I read on reddit (this was confusing people for a while) Godot 2 had the opposite, bounce used the line direction and reflect used a normal. But I haven't confirmed that. I have 22 copies of Godot on my system, I don't want to install 2.0. 🙂
    Oh wait, I have Godot 1.0 in there, time for a quick test...
    (urgh, it's UI is all mauve)
    Hmm, there is no bounce in 1.0.
    Vector2(1,1).reflect(Vector2(0,-1)) gives (2,1), which is wrong in all possible ways. I think I'll stick with 4.0. 🙂

    Plus this seems inconsistent with the reflect function in GLSL. Just all around it could not be more confusing.

    Expanding problem to 3D

    var a = Vector3(2, 2, 2)
    var n = Vector3(0, 1, 0)
    var b = a.reflect(n)
    var c = a.bounce(n)
    print(b) #(-2, 2, -2)
    print(c) #(2, -2, 2)


    It seems that in current godot .bounce() is function that corresponds to mathematical reflection
    https://en.wikipedia.org/wiki/Reflection_(mathematics)

    You guys are confused because you're mentally conceptualizing this in a kinda wrong manner. The way things are visualized on that reflect/bounce image doesn't help either. Here, I made a hopefully better diagram:

    Think of reflect as making a mirror image (reflection) of the input vector in respect to normal. This is what GLSL reflect() also does because this exact operation is commonly used in lighting calculations. Mathematically it's calulated likle this: R = I - 2.0 * dot(n, I) * n, where I is the input vector.

    Bounce on the other hand can be visualized precisely like what happens to a ball's movement direction vector when bounced off a wall defined by the normal vector.

      xyz

      xyz Bounce on the other hand can be visualized precisely like what happens to a ball's movement direction vector when bounced off a wall defined by the normal vector.

      Looking at my 3D example it seems that ball actually pierced through wall 😆

      • xyz replied to this.

        Endeo Well that's because you're confusing positions for directions in your example. Vectors behave exactly as depicted in my above diagram. And it's the same as in @Kojack's diagram just drawn a bit differently. If you translate all vectors to sprout from the origin (which your 3d visualization effectively does by turning them into positions), their arrowheads will be right at positions your spheres ended up.

        @Endeo Imho mixing positions and directions was in fact the main point of your initial bafflement. Try this. On the diagram in your first post, redraw the vectors so they all start at the origin. Now coordinates of each vector's arrowhead will be the same as their component values. Try those numbers on Godot's functions. You'll see that the diagram matches the code output.

        Correct. The vectors are just directions (not positions in space) and the line also is not a line/plane in space but a normal. For the calculations to make sense you can assume both vectors are normalized (so you can discount any position, they just point somewhere) and that the "plane" is really like a dividing angle situated at the origin.