---
name: "Position"
type: topic
aliases: ["Position2D", "Position3D", "PositionAGL", "PositionAGLS", "PositionASL", "PositionASLW", "PositionATL", "PositionConfig", "PositionRelative", "PositionWorld"]
source: https://community.bistudio.com/wiki/Position
revid: 364535
updated: 2024-05-16T20:46:45Z
---

# Position

Positions in Arma games are always represented as [arrays](../topics/Array.md). There are two types of positions:
- 2D position: `[X, Y]`
- 3D position: `[X, Y, Z]`

On the map and on the terrain, the X-axis runs from west to east and the Y-axis runs from south to north. The origin `[0, 0]` is (usually) located in the bottom left corner.

While the Z-coordinate is always the height/altitude, the point relative to which that height is measured depends on the specific position format (see [#Types](../topics/Position.md#types) below).

> [!NOTE]
> **Arma 3:** Since Arma 3 v1.94: X, Y and Z are limited to values between -50km and +500km. Using any **setPos*** command with values greater than that will [clamp](https://en.wikipedia.org/wiki/Clamping_(graphics)) the value to within these boundaries, not throwing any errors. e.g:
>
> ```sqf
> player setPosASL [-50001, 500001, 500001]; // player will be set to [-50000, 500000, 500000]
> ```

### Commands

See:
- Command Group: Positions
- Command Group: Render Time Scope

### Types

There are a number of formats available in Real Virtuality:

|  |  |
|---|---|
| **ASL:** | Presumably "**A**bove **S**ea **L**evel" |
| **ATL:** | Presumably "**A**bove **T**errain **L**evel" |
| **ASLW:** | Presumably "**A**bove **S**ea **L**evel including **W**aves" |
| **AGL:** | Presumably "**A**bove **G**eneric/**G**round **L**evel" |
| **AGLS:** | Presumably "**A**bove **G**eneric/**G**round **L**evel including **S**urfaces" |
| **World:** | Raw world coordinate system |
| **Relative:** | Position relative to an object within its model space |
| **Config:** | Position used in configs |
| **Object:** | When object is used for position, [PositionWorld](../topics/Position.md#positionworld) of the object is used |
| **Visual:** | Used for rendering objects on the screen. Useful for per-frame applications, such as [drawIcon3D](../commands/drawIcon3D.md) - see Command Group: Render Time Scope and Simulation vs Render Time Scope. |

> [!IMPORTANT]
> Note that the only **absolute position format** in Arma for 3D calculations is the ASL format. Always pay attention to this fact when performing 3D calculations. For example, when a unit is climbing a mountain, the Z in ATL format is **always 0**. The following example demonstrates this behavior:
>
> Let's say it is desired to see if there is an intersection between two horizontal positions:
>
> ```sqf
> private _pos1 = getPosATL _unit;
> private _pos2 = _pos1 vectorAdd [0,200,0]; // make a horizontal line by shifting the y, so z remains the same
> private _intersects = lineIntersects [ATLToASL _pos1, ATLToASL _pos2]; // lineIntersects needs ASL, so we just convert _pos1 and _pos2 to ASL...
> ```
>
> However, this is incorrect. ATL is a relative format, and while the ATL height between the coordinates is the same, the ASL height might not be (think of the mountain example again).
>
> This is the correct way to write the above code:
>
> ```sqf
> private _pos1 = getPosASL _unit;
> private _pos2 = _pos1 vectorAdd [0,200,0]; // make a horizontal line by shifting the y
> private _intersects = lineIntersects [_pos1, _pos2];
> ```

#### Position2D

This array only has two elements and is usually used with 2D information, for example standard markers or UI commands. If used with e.g [distance](../commands/distance.md), Z is assumed to be 0.

#### PositionASL

Z is measured from the sea level which is constant across the map.

**See also:**
[getPosASL](../commands/getPosASL.md), [setPosASL](../commands/setPosASL.md), [getPosASLVisual](../commands/getPosASLVisual.md), [visiblePositionASL](../commands/visiblePositionASL.md), [ASLToATL](../commands/ASLToATL.md), [ATLToASL](../commands/ATLToASL.md), [AGLToASL](../commands/AGLToASL.md), [ASLToAGL](../commands/ASLToAGL.md), [eyePos](../commands/eyePos.md), [aimPos](../commands/aimPos.md), [getTerrainHeightASL](../commands/getTerrainHeightASL.md), [lineIntersects](../commands/lineIntersects.md), [lineIntersectsWith](../commands/lineIntersectsWith.md), [lineIntersectsObjs](../commands/lineIntersectsObjs.md), [lineIntersectsSurfaces](../commands/lineIntersectsSurfaces.md), [terrainIntersectASL](../commands/terrainIntersectASL.md), [playSound3D](../commands/playSound3D.md), [setDefaultCamera](../commands/setDefaultCamera.md)

#### PositionASLW

Z is measured from the surface of water at that position. Both waves and pond objects affect the result.

**See also:**
[getPosASLW](../commands/getPosASLW.md), [setPosASLW](../commands/setPosASLW.md)

#### PositionATL

Z is measured from the terrain level which varies across the map.

**See also:**
[getPosATL](../commands/getPosATL.md), [setPosATL](../commands/setPosATL.md), [getPosATLVisual](../commands/getPosATLVisual.md), [ASLToATL](../commands/ASLToATL.md), [ATLToASL](../commands/ATLToASL.md)

#### PositionAGL

Z is the same as in [PositionASLW](../topics/Position.md#positionaslw) when over sea and is the same as in [PositionATL](../topics/Position.md#positionatl) when over land. Most commands either take or return [PositionAGL](../topics/Position.md#positionagl).

**See also:**
[modelToWorld](../commands/modelToWorld.md), [worldToModel](../commands/worldToModel.md), [modelToWorldVisual](../commands/modelToWorldVisual.md), [worldToModelVisual](../commands/worldToModelVisual.md), [positionCameraToWorld](../commands/positionCameraToWorld.md), [intersect](../commands/intersect.md), [terrainIntersect](../commands/terrainIntersect.md), [isOnRoad](../commands/isOnRoad.md), [drawIcon3D](../commands/drawIcon3D.md), [drawLine3D](../commands/drawLine3D.md), [distance](../commands/distance.md), [moveTo](../commands/moveTo.md), [doMove](../commands/doMove.md), [move](../commands/move.md), [setDestination](../commands/setDestination.md), [buildingPos](../commands/buildingPos.md), [screenToWorld](../commands/screenToWorld.md), [worldToScreen](../commands/worldToScreen.md), [AGLToASL](../commands/AGLToASL.md), [ASLToAGL](../commands/ASLToAGL.md), [unitAimPosition](../commands/unitAimPosition.md), [unitAimPositionVisual](../commands/unitAimPositionVisual.md)

#### PositionAGLS

Over land, Z is measured as height over terrain level minus the height of surface over terrain level underneath. If such surface exists and is counted in, the resulting Z becomes 0.

Over sea it gets even more complicated as instead of [PositionATL](../topics/Position.md#positionatl), [PositionASLW](../topics/Position.md#positionaslw) is used minus the offset for the surface height, presumably over waves too, as Z seems static. As there is currently no way to obtain Hsurface, it becomes impossible to convert given [PositionAGLS](../topics/Position.md#positionagls) into other formats, unlike with other position formats.

**See also:**
[position](../commands/position.md), [visiblePosition](../commands/visiblePosition.md), [getPos](../commands/getPos.md), [getPosVisual](../commands/getPosVisual.md)

##### setPosAGLS

The function below will place passed object onto walkable surface, if there is one, otherwise on the ground. If only X and Y of the position are supplied, the object will be placed on surface, if Z is supplied, it will be treated as offset from the surface level.

```sqf
KK_fnc_setPosAGLS = {
    params ["_obj", "_pos", "_offset"];
    _offset = _pos select 2;
    if (isNil "_offset") then {_offset = 0};
    _pos set [2, worldSize];
    _obj setPosASL _pos;
    _pos set [2, vectorMagnitude (_pos vectorDiff getPosVisual _obj) + _offset];
    _obj setPosASL _pos;
};
```

```sqf
// This will place the player exactly on top deck of Cargo HQ on Stratis:
[player, [2437.18,5693.47,0]] call KK_fnc_setPosAGLS;

// This will place the player 2m above top deck of Cargo HQ on Stratis:
[player, [2437.18,5693.47,2]] call KK_fnc_setPosAGLS;

// This will place the player 2m below top deck of Cargo HQ on Stratis:
[player, [2437.18,5693.47,-2]] call KK_fnc_setPosAGLS;
```

Alternatively, [setVehiclePosition](../commands/setVehiclePosition.md) can be used. It will put the object onto the nearest surface.

```sqf
// This will place the player inside Cargo HQ on Stratis:
player setVehiclePosition [[2437.18,5693.47,0], [], 0, "CAN_COLLIDE"];

// This will place the player on top deck of Cargo HQ on Stratis:
player setVehiclePosition [[2437.18,5693.47,100], [], 0, "CAN_COLLIDE"];
```

#### PositionWorld

Similar to [PositionASL](../topics/Position.md#positionasl), however Z is measured from the sea level to the the model centre `[0, 0, 0]` of the object, rather than transformed [boundingCenter](../commands/boundingCenter.md) or land contact vertices.

```sqf
_identical = getPosWorld _obj isEqualTo AGLToASL (_obj modelToWorld [0,0,0]); // should be true
```

**See also:**
[getPosWorld](../commands/getPosWorld.md), [setPosWorld](../commands/setPosWorld.md), [mapCenterOnCamera](../commands/mapCenterOnCamera.md)

#### PositionRelative

Relative position is normally an `[X, Y, Z]` offset from the model centre.

**See also:**
[getRelPos](../commands/getRelPos.md), [positionCameraToWorld](../commands/positionCameraToWorld.md), [selectionPosition](../commands/selectionPosition.md), [attachTo](../commands/attachTo.md), [modelToWorld](../commands/modelToWorld.md), [worldToModel](../commands/worldToModel.md), [modelToWorldVisual](../commands/modelToWorldVisual.md), [worldToModelVisual](../commands/worldToModelVisual.md), [camPrepareRelPos](../commands/camPrepareRelPos.md), [camSetRelPos](../commands/camSetRelPos.md)

#### PositionConfig

The format used in configs, such as *mission.sqm*, is `[X, Z, Y]`, where Z and Y are swapped around. One other command that uses this format is [positionCameraToWorld](../commands/positionCameraToWorld.md). Z in configs is measured from the sea level.

<sub>Source: [BI Community Wiki — Position](https://community.bistudio.com/wiki/Position) (revision 364535).</sub>
