следующий ф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 3D 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 3D 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
AddisonWesley, 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:
 12y^22z^2 2xy2wz 2xz+2wy 
R =  2xy+2wz 12x^22z^2 2yz2wx 
 2xz2wy 2yz+2wx 12x^22y^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
righthand 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)
/****************************************************************************/
/* */
/* 3DRotaion 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 asmversion we'll get */
/* on without using any asmcode... */
/* 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 floatingpoint */
/* 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 UnixWorld 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 SineTable */
#define RSIZE 29000 /* Number of entrys in the DivisionTable */
#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 ) */
/* sinecounters */
unsigned short wx = 0;
unsigned short wy = 0;
unsigned short wz = 0;
/* cosinecounters */
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 unitvectors 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 hiddenplaneremoval 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;
/* sinetable and divisiontable ( 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 LSIZE1. */
/* This will always keep them in range, because the */
/* binary representation of LSIZE1 contains only 1's */
/* and as long as w and v are smaller than LSIZE1 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 bugfix */
/* as well as a speedup) */
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 tempvariable 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 */
/* shiftvalue (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 perspectivesensitive */
/* as the following won't work if depth = 3. */
ClearArea( x, y, a, b );
SetCol("blue");
if ( e1[ DIM1 ] > 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[ DIM1 ] < 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[ DIM1 ] > 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[ DIM1 ] < 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[ DIM1 ] > 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[ DIM1 ] < 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 3Drotationmatrix. I tried to */
/* optimize the code as well as possible and in the same time make it */
/* asmfriendly. 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 */
/* unitvectors. Using three 2Dtransformations 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 CayleyKlein */
/* Parameters. Some of these might even give further improvement. */
/* Another improvement can be achieved using log and */
/* exponentialtables. 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 divisiontable. */
/* Speaking of the divisiontable, 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),
CWBackingStoreCWBackPixel,
&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),
oxa, oya, 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 xaxis:
[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 xaxis 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 precalcualte your points in Basic
first, and just plot the lines in ML, and then try to do "realtime"
vectors where the points are calculated in ML. Want any help, just ask...
Oh yeah, to project a point (x,y,z) into the xyplane, 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/5790336
"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)

XRealName: 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. (gambetalp), rotation
* then pitch then roll sequence. gamrotation, betpitch,
* alproll.
*
* 
*  /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_cosalpT_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_sinalpT_cosgam*T_sinbet*T_cosalp;
T_mx3=T_singam*T_cosbet;
T_my3=T_sinbet;
T_mz3=T_cosgam*T_cosbet;
}
/***********************************************************
* Constructing rotation matrix. (alpbetgam), roll
* then pitch then rotation sequence. gamrotation, betpitch,
* alproll.
*
* 
*  /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_cosgamT_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_singamT_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?

XRealName: 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 Xaxis and then start to rotate it around the Zaxis, it
will turn around the global Zaxis...
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
Xaxis unit vector has coordinates (A,B,C), Yaxis has (D,E,F) and Zaxis
(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 Isz 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 fixedfonts 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 Xaxis 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*Xrotate matrix):
D'=D*cxG*sx
E'=E*cxH*sx
F'=F*cxI*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?

XRealName: 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 alphadegrees around
vector (N1, N2, N3):
[ (1c)xx+c (1c)xy+zs (1c)xzys 0 ]
M = [ (1c)xyzs (1c)yy+c (1c)yz+xs 0 ]
[ (1c)xz+ys (1c)yzxs (1c)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: +35804512961 Helsinki University of Technology
Email: mseppa@neuro.hut.fi Rakentajanaukio 2 C
WWW: http://boojum.hut.fi/~mseppa/ FI02150 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?

XRealName: Kevin Stone
Mika Seppa (Mika.Seppa@hut.fi) wrote:
: "Standard" 4x4 matrix for rotating space alphadegrees around
: vector (N1, N2, N3):
:
: [ (1c)xx+c (1c)xy+zs (1c)xzys 0 ]
: M = [ (1c)xyzs (1c)yy+c (1c)yz+xs 0 ]
: [ (1c)xz+ys (1c)yzxs (1c)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)
