Jump to content
Sign in to follow this  
dimon

Construction of direct lines bresenham's algorithm.

Recommended Posts

Construction of direct lines bresenham's algorithm.

func_line_algorithm

/*
       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;

7aceeba0ed3a8301aad331ba0ce59b70.jpeg

8a77dfdc712863e7df976d0ebf34491a.jpeg

Share this post


Link to post
Share on other sites

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

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;

  • Like 1

Share this post


Link to post
Share on other sites

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

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
Sign in to follow this  

×