# Arcustangent function of the Apollo Computer, atan() or atan2()?

What type of the arcustangent function was used, the one with single argument only or the famous atan2(y, x) or arctan2(y, x) with two arguments x and y? What kind of aproximation was used?

# Two arguments, but not exactly like atan2()

The first thing you should understand is that although ARCTAN is called in 3 places in the Apollo code, in every case it is used for converting rectilinear coordinates (x, y, z) into spherical coordinates (r, latitude, longitude).

I will describe how ARCTAN is used in the LAT-LONG subroutine, in file LATITUDE_ LONGITUDE_ SUBROUTINES.agc, although the use is similar in the other callers. The first step is to compute gamma = $$\sqrt{x^2+y^2}$$ (lines 77-82). We then divide x and y each by gamma; x/gamma is stored in global variable COSTH and y/gamma is stored in global variable SINTH (lines 83-87). We are then ready to call the ARCTAN subroutine (line 88). After it returns, the result is stored in global variable LAT (line 89). A similar set of calculations determines the longitude.

77:     DLOAD   DSQ
78:     ALPHAV
79:     PDDL    DSQ
80:     ALPHAV +2
81:# Page 1237
83:     DMP SL1R
84:     GAMRP
85:     STODL   COSTH       # COS(LAT) B-1
86:     ALPHAV +4
87:     STCALL  SINTH       # SIN(LAT) B-1
88:     ARCTAN
89:     STODL   LAT     # LAT B0


Like atan2(), ARCTAN takes two arguments. However, unlike atan2(), the arguments must already be pre-divided. In other words, they must be in the range of -1 to +1, and their squares must add to 1. The arguments are taken from the global variables COSTH and SINTH. As the names suggest and because of the pre-division, these arguments are the cosine and sine of the angle we are looking for. The bulk of the subroutine checks the +/- sign of the arguments, adjusting the result for the appropriate quadrant. The main calculation is done by calling ASIN with argument SINTH (line 219).

196:        # Page 1240
197:        # ARCTAN SUBROUTINE
198:        #
199:        # CALLING SEQUENCE
200:        #   SIN THETA IN SINTH B-1
201:        #   COS THETA IN COSTH B-1
202:        #   CALL ARCTAN
203:        #
204:        # OUTPUT
205:        #   ARCTAN THETA IN MPAC AND THETA B-0 IN RANGE -1/2 TO +1/2
206:
207:        ARCTAN      BOV
208:                    CLROVFLW
210:                    SINTH
211:                PDDL    DSQ
212:                    COSTH
214:                BZE SQRT
215:                    ARCTANXX    # ATAN=0/0.  SET THETA=0
216:                BDDV    BOV
217:                    SINTH
218:                    ATAN=90
219:                SR1 ASIN
220:                STORE   THETA
221:                PDDL    BMN
222:                    COSTH
223:                    NEGCOS
227:                    NEGOUT
228:                    DP1/2
229:        ARCTANXX    STORE   THETA
230:                RVQ
231:
232:        NEGOUT      DSU GOTO
233:                    DP1/2
234:                    ARCTANXX
236:                    LODP1/4
237:                    SINTH
238:                STORE   THETA
239:                RVQ


ASIN is a macro for the ARCSIN subroutine in file INTERPRETER.agc. In turn, it is computed from the arccosine, using the relation ARCSIN(X) = PI/2 - ARCCOS(X). (Lines 2704-2705. Yeah, even though we already have the cosine stored in COSTH.) ARCCOS is calculated using the "Hastings approximation" and a 7th degree polynomial.

The result of each of the inverse trig subroutines are angles in the range of -1/2 to +1/2. To convert to radians, you must multiply by $$\pi$$ .

So, there are two arguments, but they must be pre-divided, and the result must be multiplied by $$\pi$$ .

• Could you explain what is done in line 214? The case arctan = 0 for x = 0 and y = 0? – Uwe Oct 11 '18 at 11:52
• @uwe BZE is branch when zero, if true it will run ARCTANXX (after that I am lost). Not sure what RVQ does, return value quit maybe? – Magic Octopus Urn Oct 11 '18 at 13:14
• @MagicOctopusUrn: RVQ is Return via QPRET. Returns to the location specified in the QPRET register. This is the normal way to return from a subroutine, although if the QPRET register had previously been saved to a memory location, then GOTO can be used instead. BZE seems to use the previously computed value gamma = sqrt(x^2+y^2) to find out if both x and y are zero. – Uwe Oct 11 '18 at 15:44
• @DrSheldon Do you want to take a stab at space.stackexchange.com/q/31196/195 ? – Russell Borogove Oct 11 '18 at 16:06
• @RussellBorogove: I've been working on it and hope to have an answer later today! – DrSheldon Oct 11 '18 at 16:27

Here you can see source code of the Apollo 11 Guidance computer.

https://github.com/chrislgarry/Apollo-11/blob/27e2acf88a6345e2b1064c8b006a154363937050/Comanche055/LATITUDE_LONGITUDE_SUBROUTINES.agc

Inside, see Subroutine for ARCTAN.