gc8 977 Posted December 7, 2011 hi is it possible to find clear landing zone for helicopter? I tried this code but it often returns places at tree lines or inside forest. _exp = "(1 + meadow) * (1 - forest) * (1 - trees)"; _bestplace = selectBestPlaces [_pos,_radius,_exp,50,1]; thx Share this post Link to post Share on other sites
igneous01 19 Posted December 7, 2011 look into the command isFlatEmpty on the wiki, its more streamlined for open spaces Share this post Link to post Share on other sites
gc8 977 Posted December 7, 2011 Actually I need multible landingzones.. the isFlatEmpty allows to look for one only... thats why i tried to use selectbestplaces. But thanks anyway Share this post Link to post Share on other sites
rübe 127 Posted December 8, 2011 Actually I need multible landingzones.. You can give the following function a try: fn_randomCirclePositions.sqf: /* Author: rübe Description: Generate random positions around a center position within the given limitations (distance, sector and findSafePos). The function does not guarantee to return the desired amount of positions and may return an empty array anyway! - Beware: You could get positions on islands though... :/ Parameter(s): _this: parameters (array of array [key (string), value (any)]) - required: - "position" (position) - "number" (int) - number of positions to be returned, though it's not guaranteed that this many will be returned. - optional: - "range" (array of [minDistance (scalar), maxDistance (scalar)]) - default: [0, 250] - "sector" (array of [minAngle (scalar), maxAngle (scalar)]) - default: [0, 360] - "objDistance" (scalar) - minimal distance to other/nearest objects - default = 1 - "posDistance" (scalar) - minimal distance between returned positions - default = "objDistance" * 2 - "adjustPos" (scalar) - if greater than zero, the sample position may be adjusted at max. the given distance to better fit isFlatEmpty criteria. - default: 0 - "roadDistance" (scalar) - 0: doesn't matter/no check - n > 0: minimal distance to any roads - default: 0 - "locationDistance" (scalar) - 0: doesn't matter/no check - n > 0: minimal distance to nearest location - default: 0 - "locations" (array of strings) - define what is considered a location - affects "locationDistance" - default: ["NameCityCapital", "NameCity", "NameVillage"] - "blacklist" (array of positions) - default = empty - "blacklistDistance" (scalar) min. distance to stay away from points in the blacklist, aka a radius, if you like. - default = 500; - "maxGradient" (scalar from 0.0 to 1.0) - default = 1.0; - "gradientRadius" (scalar in m) - default = "objDistance" - "waterMode" (int from 0 to 2) - 0: cannot be in water - 1: can either be in water or not - 2: must be in water - default: 0 - "onShore" (boolean/int from 0 to 1) - 0: does not have to be at a shore - 1: must be at a shore - default: 0 Example: _positions = [ ["position", _campCenterPosition], ["number", 7], ["range", [0, 120]], ["sector", [0, 360]], ["objDistance", (_tentLength * 0.5)], ["maxGradient", 0.3] ] call RUBE_randomCirclePositions; Returns: array-of-positions OR empty-array */ private ["_thePositions", "_pos", "_numPos", "_distMin", "_distMax", "_dirMin", "_dirMax", "_objDistance", "_posDistance", "_adjustPos", "_maxGradient", "_gradientRadius", "_waterMode", "_onShore", "_roadDistance", "_locationDistance", "_locationDefinition", "_entities", "_i", "_maxIter", "_accepted", "_diceDir", "_diceDist", "_dicePos", "_blacklist", "_blacklistDistance"]; _thePositions = []; // catch arguments _pos = [0,0,0]; _numPos = 1; _distMin = 0; _distMax = 250; _dirMin = 0; _dirMax = 360; _objDistance = 1; _posDistance = false; _adjustPos = 0; _maxGradient = 1.0; _gradientRadius = false; _waterMode = 0; _onShore = false; _roadDistance = 0; _locationDistance = 0; _locationDefinition = [ "NameCityCapital", "NameCity", "NameVillage" ]; _blacklist = []; _blacklistDistance = 500; // read parameters { switch (_x select 0) do { case "position": { _pos = _x select 1; }; case "number": { _numPos = _x select 1; }; case "range": { _distMin = (_x select 1) select 0; _distMax = (_x select 1) select 1; }; case "sector": { _dirMin = (_x select 1) select 0; _dirMax = (_x select 1) select 1; }; case "adjustPos": { _adjustPos = _x select 1; }; case "objDistance": { _objDistance = _x select 1; }; case "posDistance": { _posDistance = _x select 1; }; case "blacklist": { _blacklist = _x select 1; }; case "blacklistDistance": { _blacklistDistance = _x select 1; }; case "maxGradient": { _maxGradient = _x select 1; }; case "gradientRadius": { _gradientRadius = _x select 1; }; case "waterMode": { _waterMode = _x select 1; }; case "onShore": { if ((typeName (_x select 1)) == "BOOL") then { _onShore = _x select 1; } else { if ((_x select 1) == 1) then { _onShore = true; }; }; }; case "roadDistance": { _roadDistance = _x select 1; }; case "locationDistance": { _locationDistance = _x select 1; }; case "locations": { _locationDefinition = _x select 1; }; }; } forEach _this; // set adaptive auto default values if ((typeName _posDistance) == "BOOL") then { _posDistance = _objDistance * 2; }; if ((typeName _gradientRadius) == "BOOL") then { _gradientRadius = _objDistance; }; if ((count _blacklist) == 0) then { _blacklistDistance = 0; }; // we may need more iterations if we need a minimum distance between the positions _i = 0; _maxIter = 1000; if (_posDistance > 0) then { // roughly approximated.. _maxIter = _maxIter + (_posDistance * _numPos); }; // search n positions while {(count _thePositions) < _numPos} do { _diceDir = _dirMin + (random (_dirMax - _dirMin)); _diceDist = _distMin + (random (_distMax - _distMin)); _dicePos = [ ((_pos select 0) + (_diceDist * (sin _diceDir))), ((_pos select 1) + (_diceDist * (cos _diceDir))), 0 ]; // check if the position is safe if ((count (_dicePos isFlatEmpty[_objDistance, _adjustPos, _maxGradient, _gradientRadius, _waterMode, _onShore, objNull])) > 0) then { // check if dicePos is not too near to an already accepted position _accepted = true; if (_posDistance > 0) then { { if ((_dicePos distance _x) < _posDistance) then { _accepted = false; }; } forEach _thePositions; }; if (_roadDistance > 0) then { _entities = _dicePos nearRoads _roadDistance; if ((count _entities) > 0) then { _accepted = false; }; }; if (_locationDistance > 0) then { _entities = nearestLocations [_dicePos, _locationDefinition, _locationDistance]; if ((count _entities) > 0) then { _accepted = false; }; }; if (_blacklistDistance > 0) then { { if ((_dicePos distance _x) < _blacklistDistance) exitWith { _accepted = false; }; } forEach _blacklist; }; // all sub-tests passed? if (_accepted) then { _thePositions = _thePositions + [_dicePos]; }; }; // we do not wanna search forever... if (_i > _maxIter) exitWith {}; _i = _i + 1; }; // return _thePositions Use the parameter "objDistance" to define the size of the needed area and set a reasonable max gradient with "maxGradient". Since the function doesn't guarantee to return the desired amount of positions, the strategy would be to call that function in a while loop until it does return enough positions, while loosening the restrictions every iteration (for example you could increase the search radius or up maxGradient slightly or something). If you need an example on how to use this function, you could look into my RUBE Fire Ants mission. Share this post Link to post Share on other sites
demonized 20 Posted December 8, 2011 i used this in my prareinforce v 1.2 script, works everytime, need function module: _hPad = editorplaced_hPad_name; // object we place at the found LZ. _findGoodSpot = true; _maxdist = 100; // max initial range from below position to search for LZ. _LZpos = getPos player; // position where a safe LZ should be found. while {_findGoodSpot} do { _posTemp = [_LZpos, 0, _maxdist, 10, 0, 0.5, 0] call BIS_fnc_findSafePos; _maxdist = _maxdist + 10; // add to the range to check if no LZ found. sleep 2; _string = format _posTemp; sleep 1; if (!isNil ("_string")) then { _hPad setPos _posTemp; // place the hPad at the found LZ and exit while loop. _findGoodSpot = false; }; }; Share this post Link to post Share on other sites
gc8 977 Posted December 9, 2011 You can give the following function a try:fn_randomCirclePositions.sqf: Great script thanks! you wrote it? Share this post Link to post Share on other sites