gessel@cs.swarthmore.edu (Dan Gessel) (02/03/89)
I have a question about matrix operations on vertex lists defining objects within a ray tracer. I use a triangular primatve that goes through a recursive subdivision to either smooth out the surface or make it fractal during the ray trace calculation. This allows for very fine detail over the surface without having to store large amount of information. Stored in the vertex list is not only the coordinates of the vertex, but also the normal to the surface at that point. These normals define the smoothing operations required. I use matrices to perform rotations and would like to for scaling operations. The first is no problem, I rotate the vertices and the normals through simple matrix multiplication, but if I want to stretch the object, the normals would be increased in length in the direction of the stretch. If we think of a sphere, it will stretch to an oval shape. We can figure that the opposite should happen, the normals should decrease in the direction of the stretch to the oval shape. That is, given a matrix operation to be performed on a surface, how does this operation affect the normals? Any solutions or sources would be appreciated. Daniel Mark Gessel gessel@cs.swarthmore.edu I apologize if this went up twice. I posted it yesterday and found it marked unavailable this morning, not simply already read, so I assumed it didn't go through.
cme@cloud9.Stratus.COM (Carl Ellison) (02/05/89)
If you have either a plane equation or just a normal (4 or 3 components respectively; homogeneous coordinates or raw 3D) which you want to rotate via some matrix, M, (4x4 or 3x3, respectively) the answer is found in math or physics books on tensors. Between a vertex, v, and a normal, n, one is covariant and the other is contravariant. (I'm not sure, but I think the normal is covariant... That doesn't matter so much for what follows.) The solution comes from the fact that the dot product v.n is an invariant. That is, if you rotate coordinate systems, the scalar result of v.n should remain unchanged ... or v'.n' (each in the new system) should = v.n Assuming v is a row vector so that v' = vM, the normal would be a column vector and n' = inverse(M)n. v'.n' = v M inverse(M) n = v.n It's been ages since I worked this out for matrices with both scaling and skew. I'll leave that to fellow netters. I'm away from graphics devices at the moment. Enjoy, --Carl Ellison UUCP:: cme@cloud9.Stratus.COM SNail:: Stratus Computer; 55 Fairbanks Blvd.; Marlborough MA 01752 Disclaimer:: (of course)
ph@miro.Berkeley.EDU (Paul Heckbert) (02/06/89)
Daniel Gessel (gessel@cs.swarthmore.edu) asks: >... given a matrix operation to be performed on a surface, how does this >operation affect the normals? Good question. It's non-intuitive; you might think that you transform normals by the same matrix as points, but that doesn't work in general. Let's assume you're transforming points like so: p' = p M [m00 m01 m02 m03] [m10 m11 m12 m13] (x' y' z' w') = (x y z 1) [m20 m21 m22 m23] [m30 m31 m32 m33] where p is the original point, p' is the transformed point, and M is the homogeneous transformation matrix. [ref: Foley & van Dam, Fundamentals of Interactive Computer Graphics]. Normals transform like planes. Points are row vectors and planes are column vectors. Given a plane n: (ax+by+cz+d=0), it transforms to the plane n': (a'x'+b'y'+c'z'+d'=0) like so: n' = M~ n (a') [m00 m01 m02 m03]~ (a) (b') [m10 m11 m12 m13] (b) (c') = [m20 m21 m22 m23] (c) (d') [m30 m31 m32 m33] (d) where M~ means the matrix inverse or adjoint of M. ( The adjoint is the transpose of the matrix of cofactors. It is preferable to the inverse matrix in homogeneous matrix algebra because it is a scalar multiple of the inverse, and it always exists, while the inverse does not. inv(M)=adj(M)/det(M) ) Represent the normal (a,b,c) at a surface point by the tangent plane with coefficients (a,b,c,d), transform as above, then normalize (a',b',c'). If you'd rather think of your planes/normals as row vectors then transpose the above and you get n'^ = n^ M~^, where "^" denotes transposition. That's the formula. If you're interested in why, then read on. ------------- Varying d selects from the family of planes perpendicular to normal (a,b,c). You might wonder: what does "d" mean when one is transforming normals, and why set it to 0? Its effects on n' depend on the type of transformation in M. There are shortcuts to the general formula if M is a simple transformation. If M is just a rotation then M~^=M, so you can get away with the formula n'^ = n^ M. If M is just a translation then its inverse will be a translation, so d' may not equal d, but (a',b',c')=(a,b,c), so the normal is unchanged. If M is scale(A,B,C) (scale x by A, scale y by B, scale z by C) then M~^ = scale(1/A,1/B,1/C). If it's a uniform scale (A=B=C) then normalization will undo the scaling, so normalized(n')=n. If the scale is differential (NOT A=B=C) then you can't use the shortcuts n'=n or n'^=n^M. If M is a concatenation of scales, rotates, and translates then M is 4x3 with last column of (0,0,0,1), and so is its inverse, so a', b', and c' are unaffected by d (parallel planes transform to parallel planes). In the most general case, when M contains a perspective transformation (when its last column is not (0,0,0,1)) then its inverse is also a perspective transformation, and a', b', and c' ARE affected by d. In this case parallel planes transform to nonparallel planes. That makes sense intuitively: the yz plane passing through your eye is perpendicular to your line of sight, but translate it left or right and it becomes either front-facing or backfacing in the perspective coordinate system centered on your eye; its normal vector in that space depends on its lateral translation d. The conclusion is that if you're transforming normals then you don't care about d', and if M has no perspective in it then the value of d is irrelevant, but if M does have perspective in it then d influences the transformed normal, and you should choose d such that (ax+by+cz+d=0) is the tangent plane at your surface point. ------ Why transform by the inverse of M? That's fairly easy to show. If our plane equation is pn=0 in one coordinate system then we want to find the new plane equation n' such that p'n'=0 in the transformed coordinate system. We already know p'=pM, and multiplying both sides by M~ on the right, we have p=p'M~. Substituting into pn=0 we have p'M~n=0. If this is to be true for all p' then n'=M~n. ------ Has anybody seen normal/plane transformation explained well in a textbook? Paul Heckbert, CS grad student 508-7 Evans Hall, UC Berkeley UUCP: ucbvax!miro.berkeley.edu!ph Berkeley, CA 94720 ARPA: ph@miro.berkeley.edu