Dot product shortcut (from Game Coding 2nd Ed)

    This site uses cookies. By continuing to browse this site, you are agreeing to our Cookie Policy.

    • Dot product shortcut (from Game Coding 2nd Ed)

      Hi everyone,

      I'm reading Game Coding Complete at the moment and I've come across a point which I'm having difficulty understanding. Hopefully someone can help me out.

      In chapter 13: 3D Basics there is a section on vector maths in which it discusses the dot product and the cross product. It states that the dot product is used to find the cosine of the angle between two vectors, and the cross product is used to find the direction of that angle.

      In the closing paragraph of that section (page 444) it implies that it is possible to determine the direction of the angle using only the dot product. I have tried reading and re-reading this section and even asked for help from a friend of mine with a degree in maths and we're both still stumped.

      The section in question is this: "Through a little trickery, you can do it solely with the dot product, as long as you choose the correct vectors. If you use a vector that points to your right instead of straight ahead, your dot product will yield a positive number if you need to steer right and a negative number if you need to steer left, and something close to zero if the target is right in front of you."

      If anyone could elucidate I would be very grateful. Thanks a lot!
    • RE: Dot product shortcut (from Game Coding 2nd Ed)

      Sure thing.

      The dot product takes two vectors as input and gives you a scalar. If the two vectors are normalized (length of 1.0), the scalar will be between -1.0 and 1.0, depending on the respective orientations of the two input vectors.

      If the two vectors are coincident (pointing in exactly the same direction), the return will be 1.0. If the two vectors are at right angles to one another, the return will be 0.0. If the two vectors are pointing in exactly the opposite direction, the return will be 1.0.

      Most of the time you use the dot product to determine angles, such as the difference between your current direction and the direction to a target. The problem comes when you use acos() function on the return of the dot product - because the result of acos() is always positive (0.0-1.0). You can find whether the resulting steering angle is positive or negative by doing a cross product, and looking at the direction of the resulting vector.

      But, if all you want is a steering input - say -1.0 to steer left full, 0.0 to steer straight ahead, and 1.0 to steer full right, you can take the following shortcut.

      Assume O is a vector describing the location of the vehicle or character you are steering.

      Assume R is a normalized vector (length=1.0) that describes the direction of the character or vehicle's right, in world space.

      Assume T is a vector describing the location of the target.

      Set vector A to (T - O).
      Normalize vector A by dividing it by length(A).
      Take the dot product of A and R.

      You will then get a scalar in the range of [-1,1] and here's how the results will play out - as you can see these results can be input directly into a steering solution:

      negative result = the target is off to the left
      0.0 = the target is directly ahead (or directly behind - watch out for that odd case)
      postive result = the target is off to the right

      So, you don't have to use the expensive acos() and a cross product if all you need is a steering input - this solution doesn't give you exact angles - which is why you might have been confused - it is only a shortcut for finding a value that is communly used in simulations.
      Mr.Mike
      Author, Programmer, Brewer, Patriot
    • I'd just like to point out that the dot product and such are not the easiest functions to grab an understanding of if you havent previously had a college level calc course or something which explains what vectors are. I havent read this section of Mikes book yet and i'm not sure if your talking about 2d vectors or 3d vectors for this example. But if your still having problems grasping this concept then i suggest getting a pencil and some paper and drawing out some 2d graphs and everything will make a lot more sence.
      - Brian Wight
    • Thanks both to Mike for the explanation and Monalin for the suggestion. I now think I understand it almost completely but there is one point that I want to check first before I declare myself fully educated.

      Mike, you say that the beauty of this short cut is that the result of the dot product can be plugged directly into a steering function with a range of -1.0 to 1.0. However, unless I'm getting my maths wrong (which is entirely possible), those extreme turning ranges of -1.0 and 1.0 are only reached if the steering object's directional vector is perpendicular to the target vector.

      If I want to use the dot product's magnitude to determine how quickly the steering object should turn, this causes a problem: If the steering object's directional vector is more than 90 degrees from the target vector the dot product will be lower than the maximum turning range, even though it should be turning as hard as possible to face the right direction.

      Is this an easily solvable problem, or have I simply over-complicated the issue and should stick to checking whether the dot product is positive/negative rather than trying to use its magnitude to vary the degrees of turning?
    • Ah - but you see both vectors should be normalized (length = 1.0) before the dot product is taken.

      That is a critical point I failed to mention in my previous post (but I've edited it!).

      Then, the magnitude of the dot product can only be in the range of [-1, 1].

      For a graphical demonstration of the dot product - check out this web site: falstad.com/dotproduct/
      Mr.Mike
      Author, Programmer, Brewer, Patriot
    • And since it's a range, you can use it as a multiplier for how hard to steer, too. Output should be a continuous range, not discreet -1.0, 0.0 or 1.0. So if it's 0.53 you can use this to multiply by your steering range to get the "hardness" of your turn, especially if you have road friction or some such and want to prevent oversteering and loss of vehicle control.

      I've only ever used it with 2D vectors, but that's only because the general use I've put it to so far has been in FPS-like apps where I'm only concerned with basic ground-plane directions. You could use 2 2D vectors, one for the right vector and one for the up vector and use those two to combine into a 3D movment/steering solution....
      "Your job is not to die for your country. Your job is to make some other poor sod die for his."