0
\$\begingroup\$

I am trying to understand the dot product. I have found a website that gives you intuition about this topic and one of the examples involves a speed boost pad:

Image of Mario Kart from the article

Imagine the red vector is your speed (x and y direction), and the blue vector is the orientation of the boost pad (x and y direction). Larger numbers are more power.

How much boost will you get? For the analogy, imagine the pad multiplies your speed:

  • If you come in going 0, you'll get nothing [if you are just dropped onto the pad, there's no boost]

  • If you cross the pad perpendicularly, you'll get 0 [just like the banana obliteration, it will give you 0x boost in the perpendicular direction]

But, if we have some overlap, our x-speed will get an x-boost, and our y-speed gets a y-boost:

\$\text{Total} = speed_x \cdot boost_x + speed_y \cdot boost_y\$

Neat, eh? Another way to see it: your incoming speed is \$\|a\|\$, and the max boost is \$\|b\|\$. The percentage of boost you actually get (based on how you're lined up) is \$\cos(θ)\$ , for a total of \$\|a\| \|b\|\cos(θ)\$.

Let's say we have an object moving with a speed v of <3,3> at an angle of 45 degrees and a boost pad p of <10,0>. I am looking to see the increase of vector v when it hits the pad.

I have calculated the dot product obtaining a value of 30. My questions are:

  • how does this value modify the speed vector?

  • And what does this value actually represent? The new total length of v? Does it modify only the x coordinate of v?

  • And how do I add it over the initial vector? What would be the new speed vector after the interaction with the boost pad?

  • If we are to normalize the vectors and calculate the dot product, we get a value of around 0.70(cos 45). How is this value to be used on the current speed vector v<3,3>? And what does this percentage represent?

Also, I imagine that the new value for the vector would be just for the frame where it hits the pad, thus to make use of the boost a timer should be added before the speed comes back to normal.

\$\endgroup\$
3
  • \$\begingroup\$ Short answer: dot product tells you how to project one vector onto another. You take two vectors, normalize them and calculate their dot product. You can now multiply vector A by this dot product and you get the projection of vector A onto B. Dot product is symmetric, so it works both ways. It;s intuitive, because cos(90) is 0, AKA perpendicular vector projected onto another is of zero length. \$\endgroup\$
    – Tooster
    Aug 30, 2021 at 23:35
  • \$\begingroup\$ also your link is dead - is it this one? betterexplained.com/articles/… There are 2 important intuitions about dot product and cross product: - dot product measures "similarity" - when 0 two vectors are perpendicular. When 1 they point the same way. When -1 they point opposite ways. Cross product on the other hand measures "DISsimilarity" -- what is a "signed area" spanned between two vectors. When they are perpendicular the area is a square. When they are collinear the area is 0. Dot and cross product describe complementary concepts. \$\endgroup\$
    – Tooster
    Aug 30, 2021 at 23:43
  • \$\begingroup\$ Just as a note: don't confuse speed and velocity. Speed is just how fast you are going. Velocity is a vector, describing your speed in a particular direction. Speed is the magnitude of the velocity vector. \$\endgroup\$
    – Tashus
    Dec 30, 2021 at 2:23

1 Answer 1

0
\$\begingroup\$

It sounds like the author envisions the mechanic working something like this:

Vector3 boostDirection = Vector3.Normalize(pad.boostVector);
float boostFactor = Vector3.Dot(boostDirection, car.Velocity);

boostFactor = Mathf.Max(boostFactor, 0);

Vector3 velocityChange = pad.boostVector * boostFactor;
// Equivalently:
// velocityChange = new Vector3(
//                     pad.boostVector.x * boostFactor,
//                     pad.boostVector.y * boostFactor,
//                     pad.boostVector.z * boostFactor
//                );

car.velocity += velocityChange;

They don't explicitly state that the boost factor should be clamped so it doesn't drop below zero, but I'd recommend this to avoid getting a boost backward if you drive across the pad the other way (unless you want a bi-directional race of some kind).

Note that since we normalized the pad's vector to a unit vector direction first, we've taken its length out of the dot product equation, leaving \$\text{boostFactor} = \| \text{car.velocity} \| \cos(\theta)\$, where \$\theta\$ is the angle between the car's direction of motion and the boost pad's direction.

So then when we multiply this scalar by the original boost vector, we re-introduce that vector's length, getting a total velocity change with magnitude:

$$\begin{align} \| \text{velocityChange} \| &= \| \text{pad.boostVector}\|\| \text{car.velocity} \| \cos(\theta)\\ &= \text{pad.boostVector} \cdot \text{car.velocity} \end{align}$$

Here the length of the pad's boost vector represents a multiplier on the incoming velocity: a length of 1 means your extra boost is 100% of your incoming velocity if you match the pad direction perfectly. A length of 0.5 means you'll get an extra 50% of your incoming velocity, etc.

Doing it this way, the velocity change is always pointing in the direction of the pad, so if you drive across it at a diagonal, you'll get a nudge to redirect you forward according to the pad's direction, helping you stay on-track even if you veered sideways quickly to catch the boost pad. (I chose to show this style because anecdotally, that's the behaviour I'm used to seeing in racing games - though it's been a while since I played this particular Mario Kart so I don't recall whether that's how they do it)

You could instead choose to normalize the velocity, not the boost vector, and multiply the velocity by the boost factor to get the velocity change. That would give you a boost pad that sill gives you the same magnitude of extra velocity, but preserves your incoming direction: drive across the pad diagonally, and you'll be accelerated diagonally.

Note that this is a good example for showing the kind of thing we might use dot products for, but it's likely not exactly how Mario Kart or other racers implement their boosts. A few considerations we'd often apply when fleshing this out to a real game feature:

  • Fine-grained degrees of success depending on how perfectly you match the pad's angle can feel inconsistent to the player. You'll almost never get the perfect 0-degree-deviation 100% boost.

    So in practice, games will often "bucket" the angle into coarser wedges. Say you get a 100% boost if you're aligned within 5 degrees, and a 75% boost if you're aligned within 45 degrees. This helps with the perceived consistency, and players can clearly feel the difference between hitting the boost "perfectly" and "almost" because there's a discrete jump in the effect (and sounds/visuals we use) rather than a smooth gradient of intermediate degrees.

    We'll still use dot products to compute your alignment and find the correct bucket, we just won't use the dot product directly as the boost factor.

  • Similarly, we'll often have a more restrictive tolerance for what's needed to activate the boost. With the model in the example, if you drive across the pad at an angle of 89 degrees to its direction, you still get a boost.

    Many games will set a higher tolerance before you hit the "minimum boost" bucket, so you have to be travelling at most 45-60 degrees from the pad's direction for it to activate.

  • We'll usually enforce a maximum speed, so that hitting a chain of boosts doesn't multiply your speed exponentially and rocket you out of the level entirely.

  • We'll often "bucket" the velocity change too, similar to how we bucket the angles, for similar consistency reasons.

    Say this boost pad is on a jump to the next segment of track, and the player just landed it on their previous lap. This time, they hit the same boost pad but with 5% less incoming speed. The player probably can't perceive that they did anything differently this time, but if we use the formula above and give them 5% less boost, they end up missing the jump and it looks like the game cheated them!

    So for this type of boost pad, we'd often make it give a fixed amount of extra velocity over a range of speeds, so if you hit it anywhere within this tolerance zone you get the full boost you expect. (Though this "full boost amount" could still depend on which car you're using)

So take this example for what it is: a way to illustrate a situation where dot products are useful, but not as a prescription for how boost pads must be implemented. Like any game mechanic, there are lots of different ways we can choose to implement it to get different effects.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .