1

I want to draw a plane which is given by the equation: Ax+By+Cz+D=0. I first tried to draw him by setting x,y and then get z from the equation. this did not work fine because there are some planes like 0x+0y+z + 0 = 0 and etc...

my current solution is this: - draw the plane on ZY plane by giving 4 coordinates which goes to infinity. - find out to rotation that should be done in order to bring the normal of the given plane(a,b,c) to lay on z axis. - find the translation that should be done in order for that plane be on x axis. - make the exactly opposite transformation to those rotation and to this translation hence i will get the
plane in his place.

ok

this is a great thing but I can make the proper math calculations(tried a lot of times...) with the dot product and etc....

can someone help me in understanding the exact way it should be done OR give me some formula in which I will put ABCD and get the right transformation?

Cœur
  • 37,241
  • 25
  • 195
  • 267
talel
  • 355
  • 2
  • 16
  • What is it you want exactly? Do you want the a point and normal for the plane? Do you want three points on the plane, do you want the angles of the plane with respect to the Z=0 plane? – wich Jan 25 '11 at 14:33
  • Hi, Thanks for the quick response. I want to be able to draw the plane. for that i need 4 points on the plane, however this task is of greater difficult then to make what is suggested earlier. the exact thing i want is an affine transformation between the YX plane to my plane (Ax+By+Cz+D=0). after having this transformation i can use her to draw my plane by applaying the inverted transformation to a plane i will easealy draw on the YX plane. – talel Jan 25 '11 at 14:47
  • Well, a,b,c,d doesn't give you enough information to get you a fixed affine transformation. The projection could still be at any origin within the plane and at any mapping of the X and Y vector of the original XY plane into your new plane, i.e. any rotation or skew. – wich Jan 25 '11 at 14:55
  • Why not? I have the normal of the plane - call this n1. I have the Z axis - call this n2. What i need to make is rotation in X plane and in Y plane in order to make n1 lay on n2. I can add some translation in order to make them start from the same place. what is exactly not possible? – talel Jan 25 '11 at 14:59
  • Only a normal vector is not enough, you can translate, rotate and skew the contents of each plane without changing the plane definition. The plane defition only gives you an R^2, the coordinate system within that R^2 is completely up for grabs. – wich Jan 25 '11 at 15:53

2 Answers2

1

You will want the following transformation matrix:

    [ x0_x y0_x z0_x o_x ]
M = [ x0_y y0_y z0_y o_y ]
    [ x0_z y0_z z0_z o_z ]
    [    0    0    0   1 ]

Here, z0 is the normal of your plane, and o is the origin of your plane, and x0 and y0 are two vectors within your plane orthogonal to z0 that define the rotation and skew of your projection.

Then any point (x,y) on your XY plane can be projected to a point (p_x, p_y, p_z) your new plane with the following:

(p_x, p_y, p_z, w) = M * (x, y, 0, 1)

now, z0 in your transformation matrix is easy, that's the normal of your plane and that is simply n = normalize(a,b,c).

In choosing the rest however you have distinctly more freedom. For the origin you could take the point that the plane intersects the Z axis, unless of course the plane is parallel to the Z axis, in which case you need something else.

So e.g.

if (c != 0) { //plane intersects Z axis
  o_x = 0;
  o_y = 0;
  o_z = -d/c;
}
else if (b != 0) { // plane intersects Y axis
  o_x = 0;
  o_y = -d/b;
  o_z = 0;
}
else { // plane must intersect the X axis
  o_x = -d/a;
  o_y = 0;
  o_z = 0;
}

In practice you may want to prefer a different test than (c != 0), because with that test it will succeed even is c is very very small but just different from zero, leading your origin to be at say, x=0, y=0, z=10e100 which would probably not be desirable. So some test like (abs(c) > threshold) is probably preferable. However you could of course take an entirely different point in the plane to put the origin, perhaps the point closest to the origin of your original coordinate system, which would be:

o = n * (d / sqrt(a^2 + b^2 + c^2))

Then finally we need to figure out an x0 and y0. Which could be any two linearly independent vectors that are orthogonal to z0.

So first, let's choose a vector in the XY plane for our x0 vector:

x0 = normalize(z0_y, -z0_x, 0)

Now, this fails if your z0 happens to be of the form (0, 0, z0_z) so we need a special case for that:

if (z0_x == 0 && z0_y == 0) {
  x0 = (1, 0, 0)
}
else {
  x0 = normalize(z0_y, -z0_x, 0)
}

Finally let's say we do not want skew and choose y0 to be orthogonal to both x0, and y0, then, using the crossproduct

y0 = normalize(x0_y*y0_z-x0_z*y0_y, x0_z*y0_x-x0_z*y0_z, x0_x*y0_y-x0_y*y0_x)

Now you have all to fill your transformation matrix.

Disclaimer: Appropriate care should be taken when using floating point representations for your numbers, simple (foo == 0) tests are not sufficient in those cases. Read up on floating point math before you start implementing stuff.

Edit: renamed some variables for clarity

wich
  • 16,709
  • 6
  • 47
  • 72
0

Is this what you're asking?

Transforming a simple plane like the xy plane to your plane is fairly simple:

your plane is Ax+By+Cz+D=0

the xy plane is simply z=0. i.e. A=B=D=0, while C=whatever you want. We'll say 1 for simplicity's sake.

When you have a plane in this form, the normal of the plane is defined by the vector (A,B,C)

so you want a rotation that will take you from (0,0,1) to (A,B,C)*

*Note that this will only work if {A,B,C} is unitary. so you may have to divide A B and C each by sqrt(A^2+B^2+C^2).

rotating around just two of the axes can get your from any direction to any other direction, so we'll pick x and y;

here are the rotation matrices for rotations by a about the x axis, and b about the y axis.

Rx := {{1, 0, 0}, {0, Cos[a], Sin[a]}, {0, -Sin[a], Cos[a]}}

Ry := {{Cos[b], 0, -Sin[b]}, {0, 1, 0}, {Sin[b], 0, Cos[b]}}

if we do a rotation about x, followed by a rotation about y, of the vector normal to the xy plane, (0,0,1), we get:

Ry.Rx.{0,0,1} = {-Cos[a] Sin[b], Sin[a], Cos[a] Cos[b]}

which are your A B C values.

i.e.

A = -Cos[a]Sin[b]

B = Sin[a]

C = Cos[a]Cos[b]

From here, it's simple.

a = aSin[B]

so now A = -Cos[aSin[B]]Sin[b]

Cos[aSin[x]] = sqrt(1-x^2) so:

A = -Sqrt[1-B^2] * Sin[b]

b = aSin[-A/sqrt[1-B^2]]

a = aSin[B] (rotation about x axis)

b = aSin[-A/sqrt[1-B^2]] (rotation about y axis)

So we now have the angles about the x and y axes we need to rotate by.

After this, you just need to shift your plane up or down until it matches the one you already have.

The plane you have at the moment, (after those two rotations) is going to be Ax+By+Cz=0.

the plane you want is Ax+Bx+Cz+D=0. To find out d, we will see where the z axis crosses your plane.

i.e. Cz+D=0 -> z = -D/C

So we transform your z in Ax+By+Cz=0 by -D/C to give:

Ax+By+C(z+D/C) = Ax+By+Cz+D=0. Oh would you look at that!

It turns out you don't have to do any extra maths once you have the angles to rotate by!

The two angles will give you A,B, and C. To get D you just copy it from what you had.

Hope that's of some help, I'm not entirely sure how you plan on actually drawing the plane though...

Edited to fix some horrible formatting. hopefully it's better now.

will
  • 10,260
  • 6
  • 46
  • 69
  • Hi!Tnx for the clear and helpful response! I am pretty loosly in math so your help is very appriciate! how does the current solution handle the plane A=0,B=1,C=0,D=0 which is the XZ plane? or in more generallity how it handle planes with B=1 (after normalization). btd: the transform of z with -D/C is after normlizing C? TNX!!!! – talel Jan 25 '11 at 21:33