How to figure out how much of a part's velocity is perpendicular to the velocity of another part

I’m working on developing a game, and I need to solve a bit of an interesting equation/scenario for this one mechanic involved in the game. I already have a solution in mind, but I’m not 100% confident that I haven’t made any mistake or if there’s a better/easier way of accomplishing this task, so for all of you math-people out there, I need your brainpower :smiley:. I want to make sure I’m doing this correctly so I don’t waste my time writing a bunch of useless code.

Let me lay out the scenario that needs to be solved. You have two parts that can be travelling in ANY given direction on a 2D-Plane, ignoring the Y axis as the parts will always be bound to the same height on the Y axis. As stated in the title, I need to figure out how much of part #2’s velocity is perpendicular to the velocity of part #1. That statement may be a bit confusing, and may not be the best way of describing the problem, so I’ve illustrated the problem below with an image to help.

Black lines = travel direction of parts
Light blue numbers = the velocity vector
Green lines = perpendicular travel direction
Pink line = travel direction of first part shown in relation to second part
Red highlight on green line = the distance value I’m trying to figure out
Blue = Axis View (This is a top-down view, Y axis is towards you)

Here’s the steps for my current approach to solve this problem:

  1. If either part has a velocity vector with a negative X value such as part#2, flip the signs of both X and Z so that we can create a proper line equation using the traditional rules of the X axis only moving from negative to positive. In the example above, the second part’s velocity vector would change from (-2, 2) to (2, -2)
  2. Assume point A = (0, 0)
  3. Create equation for line AB (Z = -1X)
  4. Create equation for line AC (Z = -2/3X)
  5. Create equation for line BC (Z = 3/2X - 5)
  6. Find intersection of line AC and line BC, steps for example below
  • -2/3X = 3/2X - 5
  • 2/3X + 3/2X = 5
  • 13/6X = 5
  • X = 5 / (13/6)
  • X ~= 2.308
  • Z = -2/3(2.308)
  • Z ~= -1.538
  • Intersection = (2.308, -1.538)
  1. Finally, either use another equation that calculates distance between two points, or just use roblox’s vector magnitude property to calculate the distance between point B (2, -2 in example) and the intersection point that was just calculation (point C in example)

I also need to know the direction on the X axis of this final distance value, positive or negative, and I’m assuming I can just grab the sign of X from the original velocity vector or part #2, before any potential sign flips in step 1.

Thoughts?

1 Like

In other words, you want to find the vector rejection of v with respect to u, where u,v are the velocities of parts 1 and 2, respectively:

v’ = v-(u*v:Dot(u)/u:Dot(u))

Basically you subtract from v its projection onto u (aka the parallel component).

4 Likes

Wow. that’s a million times shorter than my method. I only ever took the regular math courses in high school, never did anything extra like calculus and sometimes when I run into math problems in code, I wish I had. And my programming in college was never very heavy in math either, so even the math I did learn in high school is a struggle to remember sometimes.

I plugged in the numbers from my example and it worked out to the same answer as mine.
I’ve read up on dot products on the roblox wiki to try and get an understanding of them, and I think it mostly makes sense… but I’m not quite following what your line of code is doing. Do you think you could elaborate with a bit more detail on what you did? I hate using code if I don’t completely understand it.

EDIT: I just implemented this formula into my code, and seems to work exactly as I’d hoped. I’m actually using this to simulate a ball having spin (angular velocity) when its hit by another moving object, and then changing the angular velocity into directional velocity over time to give the ball a curved travel trajectory. I already have the second part of that done, but I needed to solve this problem to calculate how much angular velocity should be applied to the ball. Thanks a ton. I still wouldn’t mind a bit of an elaboration on that line of code though.

2 Likes

v:Dot(u) is the length of v’s projection onto u, times the length of u. The expression u*v:Dot(u)/u:Dot(u) can be read as u*v:Dot(u)/|u|^2 or (u/|u|)*(v:Dot(u/|u|)), which is a vector that represents the parallel component of v with respect to u.

Since any vector can be expressed as the sum of its parallel and perpendicular components with respect to another vector, conversely a vector minus its parallel component gives us the perpendicular component.

Note: the vector projection has a singularity near u=0. You will have to deal with the situation where |u| is very small.