Need expert help—fast? Use the Help Bell for personalized assistance getting answers to your important questions.

All i need is a FAST procedure that will be given a x,y,z, lengths and : x angle, y angle and z angle and return the resoult of the rotation ( rotate a point X,Y,Z in angle Ax,Ay,Az ). the procedure can use any cos,sin table or matrixes or assembly - just make it fast. If you tell me your real name I'll give you credit for your work when ever i use the procedure.

The procedures declaration should be as simple as that :

Procedure Rotate3D(X,Y,Z:LongInt;AngX,AngY,AngZ:Integer Var resoultX,resoultY,resoultZ:LongInt);

Ofcource the procedure must use an integer values becouse real is way to slow for 3D real time uses ( the X,Y,Z values must be LongInt and not Integer )

The procedures declaration should be as simple as that :

Procedure Rotate3D(X,Y,Z:LongInt;Ang

Ofcource the procedure must use an integer values becouse real is way to slow for 3D real time uses ( the X,Y,Z values must be LongInt and not Integer )

Experts Exchange Solution brought to you by

Enjoy your complimentary solution view.

Get every solution instantly with Premium.
Start your 7-day free trial.

I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Igor

0.5 degree would be very good. I'll be glad to have your code when ever you can give it to me !

Yotam.

To make things fast we should assume some model for our integer operations. I decided the following, if you need more accuracy let me know after trying:

- Assume we divide the 2*PI = 360 deg into 256 (2^8).

- Also, let our cos and sine values are scalled so that 1.0 coresponds to 16384 = 2^14 (we should do all this stuff to represent the divides as shr)

The test program and your source is

Dear zot; here is the story; (Sorry, I know you just one a proc but the word FAST makes things little bit more complicated)

To make things fast we should assume some model for our integer operations. I decided the following, if you need more accuracy let me know after trying:

- Assume we divide the 2*PI = 360 deg into 256 (2^8).

- Also, let our cos and sine values are scalled so that 1.0 coresponds to 16384 = 2^14 (we should do all this stuff to represent the divides as shr)

The look up table construction is

const

num_div = 256;

var

CosN : array[0..num_div-1] of longint;

SinN : array[0..num_div-1] of longint; {we may not need sine because Cos(N) = Sin(N+90) but I'd better do not complicate that much}

procedure PrepareLookUp;

var

i : integer;

M_PI : real;

begin

M_PI := Pi; {Never use Pi, you know it is a function}

for i := 0 to num_div-1 do

begin

CosN[i] := Trunc(cos(2*M_PI*i/num_div

SinN[i] := Trunc(sin(2*M_PI*i/num_div

end;

end;

{Now lets rotate fast:

Note that AngX, AngY, AngZ are the angles scaled to num_div; we should not scale it in the rotation because it is time critical inner loop}

Procedure Rotate3D(X,Y,Z:LongInt;AX,

rX,rY,rZ:LongInt);

var

cx,cy,cz,sx,sy,sz : longint;

begin

cx := CosN[AX]; cy := CosN[AY]; cz := CosN[AZ];

sx := SinN[AX]; sy := SinN[AY]; sz := SinN[AZ];

{rotate around x first}

rX := X;

rY := (Y*cx - Z*sx) * shr 14;

rZ := (Y*sx + Z*cx) * shr 14;

{rotate result around y then}

rX := (rX*cy - rZ*sy) * shr 14;

rZ := (rX*sy + rZ*cy) * shr 14;

{rotate finaly round z}

rX := (rX*cz - rY*sz) * shr 14;

rY := (rX*sz + rY*cz) * shr 14;

end;

It is not very accurate and not too much speedy but the idea is this. If you have time write it in assembler to boostup speed. I test it in BP7.0 real mode so, since the instrucions are 16 bit the BP calls an internal procedure for longmultiplications. As I said this is the idea. If I have time I try to convert it to assembler. By the way, are you using BP7.0?

Sincerely,

Igor

* OPPPPPPPSSSS!!!!!!!!!!!!!!

**************************

This is the one sorry, I do not know what happened

program drot;

const

num_div = 256;

scale = 16384;

var

CosN : array[0..num_div-1] of longint;

SinN : array[0..num_div-1] of longint; {we may not need sine because Cos(N) = Sin(N+90)

but I'd better do not complicate that much}

procedure PrepareLookUp;

var

i : integer;

M_PI : real;

begin

M_PI := Pi; {Never use Pi, you know it is a function}

for i := 0 to num_div-1 do

begin

CosN[i] := Trunc(cos(2*M_PI*i/num_div

SinN[i] := Trunc(sin(2*M_PI*i/num_div

end;

end;

{Now lets rotate fast:

Note that AngX, AngY, AngZ are the angles scaled to num_div; we should not scale it in the rotation because it is

time critical inner loop}

Procedure Rotate3D(X,Y,Z:LongInt;AX,

rX,rY,rZ:LongInt);

var

cx,cy,cz,sx,sy,sz : longint;

begin

cx := CosN[AX]; cy := CosN[AY]; cz := CosN[AZ];

sx := SinN[AX]; sy := SinN[AY]; sz := SinN[AZ];

{rotate around x first}

rX := X;

rY := (Y*cx - Z*sx) div scale;

rZ := (Y*sx + Z*cx) div scale;

{rotate result around y then}

X := (rX*cy - rZ*sy) div scale;

Y := rY;

Z := (rX*sy + rZ*cy) div scale;

{rotate finaly round z}

rX := (X*cz - Y*sz) div scale;

rY := (X*sz + Y*cz) div scale;

rZ := Z;

end;

var

X,y,z : longint;

rX,ry,rz : longint;

begin

PrepareLookUp;

x := 100000;y:=0;z:=0;

Rotate3D(x,y,z,0,32,0,rx,r

WriteLn(rx:6,ry:6,rz:6);

end.

Igor

/Anders

If you want me to give you pointz for your answer then -

Please answer my qustion !, i can't give you credit for comments ( adleast i don't think i can ).

zot ... yot !

* by the way - can i change my f***ing user-name ???

If you want me to give you pointz for your answer then -

Please answer my qustion !, i can't give you credit for comments ( adleast i don't think i can ).

zot ... yot !

* by the way - can i change my f***ing user-name ???

In fact, I have been told that with eijen vectors, you can do ray tracing ****. That is cool. Math is neat.

Mitchell is right, the wolf, doom, heretic, etc clone handles the fast thingies by using what is called RAY CASTING.

If you compile the code above in 32 bit compiler the code is speeded upto 10 times (using 32 bit integer multiplications with register) but this is not possible for real mode BP application.

One other thing is you may wonder why we do not use DIV instead of SHR, this is due to the shr shifts negative numbers as unsigned we need ASR (arithmetic shift right) so if you rewrote the code in pure assembler procedure it again speedup 10 times.

Bye,

Igor

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Pascal

From novice to tech pro — start learning today.

Experts Exchange Solution brought to you by

Enjoy your complimentary solution view.

Get every solution instantly with Premium.
Start your 7-day free trial.