{"name":"Position","title":"Position","type":"topic","url":"https://community.bistudio.com/wiki/Position","revid":364535,"updated":"2024-05-16T20:46:45Z","aliases":["Position2D","Position3D","PositionAGL","PositionAGLS","PositionASL","PositionASLW","PositionATL","PositionConfig","PositionRelative","PositionWorld"],"markdown":"Positions in Arma games are always represented as arrays. There are two types of positions:\n- 2D position: `[X, Y]`\n- 3D position: `[X, Y, Z]`\n\nOn 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.\n\nWhile 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 below).\n\n> [!NOTE]\n> **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:\n>\n> ```sqf\n> player setPosASL [-50001, 500001, 500001]; // player will be set to [-50000, 500000, 500000]\n> ```\n\n### Commands\n\nSee:\n- Command Group: Positions\n- Command Group: Render Time Scope\n\n### Types\n\nThere are a number of formats available in Real Virtuality:\n\n|  |  |\n|---|---|\n| **ASL:** | Presumably \"**A**bove **S**ea **L**evel\" |\n| **ATL:** | Presumably \"**A**bove **T**errain **L**evel\" |\n| **ASLW:** | Presumably \"**A**bove **S**ea **L**evel including **W**aves\" |\n| **AGL:** | Presumably \"**A**bove **G**eneric/**G**round **L**evel\" |\n| **AGLS:** | Presumably \"**A**bove **G**eneric/**G**round **L**evel including **S**urfaces\" |\n| **World:** | Raw world coordinate system |\n| **Relative:** | Position relative to an object within its model space |\n| **Config:** | Position used in configs |\n| **Object:** | When object is used for position, PositionWorld of the object is used |\n| **Visual:** | Used for rendering objects on the screen. Useful for per-frame applications, such as drawIcon3D - see Command Group: Render Time Scope and Simulation vs Render Time Scope. |\n\n> [!IMPORTANT]\n> 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:\n>\n> Let's say it is desired to see if there is an intersection between two horizontal positions:\n>\n> ```sqf\n> private _pos1 = getPosATL _unit;\n> private _pos2 = _pos1 vectorAdd [0,200,0]; // make a horizontal line by shifting the y, so z remains the same\n> private _intersects = lineIntersects [ATLToASL _pos1, ATLToASL _pos2]; // lineIntersects needs ASL, so we just convert _pos1 and _pos2 to ASL...\n> ```\n>\n> 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).\n>\n> This is the correct way to write the above code:\n>\n> ```sqf\n> private _pos1 = getPosASL _unit;\n> private _pos2 = _pos1 vectorAdd [0,200,0]; // make a horizontal line by shifting the y\n> private _intersects = lineIntersects [_pos1, _pos2];\n> ```\n\n#### Position2D\n\nThis 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, Z is assumed to be 0.\n\n#### PositionASL\n\nZ is measured from the sea level which is constant across the map.\n\n**See also:**\ngetPosASL, setPosASL, getPosASLVisual, visiblePositionASL, ASLToATL, ATLToASL, AGLToASL, ASLToAGL, eyePos, aimPos, getTerrainHeightASL, lineIntersects, lineIntersectsWith, lineIntersectsObjs, lineIntersectsSurfaces, terrainIntersectASL, playSound3D, setDefaultCamera\n\n#### PositionASLW\n\nZ is measured from the surface of water at that position. Both waves and pond objects affect the result.\n\n**See also:**\ngetPosASLW, setPosASLW\n\n#### PositionATL\n\nZ is measured from the terrain level which varies across the map.\n\n**See also:**\ngetPosATL, setPosATL, getPosATLVisual, ASLToATL, ATLToASL\n\n#### PositionAGL\n\nZ is the same as in PositionASLW when over sea and is the same as in PositionATL when over land. Most commands either take or return PositionAGL.\n\n**See also:**\nmodelToWorld, worldToModel, modelToWorldVisual, worldToModelVisual, positionCameraToWorld, intersect, terrainIntersect, isOnRoad, drawIcon3D, drawLine3D, distance, moveTo, doMove, move, setDestination, buildingPos, screenToWorld, worldToScreen, AGLToASL, ASLToAGL, unitAimPosition, unitAimPositionVisual\n\n#### PositionAGLS\n\nOver 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.\n\nOver sea it gets even more complicated as instead of PositionATL, 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 into other formats, unlike with other position formats.\n\n**See also:**\nposition, visiblePosition, getPos, getPosVisual\n\n##### setPosAGLS\n\nThe 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.\n\n```sqf\nKK_fnc_setPosAGLS = {\n    params [\"_obj\", \"_pos\", \"_offset\"];\n    _offset = _pos select 2;\n    if (isNil \"_offset\") then {_offset = 0};\n    _pos set [2, worldSize];\n    _obj setPosASL _pos;\n    _pos set [2, vectorMagnitude (_pos vectorDiff getPosVisual _obj) + _offset];\n    _obj setPosASL _pos;\n};\n```\n\n```sqf\n// This will place the player exactly on top deck of Cargo HQ on Stratis:\n[player, [2437.18,5693.47,0]] call KK_fnc_setPosAGLS;\n\n// This will place the player 2m above top deck of Cargo HQ on Stratis:\n[player, [2437.18,5693.47,2]] call KK_fnc_setPosAGLS;\n\n// This will place the player 2m below top deck of Cargo HQ on Stratis:\n[player, [2437.18,5693.47,-2]] call KK_fnc_setPosAGLS;\n```\n\nAlternatively, setVehiclePosition can be used. It will put the object onto the nearest surface.\n\n```sqf\n// This will place the player inside Cargo HQ on Stratis:\nplayer setVehiclePosition [[2437.18,5693.47,0], [], 0, \"CAN_COLLIDE\"];\n\n// This will place the player on top deck of Cargo HQ on Stratis:\nplayer setVehiclePosition [[2437.18,5693.47,100], [], 0, \"CAN_COLLIDE\"];\n```\n\n#### PositionWorld\n\nSimilar to PositionASL, however Z is measured from the sea level to the the model centre `[0, 0, 0]` of the object, rather than transformed boundingCenter or land contact vertices.\n\n```sqf\n_identical = getPosWorld _obj isEqualTo AGLToASL (_obj modelToWorld [0,0,0]); // should be true\n```\n\n**See also:**\ngetPosWorld, setPosWorld, mapCenterOnCamera\n\n#### PositionRelative\n\nRelative position is normally an `[X, Y, Z]` offset from the model centre.\n\n**See also:**\ngetRelPos, positionCameraToWorld, selectionPosition, attachTo, modelToWorld, worldToModel, modelToWorldVisual, worldToModelVisual, camPrepareRelPos, camSetRelPos\n\n#### PositionConfig\n\nThe 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. Z in configs is measured from the sea level.","sections":[{"heading":null,"level":1,"markdown":"Positions in Arma games are always represented as arrays. There are two types of positions:\n- 2D position: `[X, Y]`\n- 3D position: `[X, Y, Z]`\n\nOn 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.\n\nWhile 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 below).\n\n> [!NOTE]\n> **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:\n>\n> ```sqf\n> player setPosASL [-50001, 500001, 500001]; // player will be set to [-50000, 500000, 500000]\n> ```"},{"heading":"Commands","level":3,"markdown":"See:\n- Command Group: Positions\n- Command Group: Render Time Scope"},{"heading":"Types","level":3,"markdown":"There are a number of formats available in Real Virtuality:\n\n|  |  |\n|---|---|\n| **ASL:** | Presumably \"**A**bove **S**ea **L**evel\" |\n| **ATL:** | Presumably \"**A**bove **T**errain **L**evel\" |\n| **ASLW:** | Presumably \"**A**bove **S**ea **L**evel including **W**aves\" |\n| **AGL:** | Presumably \"**A**bove **G**eneric/**G**round **L**evel\" |\n| **AGLS:** | Presumably \"**A**bove **G**eneric/**G**round **L**evel including **S**urfaces\" |\n| **World:** | Raw world coordinate system |\n| **Relative:** | Position relative to an object within its model space |\n| **Config:** | Position used in configs |\n| **Object:** | When object is used for position, PositionWorld of the object is used |\n| **Visual:** | Used for rendering objects on the screen. Useful for per-frame applications, such as drawIcon3D - see Command Group: Render Time Scope and Simulation vs Render Time Scope. |\n\n> [!IMPORTANT]\n> 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:\n>\n> Let's say it is desired to see if there is an intersection between two horizontal positions:\n>\n> ```sqf\n> private _pos1 = getPosATL _unit;\n> private _pos2 = _pos1 vectorAdd [0,200,0]; // make a horizontal line by shifting the y, so z remains the same\n> private _intersects = lineIntersects [ATLToASL _pos1, ATLToASL _pos2]; // lineIntersects needs ASL, so we just convert _pos1 and _pos2 to ASL...\n> ```\n>\n> 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).\n>\n> This is the correct way to write the above code:\n>\n> ```sqf\n> private _pos1 = getPosASL _unit;\n> private _pos2 = _pos1 vectorAdd [0,200,0]; // make a horizontal line by shifting the y\n> private _intersects = lineIntersects [_pos1, _pos2];\n> ```"},{"heading":"Position2D","level":4,"markdown":"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, Z is assumed to be 0."},{"heading":"PositionASL","level":4,"markdown":"Z is measured from the sea level which is constant across the map.\n\n**See also:**\ngetPosASL, setPosASL, getPosASLVisual, visiblePositionASL, ASLToATL, ATLToASL, AGLToASL, ASLToAGL, eyePos, aimPos, getTerrainHeightASL, lineIntersects, lineIntersectsWith, lineIntersectsObjs, lineIntersectsSurfaces, terrainIntersectASL, playSound3D, setDefaultCamera"},{"heading":"PositionASLW","level":4,"markdown":"Z is measured from the surface of water at that position. Both waves and pond objects affect the result.\n\n**See also:**\ngetPosASLW, setPosASLW"},{"heading":"PositionATL","level":4,"markdown":"Z is measured from the terrain level which varies across the map.\n\n**See also:**\ngetPosATL, setPosATL, getPosATLVisual, ASLToATL, ATLToASL"},{"heading":"PositionAGL","level":4,"markdown":"Z is the same as in PositionASLW when over sea and is the same as in PositionATL when over land. Most commands either take or return PositionAGL.\n\n**See also:**\nmodelToWorld, worldToModel, modelToWorldVisual, worldToModelVisual, positionCameraToWorld, intersect, terrainIntersect, isOnRoad, drawIcon3D, drawLine3D, distance, moveTo, doMove, move, setDestination, buildingPos, screenToWorld, worldToScreen, AGLToASL, ASLToAGL, unitAimPosition, unitAimPositionVisual"},{"heading":"PositionAGLS","level":4,"markdown":"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.\n\nOver sea it gets even more complicated as instead of PositionATL, 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 into other formats, unlike with other position formats.\n\n**See also:**\nposition, visiblePosition, getPos, getPosVisual"},{"heading":"setPosAGLS","level":5,"markdown":"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.\n\n```sqf\nKK_fnc_setPosAGLS = {\n    params [\"_obj\", \"_pos\", \"_offset\"];\n    _offset = _pos select 2;\n    if (isNil \"_offset\") then {_offset = 0};\n    _pos set [2, worldSize];\n    _obj setPosASL _pos;\n    _pos set [2, vectorMagnitude (_pos vectorDiff getPosVisual _obj) + _offset];\n    _obj setPosASL _pos;\n};\n```\n\n```sqf\n// This will place the player exactly on top deck of Cargo HQ on Stratis:\n[player, [2437.18,5693.47,0]] call KK_fnc_setPosAGLS;\n\n// This will place the player 2m above top deck of Cargo HQ on Stratis:\n[player, [2437.18,5693.47,2]] call KK_fnc_setPosAGLS;\n\n// This will place the player 2m below top deck of Cargo HQ on Stratis:\n[player, [2437.18,5693.47,-2]] call KK_fnc_setPosAGLS;\n```\n\nAlternatively, setVehiclePosition can be used. It will put the object onto the nearest surface.\n\n```sqf\n// This will place the player inside Cargo HQ on Stratis:\nplayer setVehiclePosition [[2437.18,5693.47,0], [], 0, \"CAN_COLLIDE\"];\n\n// This will place the player on top deck of Cargo HQ on Stratis:\nplayer setVehiclePosition [[2437.18,5693.47,100], [], 0, \"CAN_COLLIDE\"];\n```"},{"heading":"PositionWorld","level":4,"markdown":"Similar to PositionASL, however Z is measured from the sea level to the the model centre `[0, 0, 0]` of the object, rather than transformed boundingCenter or land contact vertices.\n\n```sqf\n_identical = getPosWorld _obj isEqualTo AGLToASL (_obj modelToWorld [0,0,0]); // should be true\n```\n\n**See also:**\ngetPosWorld, setPosWorld, mapCenterOnCamera"},{"heading":"PositionRelative","level":4,"markdown":"Relative position is normally an `[X, Y, Z]` offset from the model centre.\n\n**See also:**\ngetRelPos, positionCameraToWorld, selectionPosition, attachTo, modelToWorld, worldToModel, modelToWorldVisual, worldToModelVisual, camPrepareRelPos, camSetRelPos"},{"heading":"PositionConfig","level":4,"markdown":"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. Z in configs is measured from the sea level."}],"categories":["Arrays"],"groups":["Scripting"]}