Skip to main content
gamedev.net
🔒 Locked

project vector on plane

Started by KingSnake 21 replies 2.4k views
Original Post
KingSnake
KingSnake
hello. In order to make collision reaction i want to project the speed vector on the colliding plane (to implement sliding) Plane is defined by A, B, C, D coefficients as usual. Vector is defined as an origin point, three angles to rotate this point and an absolute length. the result should be a vector with the origin point on the plane, angles and length adjusted properly. Pseudo code welcome! Thanks, Michele.
v71
v71
ok, if i have grasped you want a vector projected on a plane ?
am i right ?
first you should notice the your vector has a starting point and an ending point , trace a line passing by these two points , the direction of such lines are parallel to the plane''s normal
if you look at the line''s equation you see that the vectorial form is
P=P0+t*v
where P0 is the starting point, v is the director vector ( in this case it is equal to ( a,b,c ) form the plane normal )
and t is the interpolation factor , find the intersection beetween this line and the plane , solving some math it yelds to
have the ''t'' factor equal to :

t=-(a*x0+b*y0+c*z0+d)/( a*a+b*b+c*c )

use this value in the previous line equation and you have the starting point of the vector projected on the plane, do this for the ending point, and you have a projected starting point and a projected ending point for a new vector, find the direction of this vector and we are finished :-P



Cedric
Cedric
A vector doesn''t have an ending and a starting point; it has a length and a direction. If you want to project a line segment, then just project the starting and ending points on the plane and you''re done, but I believe you want to project a true speed vector:

if N is the normal of your plane (A,B,C) and is normalized, then:

PerpendicularComponent = Dot(v, N) * N
ParallelComponent = v - PerpendicularComponent

If your vectors are defined with angles, converting them to cartesian coordinates will be a costly operation, but you can probably find another solution that uses the angles directly, if you need good performance.

Cédric
LilBudyWizer
LilBudyWizer
That was a nice, clear way of saying that. Simply a skill I lack.
Keys to success: Ability, ambition and opportunity.
Timkin
Timkin
quote:
Original post by cedricl
If your vectors are defined with angles, converting them to cartesian coordinates will be a costly operation, but you can probably find another solution that uses the angles directly, if you need good performance.



Actually, if the vectors are defined by angles measured from the positive cartesian axes, then you can efficiently compute the vector in cartesians using:

v = |v |(cos(alpha)i +cos(beta)j cos(gamma)k )

where,

alpha: angle from positive x-axis to vector projection in x-y plane
beta: angle from positive y-axis to vector projection in x-y plane
gamma: angle from positive z-axis to vector

Obviously beta is redundant since cos(beta) = sin(alpha). FYI, the bracketed term is just the normal vector in the direction of v .

Once you have the cartesian form of the vector, then cedricl's solution is the way to go.

Cheers,

Timkin

[edited by - Timkin on April 13, 2002 10:55:28 PM]
Cedric
Cedric
I thought that evaluating 3 cos is a costy operation when compared to a dot product. Of course, the OP never mentionned that he needed good performances, so I must agree that in most problems, finding a solution directly with the angles is probably not worth the trouble (if there is such a solution).

Cédric
johnb
johnb
> I thought that evaluating 3 cos is a costy operation when
> compared to a dot product. Of course, the OP never mentionned
> that he needed good performances, so I must agree that in most
> problems, finding a solution directly with the angles is
> probably not worth the trouble (if there is such a solution).

My approach is to first find the solution then optimise it. With trig I agree that it is very expensive to use, but don''t reject it straight away: work though your problem using whatever mathematics you are familar with, then once you have a solution that works look at ways to optimise it, by removing expensive operations such as cos, sin, tan, log, sqrt, etc..

An example is finding the nearest points on two lines, which was discussed in this thread. The final solution involves no trig, but the easiest way to work it out is using the sin and cos of the angle between the lines, which can be eliminated from the final solution using the identity:

sin^2 + cos^2 = 1

The final solution is quicker and more accurate. It is also easier to deal with the degenerate case of parallel lines using it, as this arises when the division is by zero: with trig inaccuracies in calculating the trig functions make finding such cases far less robust.
John BlackburneProgrammer, The Pitbull Syndicate
KingSnake
KingSnake
Thanks everybody. I''ll take a look to everything you posted.

Cedric, you are ubiquitous! Thanks again.


I''ll let you know if it works.


Michele.
KingSnake
KingSnake
And about performance:

Don''t waste time optimizing something that won''t weight much as it is yet!
I have to project the vector only when a collision happens, it''s just calculating it once every some seconds (if it is parallel i skip it..) so don''t mind about performance.

It''s more important that the solution is
-General!
-precise!
-readable!

Bye,

Michele.
KingSnake
KingSnake
It didn''t fit straightly: when you say alpha beta gamma, they are not my ones, that are all ''absolute rotaions'' in sequence

I tried a different way: i had also the two extremities of the segment i want to project: are the same point at time t and t-1.
with them i want to do so:

-project the point at time t on the plane (p2)
-point at time t-1 is assumed on the plane (p1)

i want a method to obtain the angles that the segment p1-p2 projections on the xy/xz/yz planes make with the segment itself
(are the angles i use) to do that i can work with the components of the vector projected on the plane.

note that if i had the segment p1 p3, with p3= p2 projectd on plane, it would be simple to get the angles.
So everything is reduced to PROJECT A POINT ON A PLANE, plane defined as A, B, C, D coefficients.
I know it is basic 3d geometry manipulation, but tell me!

(if it is SO basic, whi DX does not implement some D3DXVECTOR3PROJECTONPLANE(..)?
And all 3d math libs i''ve got don''t do it? IMO this is a basic building block..)

thanks!

Michele.
Cedric
Cedric
Let me recap: p1 is on the plane, p2 is above, p3 = p2 projected. You want the angle between p1-p2 and p1-p3. Right?

To project a point on a plane, I use
P'' = P - PlaneEquation(P) * Normal / Length(Normal) ^ 2

But there is an easier solution to your question: the angle between p1-p2 and the plane is just the complement of the angle between the normal and p1-p2:

angle = PI / 2 - acos(Dot(Normal, p1-p2) / Length(Normal) / Length(p1-p2))

Cédric
Timkin
Timkin
quote:
Original post by KingSnake
i want a method to obtain the angles that the segment p1-p2 projections on the xy/xz/yz planes make with the segment itself




Given two vectors, A and B , the angle between them (theta) can be deduced from the inner product of the unit vectors in the direction of A and B



A.B
cos(theta) = ------
|A||B|


Cheers,

Timkin

[edited by - Timkin on April 15, 2002 12:42:34 AM]
KingSnake
KingSnake
Works, but i had to put -1 in all ''rhw'' fields. Why?

Thanks,

Michele.
KingSnake
KingSnake
DAMN!

I''ve replied to the wrong thread, because of many open windows...
no, it isn''t still working, but i had an idea:
i have a speed vector, the plane normal.
i make CROSS product of them: the resultant is a vector that lies on the plane, but still not the vector i want.
Now i make cross product of this vector and the normal again.
This still lies on the plane and is the vector i wanted.
Just add it to the collision point and i''ve got the projected second point (i have to take care of the cross prod order..).

is it correct?

Bye,

Michele.
Cedric
Cedric
It looks right, but IMO, it''s still more tricky than writing
vProjected = v - Dot(v, N) / |N| ^ 2 * N

Anyway, it''s your code...

Oh, and you can edit your messages by clicking on Edit at the top right corner of your message.

Cédric
Timkin
Timkin
quote:
Original post by KingSnake
no, it isn't still working, but i had an idea:
i have a speed vector, the plane normal.
i make CROSS product of them: the resultant is a vector that lies on the plane, but still not the vector i want.
Now i make cross product of this vector and the normal again.
This still lies on the plane and is the vector i wanted.
Just add it to the collision point and i've got the projected second point (i have to take care of the cross prod order..).



You can get away with this method because it is the same as the one cedricl is suggesting... here's why.

Consider your two vectors, V and N . Let's take

N x(V xN )


which turns out to be equal to


(N .N )V - (N .V )N


Now, N .N =|N |2, so, let's divide our entire equation by |N |2, giving


N x(V xN ) = V - (N .V )N
-------------- ----------
|N |2 |N |2


The right hand side is the vector V minus the component in the direction of N , which must necessarily be the component orthogonal to N and thus is the component of V in the plane. Hence, you can get away with your computation as you described if |N |2 = 1, otherwise you should divide your result by this quantity to scale the projection correctly.

Cheers,

Timkin

[edited by - Timkin on April 17, 2002 12:48:40 AM]
KingSnake
KingSnake
I used my method because i found it intuitive: i reached it drawing vectors on a piece of paper.
Once i grabbed it, if you say that your ones are the same, i''ll try them, but look less intuitive (at first sight).

Anyway, thanks a lot, You were all very kind, because these things are hardly found in books, explained in useful way.
This is often a life-saving place of help!


Bye,

Michele.
Timkin
Timkin
quote:
Original post by KingSnake
Anyway, thanks a lot, You were all very kind, because these things are hardly found in books, explained in useful way.
This is often a life-saving place of help!



Actually, almost ANY introductory text on Calculus & Analytic Geometry will have this problem in there. It is a fundamental task in dealing with vectors to be able to project them into various planes (sub-manifolds).

As to how intuitive the cross-product method is... well, that gets down to your individual eccentricities!

Cheers,

Timkin
KingSnake
KingSnake
I''ve got plenty of books of that kind and no one explains an efficient, clear, usable way to do this.
My university texts have abstruse theorems and nothing to do with real world needs.

if you were luckier, good to you !

Michele.
Timkin
Timkin
quote:
Original post by KingSnake
I've got plenty of books of that kind and no one explains an efficient, clear, usable way to do this.
My university texts have abstruse theorems and nothing to do with real world needs.



No text book could - or should - ever seek to provide an answer to every conceivable application of a theorem in all conceivable domains. Certainly a maths text book shouldn't provide code, or even an algorithm for implementing a mathematical theorem. The idea of a text book is to teach you the underlying theorem, which you can - once you understand it - apply in infinitely many conceivable problem domains. bTW: Maths books have EVERYTHING to do with real world needs... that's why we have them!

It strikes me that you simply haven't understood vector calculus and vector geometry yet and you should go back and study those books you have. Once you have an understanding of the underlying theory you will be able to solve this problem and even apply the method to different problems, should the need arise.

If after reading through those texts you have some specific questions as to why things are the way they are, I - and others in this forum - would be happy to answer those questions.

Cheers and good luck,

Timkin

[edited by - Timkin on April 19, 2002 10:53:33 PM]

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.