# 2D vector projection question

This topic is 2556 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hi,

I'm currently playing around withe 2D vector graphics (using C# and XNA) for the first time, where I have two vertical walls (each backed by a Vector2D instance) and a projectile launcher in the middle. The launcher can launch a projectile in any direction at any angle. The main aim being to detect collision between a projectile (an arrow, backed by a Vector2D instance) and either wall, and then resolve the collision using a vector projection technique to modify the velocity vector of the projectile so that it bounces off the wall at the correct angle.

The collision detection, I've got working fine. It's the velocity vector calculations that don't seem to be working as planned. Here's my code for that part:

[font="Courier New"] Vector2 v1 = vectorProjectileVelocity;
Vector2 v2 = wall.VectorWall;
Vector2 v2Normal = new Vector2(v2.Y, -v2.X);
Vector2 v2Normalized = Vector2.Normalize(v2);

// dot product between movement vector (v1) and wall vector (v2)
float dp1 = Vector2.Dot(v1, v2);

// projection of movement vector onto wall
Vector2 proj1 = dp1 * v2Normalized;

// dot product between movement vector and wall normal
float dp2 = Vector2.Dot(v1, v2Normal);

// projection of movement vector on wall normal
Vector2 proj2 = dp2 * Vector2.Normalize(v2Normal);
proj2 *= -1;

Vector2 velocityNew = proj1 + proj2;
vectorProjectileVelocity = velocityNew;

[/font]This code is based on a tutorial I found: Vector Tutorial

When I added some debug out in there I can see that velocityNew is completely wrong:
[font="Courier New"]v1 : {X:188.0582 Y:8.220284E-06}
v2 : {X:0 Y:400}
v2Normal : {X:400 Y:0}
v2Normalized : {X:0 Y:1}
dp1 : 0.003288114
proj1 : {X:0 Y:0.003288114}
dp2 : 75223.27
proj2 : {X:-75223.27 Y:0}
vectorProjectileVelocity: {X:188.0582 Y:8.220284E-06}
velocityNew: {X:-75223.27 Y:0.003288114}[/font]

Any ideas why this doesn't work? I know that there are other ways to achieve this, but this seems to be the easiest way to give me the option of applying friction and bounce.

Any help with this is much appreciated.

Cheers

GP

##### Share on other sites
[color=#1C2837]
[color=#1C2837]What is this meant to calculate?
[color=#1C2837]
// dot product between movement vector and wall normal
float dp2 = Vector2.Dot(v1, v2Normal);
[color=#1C2837]

[color=#1C2837]If you meant to project v1 onto v2Normal (I think you did), you should normalize v2Normal (which isn't normalized)

##### Share on other sites

[color="#1c2837"]
[color="#1c2837"]What is this meant to calculate?
[color="#1c2837"]
// dot product between movement vector and wall normal
float dp2 = Vector2.Dot(v1, v2Normal);
[color="#1c2837"]

[color="#1c2837"]If you meant to project v1 onto v2Normal (I think you did), you should normalize v2Normal (which isn't normalized)

Hi, thanks for the reply. To be honest, I'm new to this and have just tried to convert the flash code from the linked tutorial to C#. It's possible that I've made an error, but I've just had another look and it appears to be correct, so maybe the tutorial has a typo? Further down the code, this happens:

[font="Courier New"]// projection of movement vector on wall normal
Vector2 proj2 = dp2 * Vector2.Normalize(v2Normal); [/font]

I thought that that had the same effect? i.e. the dot prodoct is found between the two vecotors and then the projection if found my multiplying the dot product by the normalized vector.

Like I say, it's all new to me, so please correct me if I'm wrong.

Cheers

GP

##### Share on other sites
It looks like v2Normal is meant to be a normal (of a wall?)

It probably should be normalized all the way up here:

[color=#1C2837]Vector2 v2Normal = new Vector2(v2.Y, -v2.X);
[color=#1C2837]

[color=#1C2837]

To answer your question, dot(A, B) * normalize(B) is not the same as dot(A, normalize(B)) * normalize(B) (assuming B wasn't normalized already) - verify this yourself by manually doing the math

##### Share on other sites

It looks like v2Normal is meant to be a normal (of a wall?)

It probably should be normalized all the way up here:

[color="#1c2837"]Vector2 v2Normal = new Vector2(v2.Y, -v2.X);

Thanks for your help rdragon1, you were spot on. Here's some updated code which actually works, just in case someone else finds it useful.

[font="Courier New"] Vector2 v1 = vectorProjectileVelocity;
Vector2 v2 = wall.VectorWall;[/font]

[font="Courier New"] Vector2 v2NormalNormalized = Vector2.Normalize(new Vector2(v2.Y, -v2.X));
Vector2 v2Normalized = Vector2.Normalize(v2);[/font]

[font="Courier New"] // dot product between movement vector (v1) and normalized wall vector (v2)
// This gives us the length of v1 projected in the wall direction (x component)
float dp1 = Vector2.Dot(v2Normalized, v1);[/font]

[font="Courier New"] // Multiply dp by the normalized wall vector to get a new vector of the
// same length as the v1 but in the wall direction
Vector2 proj1 = dp1 * v2Normalized;

// dot product between movement vector (v1) and wall normal
// This gives us the length of v1 projected in the wall's normal direction (y component)
float dp2 = Vector2.Dot(v2NormalNormalized, v1);[/font]

[font="Courier New"] // Multiply dp by the normalized wall normal vector to get a new vector of the
// same length as the v1 but in the wall's normal direction
Vector2 proj2 = dp2 * v2NormalNormalized;

// Invert the projection on the normal
proj2 *= -1;

Vector2 velocityNew = proj1 + proj2;
vectorProjectileVelocity = velocityNew;

[/font]

1. 1
2. 2
Rutin
23
3. 3
JoeJ
20
4. 4
5. 5

• 17
• 40
• 23
• 13
• 13
• ### Forum Statistics

• Total Topics
631730
• Total Posts
3001917
×