dimon 32 Posted March 23, 2015 Construction of direct lines bresenham's algorithm. func_line_algorithm Reveal hidden contents /* File: ffa_func_line_algorithm.sqf Author: Wikipedia Used Bresenham's line algorithm. Edit: Dimon UA Description: Creating line Parameter(s): _this select 0: position (Array) _this select 1: position (Array) Returns: Array - format Position2D */ ffa_func_line_algorithm = { line_algorithm = { private ["_pos", "_this", "_end", "_angle", "_xstart", "_ystart", "_xend", "_yend", "_dx", "_dy", "_ind", "_incx", "_incy", "_pdx", "_pdy", "_es", "_el", "_x", "_y", "_err", "_arr"]; _pos = (_this select 0) select 0; _end = (_this select 0) select 1; _step = _this select 1; _ind = 0; _angle =[_pos, _end] call BIS_fnc_dirTo; _xstart = _pos select 0; _ystart = _pos select 1; _xend = _end select 0; _yend = _end select 1; _dx = _xend - _xstart;//Ð¿Ñ€Ð¾ÐµÐºÑ†Ð¸Ñ Ð½Ð° оÑÑŒ Ð¸ÐºÑ _dy = _yend - _ystart;//Ð¿Ñ€Ð¾ÐµÐºÑ†Ð¸Ñ Ð½Ð° оÑÑŒ игрек if (_dx < 0) then { _incx =-1; }else{ _incx =1; }; /* * ОпределÑем, в какую Ñторону нужно будет ÑдвигатьÑÑ. ЕÑли dx < 0, Ñ‚.е. отрезок идёт * Ñправа налево по икÑу, то incx будет равен -1. * Ðто будет иÑпользоватьÑÑ Ð² цикле поÑтороениÑ. */ if (_dy < 0) then { _incy =-1; }else{ _incy =1; }; /* * Ðналогично. ЕÑли риÑуем отрезок Ñнизу вверх - * Ñто будет отрицательный Ñдвиг Ð´Ð»Ñ y (иначе - положительный). */ _dx = abs _dx; _dy = abs _dy; if (_dx > _dy) then //определÑем наклон отрезка: { /* * ЕÑли dx > dy, то значит отрезок "вытÑнут" вдоль оÑи икÑ, Ñ‚.е. он Ñкорее длинный, чем выÑокий. * Значит в цикле нужно будет идти по Ð¸ÐºÑ (Ñтрочка el = dx;), значит "протÑгивать" прÑмую по икÑу * надо в ÑоответÑтвии Ñ Ñ‚ÐµÐ¼, Ñлева направо и Ñправа налево она идёт (pdx = incx;), при Ñтом * по y Ñдвиг такой отÑутÑтвует. */ _pdx = _incx; _pdy = 0; _es = _dy; _el = _dx; } else//Ñлучай, когда прÑÐ¼Ð°Ñ Ñкорее "выÑокаÑ", чем длиннаÑ, Ñ‚.е. вытÑнута по оÑи y { _pdx = 0; _pdy = _incy; _es = _dx; _el = _dy;//тогда в цикле будем двигатьÑÑ Ð¿Ð¾ y }; _x = _xstart; _y = _ystart; _err = _el/2; _arr=[]; for "_i" from 0 to (_el-1) do { _err =_err - _es; if (_err < 0) then { _err =_err + _el; _x=_x + _incx;//Ñдвинуть прÑмую (ÑмеÑтить вверх или вниз, еÑли цикл проходит по икÑам) _y=_y + _incy;//или ÑмеÑтить влево-вправо, еÑли цикл проходит по y } else { _x =_x + _pdx;//продолжить Ñ‚Ñнуть прÑмую дальше, Ñ‚.е. Ñдвинуть влево или вправо, еÑли _y =_y + _pdy;//цикл идёт по икÑу; Ñдвинуть вверх или вниз, еÑли по y }; _ind =_ind +1; if (_ind == _step) then { _arr set [count _arr,[_x,_y,_angle]]; _ind = 0;}; }; _arr }; private ["_arr1"]; _arr1 = []; { if (_forEachIndex != (count (_this select 0) - 1)) then { _arr1 set [count _arr1,([[_x, (_this select 0) select (_forEachIndex +1)],(_this select 1)] call line_algorithm)]; }; } foreach (_this select 0); _arr1 }; private ["_pos", "_step", "_dir", "_name", "_color", "_icon", "_type", "_local", "_array", "_index", "_m", "_x"]; _pos = _this select 0; _step = _this select 1; if (!isnil {_this select 2}) then {_dir =_this select 2;}else{_dir =0;}; if (!isnil {_this select 3}) then {_name =_this select 3;}else{_name ="markername";}; if (!isnil {_this select 4}) then {_color =_this select 4;}else{_color ="Colorblue";}; if (!isnil {_this select 5}) then {_icon =_this select 5;}else{_icon ="ICON";}; if (!isnil {_this select 6}) then {_type =_this select 6;}else{_type ="group_11";}; if (!isnil {_this select 7}) then {_local =_this select 7;}else{_local =false;}; _array = [_pos,_step] call ffa_func_line_algorithm; if (!isnil "_local" && {_local}) then { { _index = str _forEachIndex; { _m = createMarkerlocal[_name +_index+ (str _forEachIndex), [ _x select 0,_x select 1]]; _m setMarkerShapelocal _icon; _m setMarkerTypelocal _type; _m setMarkerDirlocal ((_x select 2) +_dir); _m setmarkercolorlocal _color; } foreach _x; } foreach _array; }else{ { _index = str _forEachIndex; { _m = createMarker[_name +_index+ (str _forEachIndex), [ _x select 0,_x select 1]]; _m setMarkerShape _icon; _m setMarkerType _type; _m setMarkerDir ((_x select 2) +_dir); _m setmarkercolor _color; } foreach _x; } foreach _array; }; example arr = []; mark = [markerpos "m2",markerpos "m3",markerpos "m3_1",markerpos "m3_2",markerpos "m3_3",markerpos "m3_4" ,markerpos "m2"]; arr = [mark,10,0,nil ,nil,nil,nil,nil] call func_line_algorithm; arr = []; mark = [markerpos "m2",markerpos "m3",markerpos "m3_1",markerpos "m3_2",markerpos "m3_3",markerpos "m3_4" ]; arr = [mark,10,0,nil ,nil,nil,nil,nil] call func_line_algorithm; Share this post Link to post Share on other sites
dimon 32 Posted March 23, 2015 2. Autor VVL99 the 2nd method is more easier, more economical and more practical: there is one marker of the rectangle with width 0 and with the right rotation between points. http://www.flashpoint.ru/attachments/arma2rft-2015-03-24-00-24-11-361-jpg.54285/ (300 kB) fnc_line = { #define gpa(a,b,c) (((getpos a select c)+(getpos b select c))/2) *** ***private ["_ob1","_ob2","_mm"]; *** *** _ob1 = _this select 0; *** *** _ob2 = _this select 1; *** *** _mm = _this select 2; *** *** _mm setMarkerShape "RECTANGLE"; *** *** _mm setMarkerBrush "border"; *** *** _mm setMarkerColor "ColorRed"; *** *** _mm setMarkerDir ([_ob1, _ob2] call BIS_fnc_DirTo); *** *** _mm setmarkerpos [gpa(_ob2,_ob1,0),gpa(_ob2,_ob1,1),0]; *** *** _mm setMarkerSize [0,(_ob1 distance _ob2)/2]; }; _mm = createMarker ["mm",getpos player]; [s1,s2,"mm"] call fnc_line; s1 - object, s2 - object, "mm" - marker example Share this post Link to post Share on other sites
dimon 32 Posted March 25, 2015 rewrote the function fnc_line = { fnc_line1 = { #define gpa(a,b,c) (((a select c)+(b select c))/2) private ["_ob1","_ob2","_m"]; _ob1 = if ( typename (_this select 0) == "OBJECT" ) then {getpos (_this select 0)} else {if (typename (_this select 0) == "STRING") then {markerpos (_this select 0) }else{_this select 0};}; _ob2 = if ( typename (_this select 0) == "OBJECT" ) then {getpos (_this select 1)} else {if (typename (_this select 1) == "STRING") then {markerpos (_this select 1) }else{_this select 1};}; _color = _this select 2; _m = createMarker [str random(10000),[0,0]]; _m setMarkerShape "RECTANGLE"; _m setMarkerBrush "border"; _m setMarkerColor _color; _m setMarkerDir ([_ob1, _ob2] call BIS_fnc_DirTo); _m setmarkerpos [gpa(_ob2,_ob1,0),gpa(_ob2,_ob1,1),0]; _m setMarkerSize [0,(_ob1 distance _ob2)/2]; }; _arr1 = []; { if (_forEachIndex != ((count (_this select 0)) - 1)) then { _arr1 set [count _arr1,([_x, ((_this select 0) select (_forEachIndex +1)),_this select 1] call fnc_line1)]; }; } foreach (_this select 0); _arr1 }; mark = ["m1","m2","m4","m3","m1"]; //mark = [s1,s2,s3,s4]; [mark,"ColorRed"] call fnc_line; 1 Share this post Link to post Share on other sites
Maff 251 Posted November 21, 2016 On 3/25/2015 at 5:08 AM, dimon said: rewrote the function fnc_line = { fnc_line1 = { #define gpa(a,b,c) (((a select c)+(b select c))/2) private ["_ob1","_ob2","_m"]; _ob1 = if ( typename (_this select 0) == "OBJECT" ) then {getpos (_this select 0)} else {if (typename (_this select 0) == "STRING") then {markerpos (_this select 0) }else{_this select 0};}; _ob2 = if ( typename (_this select 0) == "OBJECT" ) then {getpos (_this select 1)} else {if (typename (_this select 1) == "STRING") then {markerpos (_this select 1) }else{_this select 1};}; _color = _this select 2; _m = createMarker [str random(10000),[0,0]]; _m setMarkerShape "RECTANGLE"; _m setMarkerBrush "border"; _m setMarkerColor _color; _m setMarkerDir ([_ob1, _ob2] call BIS_fnc_DirTo); _m setmarkerpos [gpa(_ob2,_ob1,0),gpa(_ob2,_ob1,1),0]; _m setMarkerSize [0,(_ob1 distance _ob2)/2]; }; _arr1 = []; { if (_forEachIndex != ((count (_this select 0)) - 1)) then { _arr1 set [count _arr1,([_x, ((_this select 0) select (_forEachIndex +1)),_this select 1] call fnc_line1)]; }; } foreach (_this select 0); _arr1 }; mark = ["m1","m2","m4","m3","m1"]; //mark = [s1,s2,s3,s4]; [mark,"ColorRed"] call fnc_line; Nice one! This will save me many, MANY hours marking out AO's. Share this post Link to post Share on other sites