Solved

3D rotation

Posted on 1998-02-01
12
355 Views
Last Modified: 2010-04-16
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 )
0
Comment
Question by:yot
  • 4
  • 4
  • 3
  • +1
12 Comments
 
LVL 2

Expert Comment

by:mitchell042997
ID: 1217256
I haven't tried implementing this in code, ao I know not if it is fast or slow, but I have a linear algebra text book which describes linear transformations in some detail.  You can rotate things simply by using linear transformations with sin and cos.  If you are interested in my posting the theory as an answer, I will gladly oblige.
0
 
LVL 5

Expert Comment

by:inter
ID: 1217257
To make it fast we should use lookup table for cosine and sine so please indicate the accuracy so that I can post the code including the lookup table(for example 0.5 degree rotation accuracy enough?)

Igor
0
 

Author Comment

by:yot
ID: 1217258
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.
0
Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

 
LVL 5

Expert Comment

by:inter
ID: 1217259
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 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)*16384); {just scale to num_div}
    SinN[i] := Trunc(sin(2*M_PI*i/num_div)*16384);
  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,AY,AZ:Integer Var
                  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
0
 
LVL 5

Expert Comment

by:inter
ID: 1217260
****************************************
*   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)*scale); {just scale to num_div}
    SinN[i] := Trunc(sin(2*M_PI*i/num_div)*scale);
  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,AY,AZ:Integer; Var
                  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,ry,rz);
  WriteLn(rx:6,ry:6,rz:6);
end.

Igor
0
 

Expert Comment

by:andersh012098
ID: 1217261
if you want to do something fast you should be using Watcom C. My 3d engine is written using only real numbers and it's way fast.

/Anders
0
 

Author Comment

by:yot
ID: 1217262
Igor, ( Yes maaaster ... )

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 ???

0
 

Author Comment

by:yot
ID: 1217263
Igor, ( Yes maaaster ... )

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 ???

0
 
LVL 2

Expert Comment

by:mitchell042997
ID: 1217264
Also if you learn about the math behind the function, you may find ways to speed it up.  Or do other neat tricks with coordinate systems.
0
 
LVL 2

Expert Comment

by:mitchell042997
ID: 1217265
Also if you learn about the math behind the function, you may find ways to speed it up.  Or do other neat tricks with coordinate systems.

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

Accepted Solution

by:
inter earned 70 total points
ID: 1217266
Dear yot,

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
0
 

Author Comment

by:yot
ID: 1217267
Ok, i think i got da main idea !
0

Featured Post

Gigs: Get Your Project Delivered by an Expert

Select from freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely and get projects done right.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

FAQ pages provide a simple way for you to supply and for customers to find answers to the most common questions about your company. Here are six reasons why your company website should have a FAQ page
SEO can be a real minefield to navigate, but there are three simple ways to up your SEO game just be re-assessing your content output.
This Micro Tutorial hows how you can integrate  Mac OSX to a Windows Active Directory Domain. Apple has made it easy to allow users to bind their macs to a windows domain with relative ease. The following video show how to bind OSX Mavericks to …
Two types of users will appreciate AOMEI Backupper Pro: 1 - Those with PCIe drives (and haven't found cloning software that works on them). 2 - Those who want a fast clone of their boot drive (no re-boots needed) and it can clone your drive wh…

813 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now