Skip to main content

Trigonometric Functions

HelixQL provides a comprehensive set of trigonometric functions for angular calculations, including standard trigonometric functions (sine, cosine, tangent) and their inverse counterparts, essential for geospatial calculations, physics simulations, and angular measurements.

Available Functions

SIN - Sine

SIN(x)  // Returns sin(x)
Returns the sine of an angle in radians.

COS - Cosine

COS(x)  // Returns cos(x)
Returns the cosine of an angle in radians.

TAN - Tangent

TAN(x)  // Returns tan(x)
Returns the tangent of an angle in radians.

ASIN - Arcsine

ASIN(x)  // Returns arcsin(x)
Returns the arcsine (inverse sine) of x in radians. Domain: [-1, 1].

ACOS - Arccosine

ACOS(x)  // Returns arccos(x)
Returns the arccosine (inverse cosine) of x in radians. Domain: [-1, 1].

ATAN - Arctangent

ATAN(x)  // Returns arctan(x)
Returns the arctangent (inverse tangent) of x in radians.

ATAN2 - Two-Argument Arctangent

ATAN2(y, x)  // Returns atan2(y, x)
Returns the angle in radians between the positive x-axis and the point (x, y). This function handles all quadrants correctly and is commonly used for angle calculations.
When using the SDKs or curling the endpoint, the query name must match what is defined in the queries.hx file exactly.

Example 1: Geospatial bearing calculations

Calculate the bearing (direction) between geographic coordinates:
QUERY CalculateBearings() =>
    locations <- N::Location
        ::{
            name, latitude, longitude,
            radians_lat: MUL(_::{latitude}, DIV(PI(), 180.0)),
            radians_lon: MUL(_::{longitude}, DIV(PI(), 180.0)),
            sin_lat: SIN(MUL(_::{latitude}, DIV(PI(), 180.0))),
            cos_lat: COS(MUL(_::{latitude}, DIV(PI(), 180.0))),
            tan_lat: TAN(MUL(_::{latitude}, DIV(PI(), 180.0)))
        }
    RETURN locations

QUERY CreateLocation(name: String, latitude: F64, longitude: F64) =>
    location <- AddN<Location>({ name: name, latitude: latitude, longitude: longitude })
    RETURN location
Here’s how to run the query using the SDKs or curl
from helix.client import Client

client = Client(local=True, port=6969)

# Create locations with geographic coordinates
locations = [
    {"name": "New York", "latitude": 40.7128, "longitude": -74.0060},
    {"name": "London", "latitude": 51.5074, "longitude": -0.1278},
    {"name": "Tokyo", "latitude": 35.6762, "longitude": 139.6503},
]

for location in locations:
    client.query("CreateLocation", location)

result = client.query("CalculateBearings", {})
print("Location bearings:", result)

Example 2: Angle calculations with ATAN2

Use ATAN2 to calculate angles between vectors and points:
QUERY CalculateAngles() =>
    vectors <- N::Vector
        ::{
            x, y,
            angle_radians: ATAN2(_::{y}, _::{x}),
            angle_degrees: MUL(ATAN2(_::{y}, _::{x}), DIV(180.0, PI()))
        }
    RETURN vectors

QUERY CreateVector(x: F64, y: F64) =>
    vector <- AddN<Vector>({ x: x, y: y })
    RETURN vector
Here’s how to run the query using the SDKs or curl
from helix.client import Client

client = Client(local=True, port=6969)

# Create vectors in different quadrants
vectors = [
    {"x": 1.0, "y": 1.0},      # 45 degrees
    {"x": -1.0, "y": 1.0},     # 135 degrees
    {"x": -1.0, "y": -1.0},    # -135 degrees
    {"x": 1.0, "y": -1.0},     # -45 degrees
]

for vector in vectors:
    client.query("CreateVector", vector)

result = client.query("CalculateAngles", {})
print("Vector angles:", result)

Example 3: Inverse trigonometric functions

Use inverse trigonometric functions to recover angles from ratios:
QUERY RecoverAngles() =>
    measurements <- N::Measurement
        ::{
            ratio,
            angle_from_sin: ASIN(_::{ratio}),
            angle_from_cos: ACOS(_::{ratio}),
            angle_from_tan: ATAN(_::{ratio})
        }
    RETURN measurements

QUERY CreateMeasurement(ratio: F64) =>
    measurement <- AddN<Measurement>({ ratio: ratio })
    RETURN measurement
Here’s how to run the query using the SDKs or curl
from helix.client import Client

client = Client(local=True, port=6969)

# Create measurements with various ratios
ratios = [0.0, 0.5, 0.707, 0.866, 1.0]

for ratio in ratios:
    client.query("CreateMeasurement", {"ratio": ratio})

result = client.query("RecoverAngles", {})
print("Recovered angles:", result)

Radians vs Degrees

All trigonometric functions in HelixQL work with radians. To convert between degrees and radians:
// Degrees to radians
radians = MUL(degrees, DIV(PI(), 180.0))

// Radians to degrees
degrees = MUL(radians, DIV(180.0, PI()))
Use the PI() constant function for accurate conversion between degrees and radians.

Domain Restrictions

Inverse trigonometric functions have domain restrictions:
  • ASIN(x), ACOS(x): x must be in [-1, 1]
  • ATAN(x): accepts all real numbers
  • ATAN2(y, x): accepts all real numbers for both arguments

ATAN2 vs ATAN

ATAN2 is preferred over ATAN for angle calculations because:
  • It handles all four quadrants correctly
  • It avoids division by zero when x = 0
  • It returns values in the full range [-Ï€, Ï€]
// ATAN2 correctly handles all quadrants
ATAN2(1.0, 1.0)    // π/4 (first quadrant)
ATAN2(1.0, -1.0)   // 3Ï€/4 (second quadrant)
ATAN2(-1.0, -1.0)  // -3Ï€/4 (third quadrant)
ATAN2(-1.0, 1.0)   // -Ï€/4 (fourth quadrant)

Use in Geospatial Calculations

Trigonometric functions are essential for geospatial calculations:
// Calculate great circle distance (Haversine formula)
QUERY CalculateDistance(lat1: F64, lon1: F64, lat2: F64, lon2: F64) =>
    dlat <- SUB(lat2, lat1)
    dlon <- SUB(lon2, lon1)
    a <- ADD(
        POW(SIN(DIV(dlat, 2.0)), 2.0),
        MUL(MUL(COS(lat1), COS(lat2)), POW(SIN(DIV(dlon, 2.0)), 2.0))
    )
    c <- MUL(2.0, ATAN2(SQRT(a), SQRT(SUB(1.0, a))))
    distance <- MUL(6371.0, c)  // Earth radius in km
    RETURN distance