ArcTan Approximation

Jeremy Leach

Senior Member
Here's a little routine to give ArcTan. It's suitable for the Picaxes like the 28X1 that can use the Sin and Cos functions.

It's a simple iterative technique and isn't particularly efficient speedwise because it always goes through 7 iterations.

To use the routine:

1. Load up TanTarget100 with the Tan value (times 100) that you are wanting to get the ArcTan result for.

2. Then Gosub ArcTan

Note: The code below includes some test code you can delete. I've used the test code on the simulator and produced the attached error chart.

Code:
#picaxe 28x1
#rem
#############################################################################
#                                                                           #
#   TITLE              : ArcTan Routine using iterative approximation       #
#                                                                           #
#   Code Version       : 1A                                                 #
#   Date               : April 2009                                         #
#   PICAXE Type        : 28X1 (or any supporting Sin and Cos)               #
#   Firmware           : Unlikely to matter                                 #
#   Editor Software    : 5.2.0                                              #
#   Author             : Jeremy Leach                                       #
#                                                                           #
#############################################################################
#endrem


'VARIABLES
'---------
'Word0 (b0 and b1)
Symbol Angle90 		= b0
Symbol Angle128 		= b1
'Word2 (b4 and b5)
Symbol Sin100 		= b4
Symbol Cos100 		= b5
'Word4 (b8 and b9)
Symbol StepSize 		= b8
'Word6 (b12 and b13)
Symbol Tan100 		= w6
'Word8
Symbol TanTarget100	= w8

TEST:
	TanTarget100 = 10000
	Gosub ArcTan
	Stop

ArcTan:
	'ON ENTRY: TanTarget100 holds the value you want to get the ArcTan value for (positive word only 0 to 9000).
	'ON EXIT: Angle90 holds the result in degrees (0 to 90).

	'Initialise
	StepSize = 64
	Angle128 = 64
	
	Do
		Angle90 = Angle128 * 90 / 128
		
		'Calculate Tan of Angle90 
		Sin100 = Sin Angle90
	      Cos100 = Cos Angle90
	      If Cos100 = 0 Then
	      	Tan100 = 10000
	      Else	      
		      Tan100 = Sin100 * 100 /Cos100
		EndIf
	
		'Adjust the Angle128
		If Tan100 > TanTarget100 Then
			Angle128 = Angle128 - StepSize
		Else
			Angle128 = Angle128 + StepSize
		EndIf
		
		'Halve the stepsize
		StepSize = StepSize / 2
	Loop Until StepSize = 0
	
Return
 

Attachments

Jeremy Leach

Senior Member
BUT ...here's a much better routine, proposed by Skyhawk using simple lookup.
Note: This routine works with results 0 to 45 degrees only.

Code:
Symbol Offset	= b0
Symbol Result	= b0
Symbol Index 	= b1
Symbol ArcTan0	= b2
Symbol ArcTan1	= b3
Symbol Tan100	= b4

EEPROM 0, (0,5,11,16,21,26,30,34,38,41,45)

Test:
	Tan100 = 82
	Gosub ArcTan
	Stop


ArcTan:
	'ON ENTRY: Tan100 holds the argument * 100
	'ON EXIT: Result holds the answer in degrees.
	'NOTE: This only works for angles 0 to 45.
	
	Index = Tan100 / 10
	Offset = Index * 10
	Offset = Tan100 - Offset
	
	Read Index,ArcTan0
	Inc Index
	Read Index,ArcTan1
	
	Result = ArcTan1 - ArcTan0 * Offset / 10 + ArcTan0
Return
 

Technical

Technical Support
Staff member
Optimised a bit more, with lookup values rounded to nearest whole (not rounded down e.g. real value 34.99 should be rounded to 35 not 34!).

Code:
Symbol Offset    = b0
Symbol Result    = b0
Symbol Index     = b1
Symbol ArcTan0    = b2
Symbol ArcTan1    = b3
Symbol Tan100    = b4
 
EEPROM 0, (0,6,11,17,22,27,31,35,39,42,45)
 
Test:
    Tan100 = 82
    Gosub ArcTan
    Stop
 
 
ArcTan:
    'ON ENTRY: Tan100 holds the argument * 100
    'ON EXIT: Result holds the answer in degrees.
    'NOTE: This only works for angles 0 to 45.
 
    Index = Tan100 / 10
    Offset = Tan100 % 10
 
    Read Index,ArcTan0
    Inc Index
    Read Index,ArcTan1
 
    Result = ArcTan1 - ArcTan0 * Offset / 10 + ArcTan0
Return
 
Last edited:

Technical

Technical Support
Staff member
We have added this code as a new standard 'atan' unary command in the 20X2 and to the next 28X2/40X2 firmware release.
 

QuIcK

Senior Member
oh, man. if there was a log approx, i think i would wet myself.
i can never seem to get a bit-log to work. all the examples try to teach you how to do it. which is fine, im all for that, but i can never seem to get them to work... so apparently they arent that good at teaching
 
Top