• FEATURED

View more

View more

View more

### Image of the Day Submit

IOTD | Top Screenshots

### The latest, straight to your Inbox.

Subscribe to GameDev.net Direct to receive the latest updates and exclusive content.

# Arctg table!

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

19 replies to this topic

### #1asmcoder  Members

Posted 03 August 2009 - 08:20 AM

Anyone could past here, a harcoded Arctg table as array of 360 entries? Would apreciate your help! Thanks.

### #2Álvaro  Members

Posted 03 August 2009 - 08:56 AM

Do you mean a table with the tangent of each angle that is an integer number of degrees?

### #3fastcall22  Moderators

Posted 03 August 2009 - 09:11 AM

DIY:

-- lua5.1local f = assert( io.open( "invtan.txt", "w" ) )for i=0, 360 do	f:write( 1 / math.tan( i * math.pi / 180 ) .. ' ' )end

Output.

EDIT:
Did you want atan, tan or 1 / tan?

[Edited by - _fastcall on August 3, 2009 3:11:01 PM]

### #4Atrix256  Members

Posted 03 August 2009 - 09:12 AM

surely you could make that list yourself via a program? :P

shouldnt be too hard, esp not for someone who knows asm (;

### #5asmcoder  Members

Posted 03 August 2009 - 09:36 AM

Quote:
 Original post by alvaroDo you mean a table with the tangent of each angle that is an integer number of degrees?

I mean the Arc tangent values for the selected angle entry, so ArcTg[0] will store the ArcTg value of angle 0, and ArcTg[359] will store the ArcTg value of angle 259.

See, I have a circle(x0,y0), a point in the circle(x,y).
What I want to do is to detrmine the angle with this formula:

Angle= ArcTg (y-y0/x-x0)

so with the lookup table I can simply do this to get the angle:

float Angle= ArcTgArray[(y-y0/x-x0)];

Thanks.

### #6Álvaro  Members

Posted 03 August 2009 - 09:50 AM

But that slope will not always be in [0,360]... You can't have a table that covers all the reals. You could have a table for values between 0 and 1 (in however many steps you want) and reduce all the other cases to this one. Could that be roughly what you want?

### #7fastcall22  Moderators

Posted 03 August 2009 - 10:12 AM


const int step = 361;
double arctan[step];

// Create a table that uses values from -1 to 1
for ( int i = 0; i < step; ++i )
arctan[i] = std::atan( (double)(i*2 - step) / (double)step );

// Then:
double angle = arctan[ std::min( step-1, std::max( 0, (int)( (test * step + step)/2 ) ) ) ];



You should be using atan2( y-y0, x-x0 ) anyways ...

### #8Álvaro  Members

Posted 03 August 2009 - 10:22 AM

If you don't have atan2, you can use something like this:
double atan2(double y, double x) {
double alpha=3.141592653589793238462643383279;
double gx=-1.0, gy=0.0, result=-alpha;

static double cosine_and_sine[32][2]={
{-1,0},
{0,1},
{0.70710678118654757274,0.70710678118654746172},
{0.92387953251128673848,0.38268343236508978178},
{0.98078528040323043058,0.19509032201612824808},
{0.99518472667219692873,0.098017140329560603629},
{0.99879545620517240501,0.049067674327418014935},
{0.99969881869620424997,0.024541228522912288124},
{0.99992470183914450299,0.012271538285719925387},
{0.99998117528260110909,0.0061358846491544752691},
{0.99999529380957619118,0.0030679567629659761432},
{0.99999882345170187925,0.0015339801862847655001},
{0.99999970586288222663,0.0007669903187427044855},
{0.99999992646571789212,0.00038349518757139556321},
{0.99999998161642933425,0.00019174759731070329153},
{0.99999999540410733356,9.5873799095977344669e-05},
{0.99999999885102686115,4.793689960306688131e-05},
{0.99999999971275665978,2.3968449808418219318e-05},
{0.99999999992818922046,1.1984224905069705298e-05},
{0.9999999999820472496,5.9921124526424275272e-06},
{0.9999999999955118124,2.9960562263346608352e-06},
{0.99999999999887800861,1.4980281131690111427e-06},
{0.99999999999971944664,7.490140565847157414e-07},
{0.9999999999999298339,3.7450702829238412872e-07},
{0.99999999999998245848,1.8725351414619534661e-07},
{0.99999999999999567013,9.3626757073098083589e-08},
{0.99999999999999888978,4.6813378536549088116e-08},
{0.99999999999999977796,2.3406689268274550676e-08},
{0.99999999999999988898,1.1703344634137276992e-08},
{1,5.8516723170686384961e-09},
{1,2.925836158534319248e-09},
{1,1.462918079267159624e-09}
};

for(int i=0;i<32;++i) {
double c=cosine_and_sine[i][0], s=cosine_and_sine[i][1];
double nx=gx*c-gy*s, ny=gy*c+gx*s;
if(x*ny<y*nx) {
result += alpha;
gx=nx;
gy=ny;
}
alpha*=.5;
}
return result;
}



### #9asmcoder  Members

Posted 03 August 2009 - 10:29 AM

@alvaro: I can have only 360 array's entry, and then check for the nearest array value to the value i got from calculating x-x0/y-y0.

@_fastcall: Could you please provide me with the output as you did in your first post? My environement compiler does not have a math library (no cos, sin... functions) and I cannot install other compilers.

Thanks.

### #10fastcall22  Moderators

Posted 03 August 2009 - 10:38 AM

Program:

#include <iterator>
#include <fstream>
#include <iomanip>
#include <cmath>

int main()
{
const int step = 361;
double arctan[step];

// Note:  Range is from -1 to 1 inclusive.
for ( int i = 0; i < step; ++i )
arctan[i] = std::atan( (double)(i*2 - step) / (double)(step-1) );

std::ofstream fs( "out.txt" );
fs.precision( 16 );
std::copy( arctan, arctan + step, std::ostream_iterator<double>( fs, " " ) );
fs.flush();
}



The output:
Output.

You can use the binary interpreters that come with lua or python to generate your tables for you, as shown in my first post.

### #11Emergent  Members

Posted 03 August 2009 - 11:00 AM

1. Your use of the abbreviation "ArcTg" for "arctangent" is unusual. The standard abbreviation is "atan" or occasionally "arctan;" you will see either this or "tan-1" in math texts.

2. You say you have no math libraries? You can compute your table using the series expansion,

which I have taken from the Wikipedia article. Note that the return value is in radians.

[Edited by - Emergent on August 3, 2009 6:00:36 PM]

### #12Nick Alger  Members

Posted 03 August 2009 - 11:17 AM

What alvaro is saying is that you have tangent and arctangent mixed up. Arctangent takes in the ratio of sides on the triangle, which could be anything, and then returns the angle, which is between 0 and 360. It is regular tangent that takes the angle as input.
Tangent:[0,360]->[-inf,inf]
Arctangent:[-inf,inf]->[-90,90]

So it sounds like you want tangent(x) for x from 0 to 360, right?

### #13asmcoder  Members

Posted 03 August 2009 - 12:31 PM

Quote:
 Original post by Maze MasterWhat alvaro is saying is that you have tangent and arctangent mixed up. Arctangent takes in the ratio of sides on the triangle, which could be anything, and then returns the angle, which is between 0 and 360. It is regular tangent that takes the angle as input.Tangent:[0,360]->[-inf,inf]Arctangent:[-inf,inf]->[-90,90]So it sounds like you want tangent(x) for x from 0 to 360, right?

Actually, I want something to return the angle from the diference between
the point in the circle and the center of the circle. I believe this fromula applies in this case:

Angle= arctangen (PointY-CenterY/PointX-CenterX)

Cheers.

### #14Álvaro  Members

Posted 04 August 2009 - 01:42 AM

Quote:
 Original post by asmcoder@alvaro: I can have only 360 array's entry, and then check for the nearest array value to the value i got from calculating x-x0/y-y0.

You mean you will search for the value in the table? Then you need a table of tangent, not arc-tangent, as we have been saying from the beginning.

Quote:
 [...]My environement compiler does not have a math library (no cos, sin... functions) and I cannot install other compilers.

Can you use the code I posted above?

### #15asmcoder  Members

Posted 04 August 2009 - 07:37 AM

Thanks.

### #16Álvaro  Members

Posted 04 August 2009 - 08:25 AM

You are welcome. By the way, if you want the answer in degrees (which I don't recommend), simply change the line double alpha=3.141592653589793238462643383279;' to double alpha=180.0;'.

### #17asmcoder  Members

Posted 04 August 2009 - 10:43 AM

I've done that using this formula: Degree=Radian*180/Pi
Btw, why don't you recommend getting degree answers?

Thanks a lot.

### #18Álvaro  Members

Posted 04 August 2009 - 12:38 PM

Quote:
 Original post by asmcoderI've done that using this formula: Degree=Radian*180/PiBtw, why don't you recommend getting degree answers?

1) It's a more natural choice. Dividing the circle in 360 degrees is a completely arbitrary decision, although it's a familiar one. The length of a circle measured in radii is 2*pi, so it would be natural to measure angles by specifying the length of the arc determined by the angle, measured in radii, and that's what radians are.
2) It makes derivatives simple. The derivative of sin(x) is cos(x) and the derivative of cos(x) is -sin(x), if you measure angles in radians.
3) Libraries (except for OpenGL) and hardware use radians.
4) exp(i*x) = cos(x) + i*sin(x), as long as x is in radians (if this doesn't make sense, I won't try to explain it).

I've been meaning to write a little article advocating the use of the most natural representation in several types of variables. In short, it would say:
* Prefer vectors to angles.
* Prefer radians to degrees (if you have to use angles at all, which you probably don't).
* Start counting from 0.
* Use ranges of the form [x,y), which include the bottom element and don't include the top element.
* Use a 24-hour format for time, instead of am/pm.
* Use fractions, not percentages.

If you follow those simple pieces of advice, your code will have fewer special cases and many formulas will be simpler.

### #19asmcoder  Members

Posted 04 August 2009 - 01:07 PM

Cheers for the explanations dude!

Thanks.

### #20shaolinspin  Members

Posted 05 August 2009 - 01:47 AM

Quote:

Quote:
 I've been meaning to write a little article advocating the use of the most natural representation in several types of variables. In short, it would say

;)

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.