Path: csiph.com!v102.xanadu-bbs.net!xanadu-bbs.net!news.glorb.com!transit3.readnews.com!news-out.readnews.com!news-xxxfer.readnews.com!panix!not-for-mail From: JohnF Newsgroups: comp.graphics.algorithms,comp.sys.ibm.pc.demos Subject: Re: figured part out; new questions Date: Sun, 1 Jul 2012 13:50:29 +0000 (UTC) Organization: PANIX Public Access Internet and UNIX, NYC Lines: 97 Message-ID: References: <4fe645de$0$1581$91cee783@newsreader04.highway.telekom.at> NNTP-Posting-Host: panix3.panix.com X-Trace: reader1.panix.com 1341150629 23502 166.84.1.3 (1 Jul 2012 13:50:29 GMT) X-Complaints-To: abuse@panix.com NNTP-Posting-Date: Sun, 1 Jul 2012 13:50:29 +0000 (UTC) User-Agent: tin/2.0.0-20110823 ("Ardenistiel") (UNIX) (NetBSD/5.1.2 (i386)) Xref: csiph.com comp.graphics.algorithms:903 comp.sys.ibm.pc.demos:27 In comp.graphics.algorithms David Melik wrote: > //cube.cpp > //This is my new code. Apparently I had derived the rotation matrices > wrong, There's a real elegant solution at http://paulbourke.net/geometry/rotate/ including C code. I successfully used his stuff to generate the rotating figure on the banner near the top of the page http://www.forkosh.com/lineart.html Here's the function for those rotations, with structs POINT3D and LINE3D defined in the obvious way. See how very easy that is with Bourke's stuff? I wonder if there's a yet easier way. /* ========================================================================== * Function: rotate3dpt ( POINT3D p, LINE3D axis, double theta ) * Purpose: rotate point p around axis by angle theta (in degrees) * -------------------------------------------------------------------------- * Arguments: p (I) POINT3D p={double x,y,z} containing coords * of point to be rotated. * axis (I) LINE3D axis={POINT3D pt1,pt2} defines the * rotation axis, with pt1 its "tail", and * pt2 its "head", such that positive rotation * angles are interpreted by the right-hand * screw rule, pointing toward the head. * theta (I) double containing rotation in degrees. * -------------------------------------------------------------------------- * Returns: ( POINT3D ) {double x,y,z} of rotated coords, * or just returning p's coords for any error * -------------------------------------------------------------------------- * Notes: o See http://paulbourke.net/geometry/rotate/ * for discussion/derivation and original source code. * o we could interpret axislen as theta, thus eliminating * that arg, but we're now just normalizing axis. * ======================================================================= */ /* --- entry point --- */ POINT3D rotate3dpt ( POINT3D p, LINE3D axis, double theta ) { POINT3D r = p; /*p rotated by theta back to caller*/ double costheta=1.0, sintheta=0.0, /* cos,sin(theta in radians) */ pi = 3.14159265359; /* pi (convert theta to radians) */ POINT3D axispt = {0.0,0.0,0.0}; /*axis.pt2 after axis.pt1 xlated to origin*/ double axislen = 1.0; /* to normalize axispt */ /* --- * xlate p and axispt=axis.pt2 so that axis.pt1 goes to origin * (note: axis.pt1 is tail, and axis.pt2 is head of rotation vector) * ----------------------------------------------------------------- */ axispt.x = axis.pt2.x - axis.pt1.x; axispt.y = axis.pt2.y - axis.pt1.y; axispt.z = axis.pt2.z - axis.pt1.z; p.x -= axis.pt1.x; p.y -= axis.pt1.y; p.z -= axis.pt1.z; /* --- * normalize axispt * ---------------- */ axislen = sqrt( ((axispt.x)*(axispt.x)) + ((axispt.y)*(axispt.y)) + ((axispt.z)*(axispt.z)) ); if ( axislen < 0.0000001 ) goto end_of_job; /* axis.pt2=axis.pt1 */ axispt.x /= axislen; axispt.y /= axislen; axispt.z /= axislen; /* --- * apply rotation * -------------- */ costheta = cos(pi*theta/180.); sintheta = sin(pi*theta/180); r.x = r.y = r.z = 0.0; /* initialization */ /* --- x --- */ r.x += (costheta + (1.-costheta) * axispt.x * axispt.x)* p.x; r.x += ((1.-costheta) * axispt.x * axispt.y - axispt.z * sintheta) * p.y; r.x += ((1.-costheta) * axispt.x * axispt.z + axispt.y * sintheta) * p.z; /* --- y --- */ r.y += ((1.-costheta) * axispt.x * axispt.y + axispt.z * sintheta) * p.x; r.y += (costheta + (1.-costheta) * axispt.y * axispt.y)* p.y; r.y += ((1.-costheta) * axispt.y * axispt.z - axispt.x * sintheta) * p.z; /* --- z --- */ r.z += ((1.-costheta) * axispt.x * axispt.z - axispt.y * sintheta) * p.x; r.z += ((1.-costheta) * axispt.y * axispt.z + axispt.x * sintheta) * p.y; r.z += (costheta + (1.-costheta) * axispt.z * axispt.z)* p.z; /* --- * translate rotated point back to original coords * ----------------------------------------------- */ r.x += axis.pt1.x; r.y += axis.pt1.y; r.z += axis.pt1.z; /* --- * return rotated point to caller * ------------------------------ */ end_of_job: return ( r ); } /* --- end-of-function rotate3dpt --- */ -- John Forkosh ( mailto: j@f.com where j=john and f=forkosh )