Code Samples for Businesses, Schools & Developers Last Updated 20 May 2022 Four of the most commonly used trigonometric functions are built in to the standard Access VBA reference library:
- atn     (arctangent of a number = angle whose tangent is a specified number)
- cos     (cosine of an angle)
- sin     (sine of an angle)
- tan     (tangent of an angle)

However, there are times when additional 'trig' functions are required.

For example, drawing a circle on a map using VBA requires two additional trigonometric functions:
- ASin         (arcsine = angle whose sine is a specified value)
- Atn2         (arctangent of two values - latitude/longitude) The GMapCircle function used to draw the circle populates a 'temporary' table with the co-ordinates for the circle of a set radius centred on a specified latitude & longitude.

The remaining columns are used to create encoded values for each co-ordinate.

Encoding significantly reduces the overall length of the URL needed to overlay the map with a circle on a separate map layer.
The reasons for doing this are explained in the article linked above.
The code is provided in a separate article on this website: Encoded Map Path Co-ordinates.  The GMapCircle function code is as follows:

'====================================
'modified version of code in PHP by Oliver Beattie / Josh McDonald
'====================================

'Set detail = 10 to get records every 10 degrees around circle

Dim R As Long, D As Single, i As Long
Dim brng As Double
Dim Points() As Variant
Dim arrValues As Variant
Dim pLat As Double, pLng As Double
Dim rst As DAO.Recordset

R = 6371000 'earth radius in km

Lat = (Lat * Pi) / 180
Lng = (Lng * Pi) / 180
D = Rad / R 'scaling factor

i = 0

'populate table with circle points
Set rst = CurrentDb.OpenRecordset("tblMapCircle", dbOpenDynaset)

With rst
For i = 0 To 360 Step Detail
brng = i * Pi / 180
pLat = ASin((Sin(Lat) * Cos(D)) + (Cos(Lat) * Sin(D) * Cos(brng)))
pLng = ((Lng + Atn2(Sin(brng) * Sin(D) * Cos(Lat), Cos(D) - Sin(Lat) * Sin(pLat))) * 180) / Pi
pLat = (pLat * 180) / Pi
'Debug.Print i, pLat, pLng
!Bearing = i
!Latitude = pLat
!Longitude = pLng
.Update
Next
.Close
End With

Set rst = Nothing

End Function

Example usage:

'Circle of radius 500 metres centred on postcode BS25 5NB (lat = 51.340207, long = -2.804762) with 10 degree intervals
GMapCircle 51.340207, -2.804762, 500, 10

'Circle of radius 1000 metres centred on postcode SE1 7PB (lat = 51.50282, long = -0.119252) with 5 degree intervals
GMapCircle 51.50282, -0.119252, 1000, 5

The code below contains 6 missing trigonometric functions:
- ASin         (arcsine = angle whose sine is a specified value)
- ACos         (arccosine = angle whose cosine is a specified value)
- ACot         (arccotangent = angle whose cotangent is a specified value)
NOTE: cotangent = 1 / tangent = adjacent / opposite in right-angled triangle
- ASec         (arcsecant = angle whose secant is a specified value)
NOTE: secant = 1 / cosine = hypotenuse / adjacent in right-angled triangle
- ACsc         (arccosecant = angle whose cosecant is a specified value)
NOTE: cosecant = 1 / sine = hypotenuse / opposite in right-angled triangle
- Atn2         (arctangent of two values - latitude/longitude)

These functions are based on code adapted from various sources including https://www.devx.com

Place the code in a standard module e.g. modTrigFunctions

Option Compare Database
Option Explicit

'----------------------------
'MISSING TRIG FUNCTIONS
'----------------------------

' arc sine
' error if value is outside the range [-1,1]
Function ASin(Value As Double) As Double
If Abs(Value) <> 1 Then
ASin = Atn(Value / Sqr(1 - Value * Value))
Else
ASin = 1.5707963267949 * Sgn(Value)
End If
End Function

'----------------------------
' arc cosine
' error if NUMBER is outside the range [-1,1]
Function ACos(ByVal Number As Double) As Double
If Abs(Number) <> 1 Then
ACos = 1.5707963267949 - Atn(Number / Sqr(1 - Number * Number))
ElseIf Number = -1 Then
ACos = 3.14159265358979
End If
'elseif number=1 --> Acos=0 (implicit)
End Function

'----------------------------
' arc cotangent
' error if NUMBER is zero
Function ACot(Value As Double) As Double
ACot = Atn(1 / Value)
End Function

'----------------------------
' arc secant
' error if value is inside the range [-1,1]
Function ASec(Value As Double) As Double
' NOTE: the following lines can be replaced by a single call
' ASec = ACos(1 / value)
If Abs(Value) <> 1 Then
ASec = 1.5707963267949 - Atn((1 / Value) / Sqr(1 - 1 / (Value * Value)))
Else
ASec = 3.14159265358979 * Sgn(Value)
End If
End Function

'----------------------------
' arc cosecant
' error if value is inside the range [-1,1]
Function ACsc(Value As Double) As Double
' NOTE: the following lines can be replaced by a single call
' ACsc = ASin(1 / value)
If Abs(Value) <> 1 Then
ACsc = Atn((1 / Value) / Sqr(1 - 1 / (Value * Value)))
Else
ACsc = 1.5707963267949 * Sgn(Value)
End If
End Function

'----------------------------
Public Function Atn2(Y As Double, X As Double) As Double
'Arctangent of 2 values (lat/long)
If X > 0 Then
Atn2 = Atn(Y / X)
ElseIf X < 0 Then
Atn2 = Sgn(Y) * (Pi - Atn(Abs(Y / X)))
ElseIf Y = 0 Then
Atn2 = 0
Else
Atn2 = Sgn(Y) * Pi / 2
End If
End Function

I hope these trig functions will be useful to other developers

Colin Riddington           Mendip Data Systems                 Last Updated 20 May 2022 