DEMO.DESIGN
Frequently Asked Questions
 
оглавление | demo party в ex-СССР | infused bytes e-mag | новости от ib/news | другие проекты | письмо | win koi lat

следующий фpагмент (2)
- Usenet echoes (21:200/1) -------------------------- COMP.GRAPHICS.ALGORITHMS - Msg : 18 of 25 From : dmd@gradient.cis.upenn.edu 2:5030/144.99 09 May 94 17:44:10 To : All 11 May 94 01:27:26 Subj : Re: How Do I Rotate 3-D Points About A Line Other Than An Axis? -------------------------------------------------------------------------------- In article <1994May7.022812.19687@unlv.edu>, pbanta@unlv.edu (Paul Banta) writes: |> The problem is this: I have some points in 3-D space (x, y, and z |> coordinates). I would like to rotate them about any arbitrary line |> passing through the origin. (Rotation about an axis is well known and |> straight forward. I want to rotate about a line other than one of the |> axes.) There are two other responses to this so far. Both of which use some messy Euler angle thing that was painful to read. A much easier way to do this is by using quaternions (oh no.. not those!). There is a very good discussion starting page 360 in: "Advanced Animation and Rendering Techniques, Theory and Practice" Alan Watt, Mark Watt Addison-Wesley, 1992 along with other places (such as in the '87 Siggraph course notes or the '85 Siggraph paper (both by Ken Shoemake)). I believe there were also posts around two weeks ago that discussed what quaternions were and where references are. Very briefly, quaternions can be thought of as a 4D creature where q = (w,v), where v = (x,y,z) -- a vector, and w is a scalar. For rotating around some normalized vector n (which goes through the origin), by some angle T, w = cos T; v = n sin T For those who like matrices, you can make a rotation matrix from the quaternion q = (w,v) = (w,x,y,z) as: | 1-2y^2-2z^2 2xy-2wz 2xz+2wy | R = | 2xy+2wz 1-2x^2-2z^2 2yz-2wx | | 2xz-2wy 2yz+2wx 1-2x^2-2y^2 | If you are rotating bunches of points, it is efficient to construct the matrix. If you rotating very few, then you will want to read up on quaternions some more, since the construction of the matrix is not necessary, but you can rather use quaternion multiplication and other stuff, which would take a while to write up, but is more efficient. See the reference above. So that's how you rotate around your line (or vector..). The rotation uses the right-hand rule, so you might need a sign flip depending on how you represent your lines.. Quaternions are worth reading up on, just so you know.. - Doug
следующий фpагмент (3)|пpедыдущий фpагмент (1)
/****************************************************************************/ /* */ /* 3D-Rotaion Routines */ /* */ /* CrEatOr: LarZ SamuelssoN (C) AD: 1993 */ /* */ /* Version 0.04: Removed all comments. Read 'em in earlier versions. */ /* This is probably as close to the asm-version we'll get */ /* on without using any asm-code... */ /* public What I have done is to move as much as possible into the */ /* demand main loop... Function calls cost valuable time... */ /* And as asm won't even get close to floating-point */ /* numbers so I converted all routines to integer math. */ /* This is the last production from me before the summer */ /* holidays. But look out for stuff on the Amiga from me */ /* this summer. */ /* I'll be back in the Unix-World with new ideas this */ /* autumn though.... C Ya */ /* */ /* LAteRZ: Decided to add some comments after all :) */ /* */ /* COPYRIGHT Vector0.01 - 0.04.c are SpreadWare */ /* NOTICE If you like 'em, spread 'em */ /* */ /****************************************************************************/ #include <X11/Xlib.h> #include <X11/X.h> #include <stdio.h> #include <math.h> #include <stdlib.h> #define CORNERS 8 /* Number of Corners in the object (Cube) */ #define DIM 3 /* Number of Coordinates */ #define PTS 4 /* Number of Points to contain a Surface */ #define LSIZE 512 /* Number of entrys in the Sine-Table */ #define RSIZE 29000 /* Number of entrys in the Division-Table */ #define fe 13 /* Number of shifts (float ~> int) */ #define fak 8192 /* 2^fe */ void Cls( void ); void Init( void ); void Exit( void ); void WinInit( int, int, unsigned, unsigned ); void SetCol( char * ); void ClearArea( unsigned short, unsigned short, unsigned, unsigned ); void DrawSolid( short, short, short, short, short, short, short, short, unsigned short, unsigned short ); Display *dpy; XPoint mypoints[ PTS ]; XColor xcolour; GC gc; XGCValues xgcvalues; XSetWindowAttributes xsetwattrs; Window win; int scrn, pixel; int main (void) { /* loop variable */ unsigned short i; /* center of rotation */ /* if you are using WinInit( ) these should be x = y ~= scale */ unsigned short x = 600; unsigned short y = 400; /* initial angles for the object ( rem: 2pi = 511 ) */ /* sine-counters */ unsigned short wx = 0; unsigned short wy = 0; unsigned short wz = 0; /* cosine-counters */ unsigned short vx = wx + LSIZE/4; unsigned short vy = wy + LSIZE/4; unsigned short vz = wz + LSIZE/4; /* rotation velocity around the different axises */ unsigned short sx = 1; unsigned short sy = 2; unsigned short sz = 1; /* perspective depth */ int depth = 5; int depte = depth * fak; /* enlargement in pixels ( gives sidelenght of cube = 300 pixels ) */ int scale = 150; /* base vectors ( the three unit-vectors in the euclidian space ) */ int e1[ DIM ]; int e2[ DIM ]; int e3[ DIM ]; /* holds an int temporarily */ int temp; /* cube[][] holds the position of the cube's corners */ /* v[][] is cube[][] with perspective */ int cube[ CORNERS ][ DIM ]; int v[ CORNERS ][ DIM ]; /* num is used in the hidden-plane-removal part to check */ /* whether a side should be drawn or not */ int num = fak / depth; /* for use in ClearArea( ) */ unsigned a = 2*scale; unsigned b = 2*a; /* sine-table and division-table ( see COMMENTS ) */ int sinT[ LSIZE ]; int divT[ RSIZE ]; /* creating the precalculated tables */ for ( i=0; i < LSIZE; i++ ) sinT[i] = fak * sin( 6.28 / LSIZE * i ); for ( i=0; i < RSIZE; i++ ) divT[i] = fak * depte / ( depte - RSIZE/2 + i ); Init( ); /* if you want the cube in a window uncomment the following line */ /* WinInit( x, y, a, b ); */ Cls( ); while (4711) { /* ROTATION */ /* Remember to keep LSIZE as an exponential of 2 as the */ /* following won't work else. Instead of checking if v */ /* and w are out of range I 'AND' them with LSIZE-1. */ /* This will always keep them in range, because the */ /* binary representation of LSIZE-1 contains only 1's */ /* and as long as w and v are smaller than LSIZE-1 they */ /* will be unchanged, but if they get larger they'll */ /* start again from a low value (not necessarily 0 as */ /* in the previous version, so this is a small bug-fix */ /* as well as a speed-up) */ vx = (vx + sx) & LSIZE - 1; vy = (vy + sy) & LSIZE - 1; vz = (vz + sz) & LSIZE - 1; wx = (wx + sx) & LSIZE - 1; wy = (wy + sy) & LSIZE - 1; wz = (wz + sz) & LSIZE - 1; /* After each multiplication I'll get something of the */ /* size fak^2, so I have to shift the values back to */ /* something proportional to fak. Note that I get rid */ /* of the divisions this way. */ e1[0] = -sinT[wz] * sinT[wx] >> fe; e1[1] = sinT[vz] * sinT[wx] >> fe; e1[2] = sinT[vy] * sinT[vx] >> fe; e2[0] = -sinT[wz] * sinT[vx] >> fe; e2[1] = sinT[vz] * sinT[vx] >> fe; e2[2] = -sinT[vy] * sinT[wx] >> fe; e3[0] = sinT[vz] * sinT[vy] >> fe; e3[1] = sinT[wz] * sinT[vy] >> fe; e3[2] = sinT[wy]; /* I am using the temp-variable because else I would */ /* have gotten something proportional to fak^3 and */ /* fak wouldn't have to be that large to make this an */ /* integer overflow. */ temp = -sinT[vz] * sinT[wy] >> fe; temp = temp * sinT[vx] >> fe; e1[0] = e1[0] + temp; temp = -sinT[wz] * sinT[wy] >> fe; temp = temp * sinT[vx] >> fe; e1[1] = e1[1] + temp; temp = sinT[vz] * sinT[wy] >> fe; temp = temp * sinT[wx] >> fe; e2[0] = e2[0] + temp; temp = sinT[wz] * sinT[wy] >> fe; temp = temp * sinT[wx] >> fe; e2[1] = e2[1] + temp; /* Saving adds is also useful, at least for objects */ /* with many corners. What I have done is to use the */ /* symmetry of the corner's coordinates in the cube. */ /* If you look at the previous versions you'll easily */ /* see that the following holds. */ for ( i=0; i<DIM; i++ ) { cube[0][i] = e1[i] + e2[i] + e3[i]; cube[1][i] = e1[i] - e2[i] + e3[i]; cube[2][i] = e1[i] - e2[i] - e3[i]; cube[3][i] = e1[i] + e2[i] - e3[i]; cube[4][i] = - cube[1][i]; cube[5][i] = - cube[2][i]; cube[6][i] = - cube[3][i]; cube[7][i] = - cube[0][i]; } /* PERSPECTIVE */ /* Division is one of the slowest operations you can */ /* perform, so you can do almost whatever it takes to */ /* get rid of them. My solution was to precalculate all */ /* possible divisions and put them in a table. Again */ /* using integer math I have to shift the values back */ /* to something proportional to fak. */ /* Also see COMMENTS on this subject. */ for ( i=0; i <CORNERS; i++ ) { v[i][0] = cube[i][0] * divT[ RSIZE/2 - cube[i][2] ] >> fe; v[i][1] = cube[i][1] * divT[ RSIZE/2 - cube[i][2] ] >> fe; } /* SCALING */ /* If you want to have any sidelenght you want you can */ /* do the scaling as follows. But then you'll have to */ /* do a lot of mulsing and that's BAD for speed. So, */ /* what you might do instead is to play with the */ /* shift-value (fe). */ /* Anyhow, here is where I scale everything back down */ /* to it's ususal proportions, scale * v[][] is prop to */ /* scale * fak and therefore I have to shift the result */ /* to get a 'normal' (~1) value. */ for ( i=0; i<CORNERS; i++ ) { v[i][0] = scale * v[i][0] >> fe; v[i][1] = scale * v[i][1] >> fe; } /* DRAWING */ /* Instead of using Cls( ) or ClearSOb( ) I now use a */ /* a function that clears a rectangle around the cube. */ /* I also removed some of the SetCol( )'s to save time. */ /* */ /* BUG: ClearArea( ) should be perspective-sensitive */ /* as the following won't work if depth = 3. */ ClearArea( x, y, a, b ); SetCol("blue"); if ( e1[ DIM-1 ] > num ) DrawSolid( v[0][0], v[0][1], v[1][0], v[1][1], v[2][0], v[2][1], v[3][0], v[3][1], x, y ); if ( e1[ DIM-1 ] < -num ) DrawSolid( v[4][0], v[4][1], v[5][0], v[5][1], v[6][0], v[6][1], v[7][0], v[7][1], x, y ); SetCol("cornflower blue"); if ( e2[ DIM-1 ] > num ) DrawSolid( v[0][0], v[0][1], v[3][0], v[3][1], v[4][0], v[4][1], v[5][0], v[5][1], x, y ); if ( e2[ DIM-1 ] < -num ) DrawSolid( v[1][0], v[1][1], v[2][0], v[2][1], v[7][0], v[7][1], v[6][0], v[6][1], x, y ); SetCol("darkslateblue"); if ( e3[ DIM-1 ] > num ) DrawSolid( v[0][0], v[0][1], v[1][0], v[1][1], v[6][0], v[6][1], v[5][0], v[5][1], x, y ); if ( e3[ DIM-1 ] < -num ) DrawSolid( v[3][0], v[3][1], v[2][0], v[2][1], v[7][0], v[7][1], v[4][0], v[4][1], x, y ); } Exit( ); return 0; } /* COMMENTS */ /* In the released versions I have chosen to use the simple standard */ /* way of doing rotation, i e using a 3D-rotation-matrix. I tried to */ /* optimize the code as well as possible and in the same time make it */ /* asm-friendly. I wish there were some way of optimizing the drawing */ /* routines. One way of doing this would be to use Double Buffering, */ /* but I haven't got a clue of how to do that under X. So, if anyone */ /* feel up to it, include multibuf.h and start coding (it sure would */ /* be nice to get rid of that flicker). */ /* Time to calculate the number of operations I use in the main loop */ /* */ /* 48 multiplications */ /* 46 adds and subs */ /* 48 shifts (each 13 times) */ /* 6 ands */ /* 6 compares */ /* x drawing stuffs */ /* */ /* I bet there are loads of better algorithms than mine out there, but */ /* I hope I have given you a clue of how things are done. */ /* */ /* IMPROVEMENT SUGGESTIONS */ /* First, use another algorithm to generate the location of the three */ /* unit-vectors. Using three 2D-transformations you will get down to */ /* 12 muls instead of my 16 in that part. Another way of doing it is by */ /* using spherical coordinates: x = rsin(s)cos(t) */ /* y = rsin(s)sin(t) */ /* z = rcos(s) */ /* If you just figure out how the different s and t's for the different */ /* vectors are connected during rigid rotation this will get you down */ /* to 6 muls ( 2/vector ). Yet other ways of doing rotation are by */ /* using Quaternations, Bresenham's algorithms or the Cayley-Klein */ /* Parameters. Some of these might even give further improvement. */ /* Another improvement can be achieved using log- and */ /* exponential-tables. Multiplications can then be replaced with some */ /* adds and table lookups. This is done as follows: */ /* a = b * c / d = e^(log(b) + log(c) - log(d)) */ /* and this is a better way than using a division-table. */ /* Speaking of the division-table, it might also be improved somewhat. */ /* If you print the values of divT[] you'll notice that many of the */ /* values are duplicates, this is because we don't shift the values */ /* enough to notice the difference between some values. So, what you */ /* might do is to make another table containing only every fourth value */ /* of divT[], this way you'll save alot of memory as the size of divT[] */ /* is reduced by a factor of 4. When using the new table, call it */ /* div4T[], replace divT[ something ] with div4T[ (int) something/4 ] */ /* and it should work properly. */ /* The ideas presented above has been given almost no thought at all, */ /* so I will note take any responsibility if something shouldn't work. */ void DrawSolid( short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, unsigned short ox, unsigned short oy ) { mypoints[0].x = ox + x1; mypoints[0].y = oy + y1; mypoints[1].x = ox + x2; mypoints[1].y = oy + y2; mypoints[2].x = ox + x3; mypoints[2].y = oy + y3; mypoints[3].x = ox + x4; mypoints[3].y = oy + y4; XFillPolygon(dpy, win, gc, mypoints, PTS, Convex, CoordModeOrigin); } void ClearArea( unsigned short ox, unsigned short oy, unsigned a, unsigned b ) { SetCol("black"); XFillRectangle(dpy, win, gc, ox - a, oy - a, b, b); } void SetCol( char * str ) { if (XParseColor (dpy, DefaultColormap(dpy,scrn), str, &xcolour)) if (XAllocColor (dpy, DefaultColormap(dpy,scrn), &xcolour)) xgcvalues.foreground = xcolour.pixel; XChangeGC (dpy,gc,GCForeground, &xgcvalues); } void Cls( void ) { XClearWindow(dpy, win); } void Init( void ) { if (!(dpy = XOpenDisplay (NULL))) { fprintf (stderr, "Cannot open display.\n"); exit(1); } scrn = DefaultScreen(dpy); xsetwattrs.backing_store = Always; xsetwattrs.background_pixel = BlackPixel(dpy,scrn); pixel = WhitePixel(dpy,scrn); XChangeWindowAttributes(dpy,RootWindow(dpy,scrn), CWBackingStore|CWBackPixel, &xsetwattrs); win = RootWindow(dpy,scrn); gc = XCreateGC (dpy, RootWindow(dpy,scrn),0,NULL); } void WinInit( int ox, int oy, unsigned a, unsigned b ) { win = XCreateSimpleWindow(dpy, RootWindow(dpy,scrn), ox-a, oy-a, b, b, 0, WhitePixel(dpy,scrn), BlackPixel(dpy,scrn)); XMapWindow(dpy, win); } void Exit( void ) { XFlush (dpy); }
следующий фpагмент (4)|пpедыдущий фpагмент (2)
- Usenet echoes (21:200/1) -------------------------------------- COMP.SYS.CBM - Msg : 111 of 120 From : firefoot@netaxs.com 2:5030/144.99 23 Jun 94 22:26:06 To : All 29 Jun 94 02:31:08 Subj : Re: Let's talk about code... -------------------------------------------------------------------------------- Ok, well, I said I'd post 3d rotation formulas etc. I hope you know a little linear algebra, otherwise this will be confusing. To rotate a point about an axis, multiply the 1x3 matrix of the point by the 3x3 matrix of the axis around which you wish to rotate. (3x3 matricess follow). For example, to obtain the point (x',y',z') by rotating (x,y,z) around the x-axis: [x'] [ 1 0 0 ] [x] [y'] = [ 0 (cos A) (-sin A) ] [y] [z'] [ 0 (sin A) (cos A) ] [z] So, the matrix for rotating about the x-axis is above (where A is the angle). Here are the Y- and Z- axis matricees: Y Z [ (cos A) 0 (sin A) ] [ (cos A) (-sin A) 0 ] [ 0 1 0 ] [ (sin A) (cos A) 0 ] [ (-sin A) 0 (cos A) ] [ 0 0 1 ] That's the mathematical basis behind it - you should be able to take it from there. I would suggest trying to pre-calcualte your points in Basic first, and just plot the lines in ML, and then try to do "real-time" vectors where the points are calculated in ML. Want any help, just ask... Oh yeah, to project a point (x,y,z) into the xy-plane, use: x'=d*x/z y'=d*y/z those are from memory, I *think* they're right. "d" is a constant that controls how much perspective your projection has, just try different values. -- Firefoot/Style firefoot@netaxs.com 215/579-0336 "Where's my Tractor?"
следующий фpагмент (5)|пpедыдущий фpагмент (3)
- Usenet echoes (21:200/1) -------------------------- COMP.GRAPHICS.ALGORITHMS - Msg : 102 of 122 From : savs@cs.mcgill.ca 2:5030/315 25 Oct 95 01:12:24 To : All 26 Oct 95 05:06:00 Subj : Re: 3d Rotation (yet again) -------------------------------------------------------------------------------- X-RealName: Sergei SAVCHENKO In article <46hh2t$f8o@news.eecs.uic.edu>, Andrea Payne <apayne@ernie.eecs.uic.edu> wrote: >I'll just make this quick.. >Uhmm.. I have been working on a flight simulator of sorts, >and I'm trying to get my rotations to work with respect to the object, >not the world axis.. So a yaw rotation will always be a yaw rotation [clipped] >Any response is helpful. > >Thanks, >Andrea /*********************************************************** * Constructing rotation matrix. (gam-bet-alp), rotation * then pitch then roll sequence. gam-rotation, bet-pitch, * alp-roll. * * | * | /z x'= x cos(gam)-z sin(gam) * bet/|----+ z'= x sin(gam)+z cos(gam) * | |/ | alp * -------|-+----------x y'= y cos(bet)-z'sin(bet) * |/| / z"= y sin(bet)+z'cos(bet) * /----+ * / | gam y"= y'cos(alp)-x'sin(alp) * / | x"= y'sin(alp)+x'cos(alp) * |y */ void T_set_rotation_gam_bet_alp(int alp,int bet,int gam) { T_cosalp=cos(alp/TO_RADS); T_sinalp=sin(alp/TO_RADS); T_cosbet=cos(bet/TO_RADS); T_sinbet=sin(bet/TO_RADS); T_cosgam=cos(gam/TO_RADS); T_singam=sin(gam/TO_RADS); T_mx1=T_cosgam*T_cosalp-T_singam*T_sinbet*T_sinalp; T_my1=T_cosbet*T_sinalp; T_mz1=-(T_cosgam*T_sinbet*T_sinalp+T_singam*T_cosalp); T_mx2=-(T_singam*T_sinbet*T_cosalp+T_cosgam*T_sinalp); T_my2=T_cosbet*T_cosalp; T_mz2=T_singam*T_sinalp-T_cosgam*T_sinbet*T_cosalp; T_mx3=T_singam*T_cosbet; T_my3=T_sinbet; T_mz3=T_cosgam*T_cosbet; } /*********************************************************** * Constructing rotation matrix. (alp-bet-gam), roll * then pitch then rotation sequence. gam-rotation, bet-pitch, * alp-roll. * * | * | /z y'= y cos(alp)-x sin(alp) * bet/|----+ x'= y sin(alp)+x cos(alp) * | |/ | alp * -------|-+----------x y"= y'cos(bet)-z sin(bet) * |/| / z'= y'sin(bet)+z cos(bet) * /----+ * / | gam x"= x'cos(gam)-x'sin(gam) * / | z"= x'sin(gam)+x'cos(gam) * |y */ void T_set_rotation_alp_bet_gam(int alp,int bet,int gam) { T_cosalp=cos(alp/TO_RADS); T_sinalp=sin(alp/TO_RADS); T_cosbet=cos(bet/TO_RADS); T_sinbet=sin(bet/TO_RADS); T_cosgam=cos(gam/TO_RADS); T_singam=sin(gam/TO_RADS); T_mx1=T_cosalp*T_cosgam+T_sinalp*T_sinbet*T_singam; T_my1=T_sinalp*T_cosgam-T_cosalp*T_sinbet*T_singam; T_mz1=-T_cosbet*T_singam; T_mx2=-T_sinalp*T_cosbet; T_my2=T_cosalp*T_cosbet; T_mz2=-T_sinbet; T_mx3=T_cosalp*T_singam-T_sinalp*T_sinbet*T_cosgam; T_my3=T_sinalp*T_singam+T_cosalp*T_sinbet*T_cosgam; T_mz3=T_cosbet*T_cosgam; } one matrix is for world rotation another for object rotation, beware direction for y thou. hope it helps, sergei(savs@cs.mcgill.ca)
следующий фpагмент (6)|пpедыдущий фpагмент (4)
- Usenet echoes (21:200/1) -------------------------- COMP.GRAPHICS.ALGORITHMS - Msg : 35 of 52 From : jcook@interaccess.com 2:5030/144.99 05 Jul 94 05:53:08 To : All 07 Jul 94 05:55:36 Subj : 3d basics -------------------------------------------------------------------------------- Are there any good text files on how to do just the basics in 3d -> 2d algorithms, I'm interesting in it for very fast and rough 3d looking graphics, just the basic equations would be nice, also if you could, I've only completed Algebra I & some of II but no Geometry at all and don't know about alot of the geometric vocab. in one text file I saw this equation, what is the " М "? Rotating a point around (0,0,0): Recall that the formula for rotating in 2d is: Xt = X*COS(М) - Y*SIN(М) Yt = X*SIN(М) + Y*COS(М) Rotations in the third deminsion simply involve rotating on all 3 planes. To rotate a point (X,Y,Z) around the point (0,0,0) you would use this algorithim: 1st, rotate on the X axis Yt = Y*COS(Xan) - Z*SIN(Xan) Zt = Y*SIN(Xan) + Z*COS(Xan) Y = Yt -- Note that you must not alter the cordinates Z = Zt -- until both transforms are preformed Next, rotate on the Y axis Xt = X*COS(Yan) - Z*SIN(Yan) Zt = X*SIN(Yan) + Z*COS(Yan) X = Xt Z = Zt And finally, the Z axis Xt = X*COS(Zan) - Y*SIN(Zan) Yt = X*SIN(Zan) + Y*COS(Zan) X = Xt Y = Yt so what does all this mean, I haven't worked with sine and cosine, what are they? what's the Zan representing Zangle? help! please! jcook@interaccess.com ps any references to ftp sites and such are very welcome!
следующий фpагмент (7)|пpедыдущий фpагмент (5)
- Usenet echoes (21:200/1) -------------------------- COMP.GRAPHICS.ALGORITHMS - Msg : 8 of 124 From : pontus.munck@cryonics.ct.se 2:5030/315 20 Nov 95 10:32:00 To : All 26 Nov 95 00:25:32 Subj : Q: How to rotate object matrices correctly? -------------------------------------------------------------------------------- X-RealName: Pontus Munck This problem has been bugging me for quite some time now and I can't seem to solve it. I hope someone can help me... I have implemented the (standard?) way of rotating my objects using a 4x4 matrix with three unit vectors representing the orientation of the object local axes. When I rotate my object I want it to spin in its own local coordinate system, but somehow that is impossible. If I turn the object 45 degrees around the X-axis and then start to rotate it around the Z-axis, it will turn around the global Z-axis... My object matrix looks like this: I A D G 0 I I B E H 0 I I C F I 0 I I X Y Z 1 I X-axis unit vector has coordinates (A,B,C), Y-axis has (D,E,F) and Z-axis (G,H,I). X,Y,Z is the object translation. I have the following matrices for rotating around X,Y,Z: X: Y: Z: I 1 0 0 0 I I cy 0 -sy 0 I I cz sz 0 0 I I 0 cx sx 0 I I 0 1 0 0 I I-sz cz 0 0 I I 0 -sx cx 0 I I sy 0 cy 0 I I 0 0 1 0 I I 0 0 0 1 I I 0 0 0 1 I I 0 0 0 1 I (Hope this looks OK without fixed-fonts too :) sx,cx,sy etc are sin/cos for the displacement angle. I believe that what I need is a way to rotate these axes around _themselves_. Or in other words, if the X-axis is rotated 90 degrees, then this should be taken into account by the rotation formula. I have derived these matrices to eliminate unnecessary muls, but I don't think that is where the error is. I got the following when deriving [O]*[X] (object matrix*X-rotate matrix): D'=D*cx-G*sx E'=E*cx-H*sx F'=F*cx-I*sx G'=D*sx+G*cx H'=E*sx+H*cx I'=F*sx+I*cx Has anyone encountered this problem and solved it? Please explain... Thanks for your help, Pontus. ... Crop Circles: The work of a cereal killer?
следующий фpагмент (8)|пpедыдущий фpагмент (6)
- Usenet echoes (21:200/1) -------------------------- COMP.GRAPHICS.ALGORITHMS - Msg : 114 of 124 From : Mika.Seppa@hut.fi 2:5030/315 24 Nov 95 16:07:18 To : All 26 Nov 95 00:26:34 Subj : Re: Rotate 1 vector about another vector? -------------------------------------------------------------------------------- X-RealName: Mika Seppa I had a similar problem a while ago and since I wasn`t able to find the answer from CG literature, I had to solve it myself. It took some time and a bit of luck, but finally ... "Standard" 4x4 matrix for rotating space alpha-degrees around vector (N1, N2, N3): [ (1-c)xx+c (1-c)xy+zs (1-c)xz-ys 0 ] M = [ (1-c)xy-zs (1-c)yy+c (1-c)yz+xs 0 ] [ (1-c)xz+ys (1-c)yz-xs (1-c)zz+c 0 ] [ 0 0 0 1 ] where: c = cos(alpha) s = sin(alpha) r = sqrt(N1*N1 + N2*N2 + N3*N3) x = N1/r y = N2/r z = N3/r So, rotating vector (V1, V2, V3) goes like this: [M1 M2 M3 0] = [V1 V2 V3 0] * M I hope this helps you to get on ... PS. You can use the right hand rule to get the positive sense. -- ============================================================================= Mika SeppД Low Temperature Laboratory Tel: +358-0-4512961 Helsinki University of Technology Email: mseppa@neuro.hut.fi Rakentajanaukio 2 C WWW: http://boojum.hut.fi/~mseppa/ FI-02150 Espoo, FINLAND =============================================================================
следующий фpагмент (9)|пpедыдущий фpагмент (7)
- Usenet echoes (21:200/1) -------------------------- COMP.GRAPHICS.ALGORITHMS - Msg : 147 of 163 From : kbs3387@silver.sdsmt.edu 2:5030/315 24 Nov 95 22:03:18 To : All 26 Nov 95 02:24:12 Subj : Re: Rotate 1 vector about another vector? -------------------------------------------------------------------------------- X-RealName: Kevin Stone Mika Seppa (Mika.Seppa@hut.fi) wrote: : "Standard" 4x4 matrix for rotating space alpha-degrees around : vector (N1, N2, N3): : : [ (1-c)xx+c (1-c)xy+zs (1-c)xz-ys 0 ] : M = [ (1-c)xy-zs (1-c)yy+c (1-c)yz+xs 0 ] : [ (1-c)xz+ys (1-c)yz-xs (1-c)zz+c 0 ] : [ 0 0 0 1 ] : where: : c = cos(alpha) : s = sin(alpha) : r = sqrt(N1*N1 + N2*N2 + N3*N3) : x = N1/r : y = N2/r : z = N3/r Here's a function that does just that. It was posted to this newsgroup a long while ago. I don't know the name of the guy who posted it, nor do I know if he even wrote it. But, since it was posted here once before... I thought it would be ok to post it here again. Sincerly, Brian Stone bas2631@silver.sdsmt.edu Respond To: kbs3387@silver.sdsmt.edu // This function computes a 3x3 rotation matrix which rotates any // point in space around the vextor V. void create_rotmat(Matrix *mat, float Angle, Point3 V ) { float COS, SIN; float VxxCos, VyyCos, VzzCos, VxyCos, VxzCos, VyzCos; float OneMinCos; float VxSin, VySin, VzSin; /* Get the sine and cosine of the rotation angle */ COS = cos(Angle); SIN = sin(Angle); OneMinCos = 1 - COS; /* ** Do the fixed multiplies ahead of time since some are reused. ** There's definitely room for optimization here when any of the ** components of V are 0. */ VxxCos = (V.x * V.x ) * OneMinCos ; VyyCos = ( V.y * V.y ) * OneMinCos ; VzzCos = (V.z * V.z ) * OneMinCos ; VxyCos = (V.x* V.y) * OneMinCos ; VxzCos = ( V.x* V.z )* OneMinCos ; VyzCos = (V.y * V.z )* OneMinCos ; VxSin = V.x * SIN ; VySin = V.y * SIN ; VzSin = V.z * SIN ; /* ** Now stuff the matrix. */ mat->e[0][0] = COS + VxxCos; mat->e[1][0] = VxyCos + VzSin; mat->e[2][0] = VxzCos - VySin; mat->e[0][1] = VxyCos - VzSin; mat->e[1][1] = COS + VyyCos; mat->e[2][1] = VyzCos + VxSin; mat->e[0][2] = VxzCos + VySin; mat->e[1][2] = VyzCos - VxSin; mat->e[2][2] = COS + VzzCos; }

Всего 8 фpагмент(а/ов) |пpедыдущий фpагмент (8)

Если вы хотите дополнить FAQ - пожалуйста пишите.

design/collection/some content by Frog,
DEMO DESIGN FAQ (C) Realm Of Illusion 1994-2000,
При перепечатке материалов этой страницы пожалуйста ссылайтесь на источник: "DEMO.DESIGN FAQ, http://www.enlight.ru/demo/faq".