BlitzMax

BlitzMax

  • Downloads
  • Docs
  • API
  • Resources
  • About

›BRL

BlitzMax API

  • Introduction

BRL

    Audio

    • Introduction
    • TChannel
    • TSound

    AudioSample

    • Introduction
    • TAudioSample
    • TAudioSampleLoader

    Bank

    • Introduction
    • TBank

    BankStream

    • Introduction
    • TBankStream

    Base64

    • Introduction
    • TBase64

    Blitz

    • Introduction
    • TArrayBoundsException
    • TBlitzException
    • TNullFunctionException
    • TNullMethodException
    • TNullObjectException
    • TOutOfDataException
    • TRuntimeException
  • BRL.BMPLoader
  • Clipboard

    • Introduction
    • TClipboard
    • TClipboardOpts
    • TWin32ClipboardOpts
    • TX11ClipboardOpts
  • BRL.D3D7Max2D
  • BRL.D3D9Max2D
  • BRL.DirectSoundAudio
  • BRL.EndianStream
  • Event

    • Introduction
    • TEvent
  • BRL.EventQueue
  • BRL.FileSystem
  • BRL.FreeAudioAudio
  • BRL.GLGraphics
  • BRL.GLMax2D
  • BRL.GNet
  • BRL.Graphics
  • BRL.Hook
  • BRL.JPGLoader
  • BRL.KeyCodes
  • LinkedList

    • Introduction
    • TList
    • TListEnum
    • TLink

    Map

    • Introduction
    • TMap
    • TIntMap
    • TIntKey
    • TPtrMap
    • TPtrKey
    • TStringMap
  • BRL.Math
  • Matrix

    • Introduction
    • SMat2D
    • SMat2F
    • SMat2I
    • SMat3D
    • SMat3F
    • SMat3I
    • SMat4D
    • SMat4F
    • SMat4I

    Max2D

    • Introduction
    • TImage

    MaxLua

    • Introduction
    • TLuaClass
    • TLuaObject
  • BRL.OGGLoader
  • BRL.OpenALAudio
  • ObjectList

    • Introduction
    • TObjectList
    • TObjectListEnumerator
    • TObjectListReverseEnumerator

    Pixmap

    • Introduction
    • TPixmap
    • TPixmapLoader
  • BRL.PNGLoader
  • BRL.PolledInput
  • Quaternion

    • Introduction
    • SQuatD
    • SQuatF
    • SQuatI
  • BRL.RamStream
  • Random

    • Introduction
    • TRandom

    Reflection

    • Introduction
    • TTypeId
    • TMember
    • TConstant
    • TField
    • TGlobal
    • TFunction
    • TMethod
  • BRL.Retro
  • BRL.Socket
  • BRL.SocketStream
  • BRL.StandardIO
  • Stream

    • Introduction
    • TCStream
    • TIO
    • TStream
    • TStreamException
    • TStreamFactory
    • TStreamReadException
    • TStreamWrapper
    • TStreamWriteException

    StringBuilder

    • Introduction
    • TStringBuilder
    • TSplitBuffer
  • BRL.System
  • BRL.SystemDefault
  • BRL.TextStream
  • BRL.TGALoader
  • ThreadPool

    • Introduction
    • TRunnable
    • TThreadPoolExecutor

    Threads

    • Introduction
    • TThread
    • TThreadData
    • TMutex
    • TSemaphore
    • TCondVar

    Timer

    • Introduction
    • TChrono
  • BRL.TimerDefault
  • Vector

    • Introduction
    • SVec2D
    • SVec2F
    • SVec2I
    • SVec3D
    • SVec3F
    • SVec3I

    Volumes

    • Introduction
    • TVolume
  • BRL.WAVLoader

Text

    Format

    • Introduction
    • TFormatter

    JConv

    • Introduction
    • TJConv
    • TJConvBuilder
    • TJConvSerializer

    Json

    • Introduction
    • TJSON
    • TJSONObject
    • TJSONString
    • TJSONInteger
    • TJSONReal
    • TJSONBool
    • TJSONArray
    • TJSONNull
    • TJSONError
    • TJSONNumber

    Regex

    • Introduction
    • TRegEx
    • TRegExMatch
    • TRegExOptions
    • TRegExException

    Xml

    • Introduction
    • TxmlDoc
    • TxmlNode
    • TxmlAttribute

MaxGUI

  • MaxGUI.MaxGUI
  • MaxGUI.Drivers
  • MaxGUI.Localization
  • MaxGUI.ProxyGadgets
  • MaxGUI.CocoaMaxGUI
  • MaxGUI.Win32MaxGUIEx

PUB

  • Pub.FreeJoy
  • Pub.FreeProcess
  • Pub.Glad
  • Pub.Glew
  • Joystick

    • Introduction
    • TJoystickDriver
  • Pub.Lua
  • Pub.OpenAL
  • Pub.OpenGLES
  • Pub.xmmintrin
  • Pub.ZLib

Crypto

    Digest

    • Introduction
    • TMessageDigest
    • TDigestRegister
    • TNoSuchAlgorithmException

    Cipher

    • Introduction
    • TCipher
    • TCipherMode
    • Crypto.AESCipher
    • Crypto.AnubisCipher
    • Crypto.BlowfishCipher
    • Crypto.CamelliaCipher
    • Crypto.Cast5Cipher
    • Crypto.DESCipher
    • Crypto.IdeaCipher
    • Crypto.KasumiCipher
    • Crypto.KhazadCipher
    • Crypto.KSeedCipher
    • Crypto.NoekeonCipher
    • Crypto.SerpentCipher
    • Crypto.SkipjackCipher
    • Crypto.TwofishCipher
    • Crypto.XTeaCipher

    CBCMode

    • Introduction
    • TCBCCipherMode

    CFBMode

    • Introduction
    • TCFBCipherMode

    CTRMode

    • Introduction
    • TCTRCipherMode

    ECBMode

    • Introduction
    • TECBCipherMode

    F8Mode

    • Introduction
    • TF8CipherMode

    LRWMode

    • Introduction
    • TLRWCipherMode

    OFBMode

    • Introduction
    • TOFBCipherMode

    XTSMode

    • Introduction
    • TXTSCipherMode

    Blake2BDigest

    • Introduction
    • TBlake2B_512
    • TBlake2B_384
    • TBlake2B_256
    • TBlake2B_160

    CRC32

    • Introduction
    • TCRC32

    MD5Digest

    • Introduction
    • TMD5

    Ripemd320Digest

    • Introduction
    • TRipemd320

    Ripemd356Digest

    • Introduction
    • TRipemd256

    Ripemd160Digest

    • Introduction
    • TRipemd160

    Ripemd128Digest

    • Introduction
    • TRipemd128

    SHA1Digest

    • Introduction
    • TSHA1

    SHA256Digest

    • Introduction
    • TSHA256

    SHA512Digest

    • Introduction
    • TSHA512

    SHA3Digest

    • Introduction
    • TSHA3_512
    • TSHA3_384
    • TSHA3_256
    • TSHA3_224

    TigerDigest

    • Introduction
    • TTiger

    WhirlpoolDigest

    • Introduction
    • TWhirlpool

    Crypto

    • Introduction
    • TCryptoRandom
    • TCryptoSecretBox
    • TCryptoHash
    • TCryptoSign
    • TCryptoKeyExchange
    • TCryptoKey
    • TCryptoHashKey
    • TCryptoSecretBoxKey
    • TCryptoSignature
    • TCryptoExchangeKeyPair
    • TCryptoSessionKeyPair
    • TCryptoNPacket
    • TCryptoKK1Packet
    • TCryptoKK2Packet
    • TCryptoXX1Packet
    • TCryptoXX2Packet
    • TCryptoXX3Packet
    • TCryptoExchangeState
    • TCryptoPWHashMasterKey
    • TCryptoPWHashStoredKey
    • TCryptoPasswordHash

SDL

    SDL

    • Introduction
    • TSDLStream

    SDLSystem

    • Introduction
    • TSDLMultiGesture

    SDLVideo

    • Introduction
    • TSDLDisplay
    • TSDLDisplayMode
    • TSDLGLContext
    • TSDLWindow

    SDLRender

    • Introduction
    • TSDLRenderer
    • TSDLTexture

    SDLTimer

    • Introduction
    • TSDLTimer

    SDLHaptic

    • Introduction
    • TSDLHaptic
    • TSDLHapticCondition
    • TSDLHapticConstant
    • TSDLHapticCustom
    • TSDLHapticDirection
    • TSDLHapticEffect
    • TSDLHapticLeftRight
    • TSDLHapticPeriodic
    • TSDLHapticRamp

    SDLSensor

    • Introduction
    • TSDLSensor
  • SDL.SDLFreeAudio
  • SDL.GLSDLMax2D
  • SDL.GL2SDLMax2D
  • SDL.D3D9SDLMax2D
  • SDLVirtualJoystick

    • Introduction
    • TVirtualJoystick

Steam

    SteamSDK

    • Introduction
    • TSteamClient
    • TSteamUtils
    • TSteamUserStats
    • TSteamFriends
    • TSteamUGC
    • ISteamFriendsListener
    • ISteamUGCListener
    • ISteamUserStatsListener
    • ISteamUtilsListener
    • EItemPreviewType
    • EPersonaChange
    • EPersonaState
    • ERemoteStoragePublishedFileVisibility
    • EUGCMatchingUGCType
    • EUGCQuery
    • EUserRestriction
    • EUserUGCList
    • EWorkshopFileType
Edit

BRL.Math

Functions

Function IsNan:Int( x:Double )

Check if a value is NAN

Returns

True if x is 'not a number' (eg: Sqr(-1))

Example 1

SuperStrict

For Local f:Float=-0.4 Until 0.4 Step 0.2
    If IsNan(Sqr(f)) Then
       Print "Square Root of "+f+" is not a real number"
    Else
       Print "Square Root of  "+f+" = "+Sqr(f)
    EndIf
Next

' ===================
' Output
' Square Root of -0.400000006 is not a real number
' Square Root of -0.200000003 is not a real number
' Square Root of  0.000000000 = 0.00000000000000000
' Square Root of  0.200000003 = 0.44721359883195888

Example 2

SuperStrict

For Local f:Float = - 0.4 Until 0.4 Step 0.2
    If IsInf(Log(f) ) Then
        Print "Log(" + f + ")=Infinity "+Log(f)
    Else If IsNan(Log(f) ) Then
        Print "Log(" + f + ") is not a real number "+Log(f)
    Else
        Print "Log(" + f + ")=" + Log(f) 
   End If
Next

' ===================
' Output
' Log(-0.400000006) is not a real number -1.#IND000000000000
' Log(-0.200000003) is not a real number -1.#IND000000000000
' Log(0.000000000)=Infinity -1.#INF000000000000
' Log(0.200000003)=-1.6094378975329393


Function IsInf:Int( x:Double )

Check if a value is infinite (eg: 1.0/0.0)

Returns

True if x is infinite

Example 1

SuperStrict

For Local f:Float=-0.4 Until 0.4 Step 0.2
    If IsInf(1.0 / f) Then
       Print "Divide by Zero"
    Else
       Print "inverse of "+f+" = "+String(1.0/f)
    EndIf
Next

' ===================
' Output
' inverse of -0.400000006 = -2.50000000
' inverse of -0.200000003 = -5.00000000
' Divide by Zero
' inverse of 0.200000003 = 5.00000000

Example 2

SuperStrict

For Local f:Float = - 0.4 Until 0.4 Step 0.2
    If IsInf(Log(f) ) Then
        Print "Log(" + f + ")=Infinity "+Log(f)
    Else If IsNan(Log(f) ) Then
        Print "Log(" + f + ") is not a real number "+Log(f)
    Else
        Print "Log(" + f + ")=" + Log(f) 
   End If
Next

' ===================
' Output
' Log(-0.400000006) is not a real number -1.#IND000000000000
' Log(-0.200000003) is not a real number -1.#IND000000000000
' Log(0.000000000)=Infinity -1.#INF000000000000
' Log(0.200000003)=-1.6094378975329393


Function Sqr:Double( x:Double )

Square root of x

Example

'IsNan (Not a Number)
SuperStrict

For Local f:Float=-0.4 Until 0.4 Step 0.2
    If IsNan(Sqr(f)) = True Then
       Print "Square Root of "+f+" is not a real number"
    Else
       Print "Square Root of  "+f+" = "+Sqr(f)
    EndIf
Next

' ===================
' Output
' Square Root of -0.400000006 is not a real number
' Square Root of -0.200000003 is not a real number
' Square Root of  0.000000000 = 0.00000000000000000
' Square Root of  0.200000003 = 0.44721359883195888


Function Sin:Double( x:Double )

Sine of x degrees

Example 1

Rem
Sin:Double( x:Double )
End Rem

SuperStrict

For Local d:Int = 0 To 360 Step 45
    Print "Sin("+d+")="+Sin(d)
Next

Example 2

SuperStrict

Graphics 640,480

SetColor 128,128,128
DrawRect 0,240,360,1

SetColor 0,255,255

For Local t:Int=0 To 359
    Plot t,Float(240+Sin(t)*80)
Next

Flip

Repeat
    WaitKey()
Until KeyDown(KEY_ESCAPE)

Example 3

SuperStrict

Graphics 640,480

Local radius:Int=80

SetColor 0,255,255

For Local t:Int=0 To 359 Step 4
    Plot Float(320+Sin(t)*radius), Float(240+Cos(t)*radius)
Next

Flip

Repeat
    WaitKey()
Until KeyDown(KEY_ESCAPE)


Function Cos:Double( x:Double )

Cosine of x degrees

Example 1

Rem
Cosine of x
End Rem

SuperStrict

For Local d:Int = 0 To 360 Step 45
    Print "Cos("+d+")="+Cos(d)
Next

Example 2

SuperStrict

Graphics 640,480

SetColor 128,128,128
DrawRect 0,240,360,1

SetColor 0,255,255

For Local t:Int=0 To 359
    Plot t,Float(240+Cos(t)*80)
Next

Flip

Repeat
    WaitKey()
Until KeyDown(KEY_ESCAPE)

Example 3

'
' How to draw a 'dotted' flower using Sin/Cos
'
SuperStrict

Graphics 640,480

Local radius:Int

SetColor 0,255,255

For Local t:Int=0 To 359 Step 4
    radius=Sin(t*8)*40+80
    Plot Float(320+Sin(t)*radius), Float(240+Cos(t)*radius)
Next

Flip

Repeat
    WaitKey()
Until KeyDown(KEY_ESCAPE)


Function Tan:Double( x:Double )

Tangent of x degrees

Example

Rem
Tangent of x degrees
End Rem

SuperStrict

For Local d:Int = 0 To 360 Step 45
    Print "Tan("+d+")="+Float(Tan(d))
Next


Function ASin:Double( x:Double )

Inverse Sine of x

Example

Rem
Inverse Sine of x
End Rem

SuperStrict

For Local d:Double = -1.0 To 1.0 Step 0.125
    Print "ASin("+d+")="+ASin(d)
Next


Function ACos:Double( x:Double )

Inverse Cosine of x

Example

Rem
Inverse Cosine of x
End Rem

SuperStrict

For Local d:Double = -1.0 To 1.0 Step 0.125
    Print "ACos("+d+")="+ACos(d)
Next


Function ATan:Double( x:Double )

Inverse Tangent of x

Example

Rem
ATan returns the Inverse Tangent of x
End Rem

SuperStrict

For Local d:Double = -1.0 To 1.0 Step 0.125
    Print "ATan("+d+")="+ATan(d)
Next


Function ATan2:Double( y:Double,x:Double )

Inverse Tangent of two variables x , y

Example 1

Rem
ATan2 returns the Inverse Tangent of two variables
End Rem

SuperStrict

Function Angle:Double(x0:Double,y0:Double,x1:Double,y1:Double)
    Return ATan2(y1-y0,x1-x0)
End Function

Graphics 640,480
While Not KeyHit(KEY_ESCAPE)
    Cls
    Local x:Float = MouseX()
    Local y:Float = MouseY()
    DrawLine 320,240,x,y
    DrawText "Angle="+Angle(320,240,x,y),20,20
    Flip
Wend

Example 2

'
' ATan2
'
' returns the angle in degrees between two points by giving the width and height between then.
'
SuperStrict

Print ATan2(4,4)
'4^|    / (45 degrees)
'  |   / 
'  |  /
'  | /
'  |/
'  +-----
'       4>


Function Sinh:Double( x:Double )

Hyperbolic sine of x

Example

'
' Sinh Hyperbolic Sine
'
SuperStrict

Graphics 640,480

For Local t:Float=-7To 7 Step .1
    Plot 100+t*10,Float(240+Sinh(t))
Next

Flip

Repeat Until KeyDown(KEY_ESCAPE) Or AppTerminate()


Function Cosh:Double( x:Double )

Hyperbolic cosine of x

Example

'
' Cosh Hyperbolic Cosine
'
SuperStrict

Graphics 640,480

For Local t:Float = - 7To 7 Step .1
    SetColor 255,0,0 'red cosh
    Plot 100 + t * 10 , Float(240 + Cosh(t))
    SetColor 0,255,255 
    Plot 200 + t * 10 , Float(240 + Sinh(t))
Next

Flip

Repeat Until KeyDown(KEY_ESCAPE) Or AppTerminate()


Function Tanh:Double( x:Double )

Hyperbolic tangent of x

Example

'
' Tanh Hyperbolic Cosine
'
SuperStrict

Graphics 640,480

For Local t:Float = -.2 To .2 Step .001
    SetColor 255,0,0 'red cosh
    Plot 100 + t * 500 , Float(240 + Tanh(t)*500)
Print t*500+":"+Tanh(t)*500
Next

Flip

Repeat Until KeyDown(KEY_ESCAPE) Or AppTerminate()


Function Exp:Double( x:Double )

Exponential function

Example

'
' Exponential
'
SuperStrict

Graphics 640,480

For Local t:Float = - 7 To 7 Step .1
    Plot 100 + t * 10 , Float(240 - Exp(t))
    Print Exp(t)
Next

Flip

Repeat Until KeyDown(KEY_ESCAPE) Or AppTerminate()


Function Log:Double( x:Double )

Natural logarithm

Example

Rem
Log(n#) returns the natural logarithm of n
End Rem

SuperStrict

For n:Float = 1 To 20
    Print "Log("+n+")="+Log(n)
Next


Function Log10:Double( x:Double )

Base 10 logarithm

Example

Rem
Log10(n#) returns the Base 10 logarithm of n
End Rem

SuperStrict

For Local n:Float = 0 To 100 Step 10
    Print "Log10("+n+")="+Log10(n)
Next


Function Ceil:Double( x:Double )

Smallest integral value not less than x

Example 1

Rem
Ceil(x#) returns the smallest integral value not less than x
End Rem

SuperStrict

For Local i:Float = -1 To 1 Step .2
    Print "Ceil("+i+")="+Ceil(i)
Next

Example 2

SuperStrict

Graphics 640,480

Local x:Int,y:Int
Local mx:Int,my:Int

HideMouse
Repeat
    mx=MouseX()
    my=MouseY()
    
    Cls
    ' draw grid
    SetColor 90,90,90
    For y=0 Until 480 Step 20
        For x=0 Until 640 Step 20
            Plot x,y
        Next
    Next
    
    'draw mouse mx,my
    SetColor 255,255,255
    DrawRect mx-1,my-1,3,3
    
    ' draw ceiled and floored mouse mx,my
    SetColor 255,255,0
    DrawRect Float(Ceil( mx/20.0)*20-1),Float(Ceil(my/20.0)*20-1),3,3
    
    SetColor 0,255,255
    DrawRect Float(Floor(mx/20.0)*20-1),Float(Floor( my/20.0)*20-1),3,3
    
    Flip
    
Until KeyDown(KEY_ESCAPE)


Function Floor:Double( x:Double )

Largest integral value not greater than x

Example 1

Rem
Floor(x!) returns the largest integral value not greater than x
End Rem

SuperStrict

For Local i:Double = -1 To 1 Step .2
    Print "Floor("+i+")="+Floor(i)
Next

Example 2

SuperStrict

Graphics 640,480

Local x:Int,y:Int
Local mx:Int,my:Int

HideMouse
Repeat
    mx=MouseX()
    my=MouseY()
    
    Cls
    ' draw grid
    SetColor 90,90,90
    For y=0 Until 480 Step 20
        For x=0 Until 640 Step 20
            Plot x,y
        Next
    Next
    
    'draw mouse mx,my
    SetColor 255,255,255
    DrawRect mx-1,my-1,3,3
    
    ' draw ceiled and floored mouse mx,my
    SetColor 255,255,0
    DrawRect Float(Ceil( mx/20.0)*20-1),Float(Ceil(my/20.0)*20-1),3,3
    
    SetColor 0,255,255
    DrawRect Float(Floor(mx/20.0)*20-1),Float(Floor( my/20.0)*20-1),3,3
    
    Flip
    
Until KeyDown(KEY_ESCAPE)


Function Round:Double( x:Double )

Nearest integral value to x.

Example

Rem
Nearest integral value to x
End Rem
SuperStrict

Framework brl.standardio
Import brl.math

Print "Round(+2.3) = " + Round(2.3)
Print "Round(+2.5) = " + Round(2.5)
Print "Round(+2.7) = " + round(2.7)
Print ""

Print "Round(-2.3) = " + Round(-2.3)
Print "Round(-2.5) = " + Round(-2.5)
Print "Round(-2.7) = " + Round(-2.7)

Print "Round(-0.0) = " + Round(-0.0)


Function Trunc:Double( x:Double )

Nearest integral not greater in magnitude than x.

Example

Rem
Nearest integral not greater in magnitude than x
End Rem
SuperStrict

Framework brl.standardio
Import brl.math

Print "Trunc(+2.7) = " + Trunc(2.7)
Print "Trunc(-2.7) = " + Trunc(-2.7)
Print "Trunc(-0.0) = " + Trunc(-0.0)


Function SqrF:Float( x:Float )

Square root of x


Function SinF:Float( x:Float )

Sine of x degrees


Function CosF:Float( x:Float )

Cosine of x degrees


Function TanF:Float( x:Float )

Tangent of x degrees


Function ASinF:Float( x:Float )

Inverse Sine of x


Function ACosF:Float( x:Float )

Inverse Cosine of x


Function ATanF:Float( x:Float )

Inverse Tangent of x


Function ATan2F:Float( y:Float,x:Float )

Inverse Tangent of two variables x , y


Function SinhF:Float( x:Float )

Hyperbolic sine of x


Function CoshF:Float( x:Float )

Hyperbolic cosine of x


Function TanhF:Float( x:Float )

Hyperbolic tangent of x


Function ExpF:Float( x:Float )

Exponential function


Function LogF:Float( x:Float )

Natural logarithm


Function Log10F:Float( x:Float )

Base 10 logarithm


Function CeilF:Float( x:Float )

Smallest integral value not less than x


Function FloorF:Float( x:Float )

Largest integral value not greater than x


Function RoundF:Float( x:Float )

Nearest integral value to x.


Function TruncF:Float( x:Float )

Nearest integral not greater in magnitude than x.


← TStringMapIntroduction →
  • Functions
    • Function IsNan:Int( x:Double )
    • Function IsInf:Int( x:Double )
    • Function Sqr:Double( x:Double )
    • Function Sin:Double( x:Double )
    • Function Cos:Double( x:Double )
    • Function Tan:Double( x:Double )
    • Function ASin:Double( x:Double )
    • Function ACos:Double( x:Double )
    • Function ATan:Double( x:Double )
    • Function ATan2:Double( y:Double,x:Double )
    • Function Sinh:Double( x:Double )
    • Function Cosh:Double( x:Double )
    • Function Tanh:Double( x:Double )
    • Function Exp:Double( x:Double )
    • Function Log:Double( x:Double )
    • Function Log10:Double( x:Double )
    • Function Ceil:Double( x:Double )
    • Function Floor:Double( x:Double )
    • Function Round:Double( x:Double )
    • Function Trunc:Double( x:Double )
    • Function SqrF:Float( x:Float )
    • Function SinF:Float( x:Float )
    • Function CosF:Float( x:Float )
    • Function TanF:Float( x:Float )
    • Function ASinF:Float( x:Float )
    • Function ACosF:Float( x:Float )
    • Function ATanF:Float( x:Float )
    • Function ATan2F:Float( y:Float,x:Float )
    • Function SinhF:Float( x:Float )
    • Function CoshF:Float( x:Float )
    • Function TanhF:Float( x:Float )
    • Function ExpF:Float( x:Float )
    • Function LogF:Float( x:Float )
    • Function Log10F:Float( x:Float )
    • Function CeilF:Float( x:Float )
    • Function FloorF:Float( x:Float )
    • Function RoundF:Float( x:Float )
    • Function TruncF:Float( x:Float )
BlitzMax
Docs
Getting StartedDownloadsAbout
Community
ResourcesSyntaxBomb Forums
More
GitHubStarChat on Discord
Copyright © 2022 Bruce A Henderson