Path: utzoo!utgpu!news-server.csri.toronto.edu!rpi!usc!cs.utexas.edu!uwm.edu!ux1.cso.uiuc.edu!csrd.uiuc.edu!news From: neeman@s5.csrd.uiuc.edu (Henry J. Neeman) Newsgroups: comp.graphics Subject: Help me rotate? Message-ID: <1991Mar19.185202.4546@csrd.uiuc.edu> Date: 19 Mar 91 18:52:02 GMT Sender: news@csrd.uiuc.edu (news) Organization: Univ of Illinois, Center for Supercomputing R&D, Urbana, IL Lines: 94 Here's an interesting problem that I need to solve. Any ideas? The basic idea: given an object in d-space defined by d points, construct a rotation matrix that rotates the object to be perpendicular to one of the coordinate axes. The method should be fast, but I don't care about minimizing floating point error. Suppose we have a (d-1)-dimensional structure S in d-space (e.g., line in 2D; plane in 3D; hyperplane in 4D), described by d points; i.e., S={Pi|i=1..d}. Note that S is "flat" (e.g., a line segment/triangle/tetrahedron/hyperpentatope in 2/3/4/5-space) rather than some curvy thing like a spline; also that we are interested in the unbounded structure (e.g., the line/plane/hyperplane) rather than the bounded structure that the points Pi specifically define. We want to rotate S such that the normal to S, N, is parallel to a particular coordinate axis; for example, in 3D we might want to rotate the plane S such that N is parallel to the z-axis and S is parallel to the xy-plane. Now in 2D and 3D this is pretty straightforward and can be done efficiently: by finding the slope of S in 2D or the normal from cross products in 3D. But as we move into higher dimensions, it becomes a more interesting problem. Let me tell you how I'm currently solving this: Let Pi=(pi1, pi2, ..., pid). We can obtain the d-1 vectors V1, V2, ..., V(d-1) defining the unbounded structure as Vi = Pi - Pd = [vi1=pi1-pd1 vi2=pi2-pd2 ... vid=pid-pdd]. From the Vi's, we can easily obtain the normal to the d-1 structure S, N, from the solution to the homogeneous equation A*N=0: [ v11 v12 ... v1d ] * [n1] = [0] [ v21 v22 ... v2d ] [n2] [0] A=[ . . . ] N=[. ] [0] [ : : : ] [: ] [0] [v(d-1)1 v(d-1)2 ... v(d-1)d] [nd] [0] That is, N is orthogonal to all vectors Vi, i=1..d-1, so the dot product N.Vi is zero for all i=1..d-1. (Actually, N is a family of such vectors, but we can choose its length arbitrarily for now; later we'll normalize.) This system of equations has a solution, because the rank of A is d-1 and the rank of the space is d. Currently, I solve this system by Gaussian elimination with back substitution, using 1.0 as my initial constant on the family of solutions (i.e., set Nd=1.0, then back substitute). *This method is O(d^3), with a large constant of proportionality.* My first question is: is there a faster way to solve this system that's computationally simple (e.g., no iteration)? Anyway: now that we have a set of d-1 vectors in our d-1 structure S, plus the dth vector, which is S's normal N, we want to rotate S such that it is parallel to d-1 of the coordinate axes and orthogonal to the dth; i.e., we want N to be parallel to one of the coordinate axes. Here's how I'm currently doing this: first, I construct an orthonormal basis for S and N with the same orientation as S. I have N orthogonal to S, so any vector which is orthogonal to N must lie in (unbounded) S. Denoting the rows of A as Ai, we have: Let U1=N. for i=1..d-1 { Replace Ai by Ui. Solve A*U(i+1)=0 for U(i+1), which is orthogonal to N and thus lies in S, and is also orthogonal to all Uj, j <= i. } This algorithm produces a set of mutually orthogonal vectors Ui, i=1..d, such that U1=N is orthogonal to S and Ui, i=2..d, lie in (unbounded) S. Now we normalize: Bi=Ui/|Ui|=[bi1 bi2 ... bid], i=1..d. Then the set B={Bi|i=1..d} is an orthonormal basis for d-space with the same orientation as S. *Thus, the total time complexity is O(d^4), with a large constant of proportionality.* From B, we can construct a rotation matrix R which will rotate the orthonormal basis vectors Bi into the orthonormal vectors of the coordinate axes, except with respect to origins, as follows: Let C={Ci|i=1..d} be the set of coordinate axis vectors (e.g., in 3-space, C1, C2 and C3 correspond to i, j and k respectively). We construct R such that the rows of R are the vectors in the orthonormal basis: R = [B1.C1 B1.C2 ... B1.Cd] = [b11 b12 ... b1d] [B2.C1 B2.C2 ... B2.Cd] [b21 b22 ... b1d] [ : : : ] [ . . . ] [ : : : ] [ : : : ] [Bd.C1 Bd.C2 ... Bd.Cd] [bd1 bd2 ... bdd] Then R is the rotation matrix from B to C. My question is: is there a more efficient way to obtain a rotation of S's normal into one of the coordinate axes? For example, is there some way to obtain such a rotation just from S and its normal? It seems like there should be a better way, but I don't know enough linear algebra or geometry to be able to find it. I'm not overly concerned about reducing error, since my task is to rotate an object that's "very diagonal" to the coordinate axes so that it becomes "mostly parallel" to the coordinate axes. Thanks for your help. Henry Neeman neeman@csrd.uiuc.edu