Sign in to follow this  
Kalasjniekof

'd' of plane - rotation?

Recommended Posts

Hi, I've noticed planes are quite a big thingy in games. Unfortunately my math classes didn't cover them... I should have followed them on a higher level... I know the equation for a plane is ax + by + cz + d = 0. I know that a,b,c represents a normal of the plane. But what is this d? The docs say it's the distance from the plane to the origin, but how should I compute it? I can't use the normal for that, can I? [Edited by - Kalasjniekof on May 30, 2005 3:29:40 PM]

Share this post


Link to post
Share on other sites
Hi,
if you chose d=0 your plane will go through the origin of your coordinate system. If you increase/decrease d you basically translate the plane along its normal vector. E.g.if the plane's normal vector points along the y axis changing d will move your plane up and down.
hope that helps
Quak

Share this post


Link to post
Share on other sites
Quote:
The docs say it's the distance from the plane to the origin, but how should I compute it? I can't use the normal for that, can I?
Yes you can, but you need some other information as well. If you just happen to know what distance you want, you can just set d manually. More often though you have a plane normal and a point known to be on the plane, and you want to find d given that information. The solution (for your form of the equation) is d = -(point.Dot(normal)).

Sometimes you will see the plane represented as p.n = d rather than p.n-d = 0. It's pretty much the same thing, but the d values are negatives of each other.

Basically the idea is that the plane is all points p for which the equation p.n = d is satisfied. Thus it makes sense that if you have a point q known to be on the plane, d = q.n. Simply re-arranging as p.n-d = 0 gives you the form you posted.

('.' is the dot product. Also note that I'm assuming the normal is unit-length. Otherwise, d is scaled by the length of the normal. The plane is still valid, but is un-normalized.)

Share this post


Link to post
Share on other sites
I basicly have a line between two points somewhere in 3D space.
Now I want to have a plane through that line.
I have allready calculated the normal and now I have to calculate d.

ax + by + cz + d = 0

Can I just plug one of the points from the line in d = -(ax + by + cz) to get my 'd' or should I use another method?

Share this post


Link to post
Share on other sites
Quote:
Can I just plug one of the points from the line in d = -(ax + by + cz) to get my 'd'
Yes.

(You probably already know that there is an infinite number of planes that contain a given line, but I guess you already have the normal of the plane...)

Share this post


Link to post
Share on other sites
You can't really calculate a plane through a line (2 points) as the plane can be rotated at any degree around the line.

To calculate a plane you must have at least 3 vertices, you then calculate the face normal of that polygon and calculate the distance of the origin to the plane, normal DOT (vertex1-origin).

Hope that helps.

Share this post


Link to post
Share on other sites
hi, I have another question.

I know I can rotate a vector by multiplying the vector by a rotationmatrix like


matrix *

|x|
|y|
|z|
|1|

so can I multiply a plane by multiplying it by a rotationmatrix too?

matrix *

|a|
|b|
|c|
|d|

Share this post


Link to post
Share on other sites
Quote:
Original post by Kalasjniekof
hi, I have another question.

I know I can rotate a vector by multiplying the vector by a rotationmatrix like


matrix *

|x|
|y|
|z|
|1|

so can I multiply a plane by multiplying it by a rotationmatrix too?

matrix *

|a|
|b|
|c|
|d|


nope.

you should only rotate the normal, ie the abc part.

for nonorthogonal transforms you had best convert to another representation, a basevector and normalvector, rotate those, then convert back to the other representation.

Share this post


Link to post
Share on other sites
This will transform a plane by multiplying it to a matrix:


Plane p;
Matrix m;

float[] = { m._11*p.a + m._12*p.b + m._13*p.c,
m._21*p.a + m._22*p.b + m._23*p.c,
m._31*p.a + m._32*p.b + m._33*p.c };

p.a = t[0];
p.b = t[1];
p.c = t[2];
p.d = _14*t[0] + _24*t[1] + _34*t[2] + _44*p.d;





[edit] missed that "+ _44*p.d" when I copied the code =)

Share this post


Link to post
Share on other sites
Of course, if you use a 4x4 rotation matrix with no translation, then the normal part is rotated just like any vector and the 4th component (distance plane to origin in the direction of the normal) is unmodified. So you can rotate a plane with the "same" operator as an homogenous vector : the standard 4x4 * 1x4 matrix multiplication.

More interesting is the case of translation.

When you translate a plane (N,d) by T : you add -T*N to d.
So since it's linear, in terms of matrix, you multiply the plane considered as a vector of 4 dimensions by :

[ 1 0 0 0 ]
[ 0 1 0 0 ]
[ 0 0 1 0 ]
[-Tx -Ty -Tz 1 ]


You see that it does not correspond to the translation matrix used for points :

[ 1 0 0 Tx]
[ 0 1 0 Ty]
[ 0 0 1 Tz]
[ 0 0 0 1 ]


This means that apart pure rotations, you can not multiply a plane (seen as a 1x4 matrix) by a general transformation matrix (used for points and vectors).

In terms of code you need a special function to transform planes.

EDIT : glSmurph just gave this code. Except that he uses the convention origin to plane which gives :
dist(P, Plane) = P.x*Plane.x + P.y*Plane.z + P.x*Plane.x - Plane.d

The minus is unpractical since you can not use the 4D dot product that works so well with SIMD instruction sets. If you use the other convention (the one I use) just replace :

p.d = -_14*t[0] + -_24*t[1] + -_34*t[2] + _44*p.d;

and it's OK. Still, be conscious that this code does not work when the transfo contains scaling.

[Edited by - Charles B on May 30, 2005 5:25:19 PM]

Share this post


Link to post
Share on other sites
Sorry to bother you again, but I'm having trouble understanding glSmurph's code.

I represent my matrix like this

typedef float matrix4x4[16];

so it is represented like this

| 0  4  8   12 |
| 1  5  9   13 |
| 2  6  10  14 |
| 3  7  11  15 |

Can I multiply like this then? (for both translation and rotation, as I try to avoid scaling as much as I can)


void PlaneMatMult(SPlane *plane, float *mat, SPlane *dest)
{
dest->a = plane->a*mat[0] + plane->b*mat[4] + plane->c*mat[8] + mat[12];
dest->b = plane->a*mat[1] + plane->b*mat[5] + plane->c*mat[9] + mat[13];
dest->c = plane->a*mat[2] + plane->b*mat[6] + plane->c*mat[10] + mat[14];
dest->d = plane->a*mat[3] + plane->b*mat[7] + plane->c*mat[11] + mat[15];
}


Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this