[Solved] Math Question: How to project a vector onto a normal


#1

@Didier This is a good question for you :wink: :

I am trying to figure out the math to project a vector that represents my player movement direction from a top view ( Fig. 1 ) on to a plane which that is represented by a normal vector ( Fig. 2 ). The movement direction vector is calculated from the top view and doesn’t have any Z ( up/down ) component to it. I am using Bullet to get the normal of the surface that my player is walking on ( represented by the blue lines in Fig. 2 ) and I want to take my movement direction vector ( A ) and line it up with the surface like vector B in Fig. 3.

Fig. 1: Top View Movement Direction Vector
image

Fig. 2: Ground Normal Vector
image

Fig. 3: The Goal is Alignment of Movement Vector With Ground Surface


WIP Character Controller Suitable for 1st/3rd Person Shooter
#2

It is what is called the pitch or attitude of your quaternion.


#3

That’s very simple, Raycast to floor it should return the surface normal.


#4

Hi,

While both these answers would technically suffice, I presume you want a more general solution? Considering there’s several ways of doing it, do you want the answer with vectors or quaternions? As math notation, haxe or node examples (considering this is the Armory forum after all)? :slight_smile:


#5

@Naxela It would be great to get it in Haxe form, using the Armory Vector class, and the math notation could be useful too. :slight_smile: I’m fine using Quats being that there is an applyQuat() function on the Vector class. That might be the best way to do it because I do want to keep the movement direction vector’s length the same, but I can always just normalize it and multiply it to set the length as long as I can get the rotation right.

I’m already getting the surface normal, the question was how to get the direction vector to line up with the surface when the only vector that I have to go off of is the surface normal.


#6

If you want to use vectors you could try this:

Assume that n is the face normal and d the direction vector. p will be the resulting projection vector.

  • make sure that n has a length of 1.
  • calculate the dot product of d and n and store it in a variable. I’ll call it t for temp.
  • perform this calculation: p = d - ( n • t), where n•t means to multiply every value of n with t. This removes every “part” of d that points into the direction of n. In your third figure n•t would be the vector pointing from the tip of B to the tip of A.

I have used this here in the project function: https://github.com/armory3d/logic_pack/blob/master/Sources/armory/logicnode/LookingAtNode.hx
It might be a ltlle hard to read read, as I made slight adjustments to how the math functions work.


#7

OK, that’s awesome, I’ll try it out. Thanks!


#8

@zicklag I have a little more time to help you today. A first advice would be to take some time to familiarize yourself with the quaternions. This is essential to achieve a successful project (less CPU demanding) and not be confronted with rotation problems (cf. “cardan” problem with Euler).

Let’s quickly summarize the need in 3 steps:
1/ obtain the quaternion qa which allows to pass from the vector A, normalized which represents the displacement of your object I suppose and noted â, to the vector N, perpendicular to the plane of projection which you have and noted ^n (read the cap on the n) (normalisation is essentiel before getting qa).
2/ applying this rotation qa to the vector A gives a vector A’ perpendicular to the inclined plane (thus // to N)
3/ do a tilt/attitude of -90° to A’ and “it’s done”

Thus to do it:

  • you will find the “fromTo” function in “Armory/iron math quat” to get the qa quaternion.
  • to set attitude -90° to A’, just apply a quaternion with x = 0, y = 0, z = -0.7071, w = 0.7071

#9

@Didier It might just be my lack of properly understanding Quaternions, but I still think that the vector based approach is more appropriate in this case.
As far as I understand it, Quaternions are an elegant way of describing rotations in 3D space, because of the three complex numbers they use, while I assume he wants to project the vector onto the plane, instead of rotating it into the plane. Like a shadow (assuming that the incoming light is parallel to the surface normal).

As far as I understood the problem, this is what he wants:


where <·, ·> resembles the dot product and the surface normal n has a length of 1. Also there is no rotation or any other (euler) angles involved. If one wants the resulting vector to be as long as the original one, one could apply some simple stretching to it.


#10

@zaethan sure,it exists several ways as with vectorial or trigonometrics ways to resolve this … but quaternions are particularly well suited for game engine … and I find them more fun :sunglasses:
Imagine them like if you where at the command of a plane and flying where you want.
If you look at Armory code, you will see that they are often used, giving a compact code, so I think too it’s a good idea to start to use them if you want to take advantage of actual modern code.


#11

Thank you all for your help! I’ll probably try out both techniques, and I’m glad to have two approaches to try and your explanations will help me understand Quaternion and Vector math a little bit more. This will help a lot. If I get it working, I will be using it in a first person controller that I will share with the community. :smiley:

P.S. If anybody knows any websites dedicated to teaching math including Vector, Quaternion, or Matrix, that would be great.


#12

I was able to get it working with the vector math strategy! I went with the vector based strategy because I understood it more than than the Quaternion based strategy, but as soon as I get a better understanding of Quats that will be a consideration.

I’ve still got to work out some physics issues, but this will help my character controller a lot. Thanks everybody!