Jump to content
🛡️FORUMS ARE IN READ-ONLY MODE Read more... ×
Mallen_

Polygon Triangulation for Map Markers

Recommended Posts

Hey guys,

So im posting this in the hopes that it can help people looking for similar solutions to shading a custom map area defined by a polygon of markers, it took a while to get working but creates a really clean effect thats easy to adapt to most situations.

 

Spoiler



fnf_trianglesToDraw = [];

_markerList = [
  "marker_0",
  "marker_1",
  "marker_2",
  "marker_3",
  "marker_4",
  "marker_5",
  "marker_6",
  "marker_7",
  "marker_8",
  "marker_9"
];

fnf_triangulate = {
  params["_markerList", "_output"];
  if (count _markerList < 3) exitWith {hint "invalid marker list"};
  if (count _markerList == 3) exitWith {_output pushBack _markerList};

  {
    _prevMarker = "";
    _nextMarker = "";
    _marker = _x;
    if (_forEachIndex == 0) then
    {
      _prevMarker = _markerList select ((count _markerList) - 1);
    } else {
      _prevMarker = _markerList select (_forEachIndex - 1);
    };
    if (_forEachIndex == (count _markerList) - 1) then
    {
      _nextMarker = _markerList select 0;
    } else {
      _nextMarker = _markerList select (_forEachIndex + 1);
    };
    _markerPos = getMarkerPos _marker;
    _prevMarkerPos = getMarkerPos _prevMarker;
    _nextMarkerPos = getMarkerPos _nextMarker;

    _avgX = ((_markerPos select 0) + (_prevMarkerPos select 0) + (_nextMarkerPos select 0)) / 3;
    _avgY = ((_markerPos select 1) + (_prevMarkerPos select 1) + (_nextMarkerPos select 1)) / 3;

    _currentPolygon = [];

    {
      _currentPolygon pushBack (getMarkerPos _x);
    } forEach _markerList;

    if ([_avgX, _avgY, 0] inPolygon _currentPolygon) then
    {
      _foundInPolygon = false;
      {
        _tempMarkerPos = getMarkerPos _x;
        if (_x != _marker and _x != _prevMarker and _x != _nextMarker and _tempMarkerPos isNotEqualTo _markerPos and _tempMarkerPos isNotEqualTo _nextMarkerPos and _tempMarkerPos isNotEqualTo _prevMarkerPos) then
        {
          if ((getMarkerPos _x) inPolygon [_prevMarkerPos, _markerPos, _nextMarkerPos]) then {
            _foundInPolygon = true;
          };
        };
      } forEach _markerList;
      if (not _foundInPolygon) then
      {
        _output pushBack [_prevMarker, _marker, _nextMarker];
        _markerList deleteAt _forEachIndex;
        if (count _markerList == 3) then
        {
          _output pushBack _markerList;
        } else {
          [_markerList, _output] call fnf_triangulate;
        };
        break;
      };
    };
  } forEach _markerList;
};

_outputsToUse = [];

[_markerList, _outputsToUse] call fnf_triangulate;
{fnf_trianglesToDraw pushBack [_x, [0,0,0,0.5] ,"#(rgb,1,1,1)color(1,1,1,1)"]} forEach _outputsToUse;

findDisplay 12 displayCtrl 51 ctrlAddEventHandler ["Draw",
{
  _map = _this select 0;
  {
    _pos1 = getMarkerPos ((_x select 0) select 0);
    _pos2 = getMarkerPos ((_x select 0) select 1);
    _pos3 = getMarkerPos ((_x select 0) select 2);
	  _map drawTriangle [[_pos1, _pos2, _pos3], _x select 1, _x select 2];
  } forEach fnf_trianglesToDraw;
}];


 

 

  • Like 6
  • Thanks 1

Share this post


Link to post
Share on other sites

Excellent job with this. I have been trying to find out how to do this for over a year...

It works perfectly, apart from one thing. How would I use this if I wanted to different polygons on the map? i.e A green zone and a red zone?
I have managed to change the colour, but can only get one polygon to show at a time.

Share this post


Link to post
Share on other sites
On 3/15/2023 at 2:43 PM, aurora1-4 said:

Excellent job with this. I have been trying to find out how to do this for over a year...

It works perfectly, apart from one thing. How would I use this if I wanted to different polygons on the map? i.e A green zone and a red zone?
I have managed to change the colour, but can only get one polygon to show at a time.

New to this stuff, but maybe changing the naming convention for markers based on what they are for might work (opforSpawn_1, independentSpawn_6, etc,) store them to arrays, then run the function separately on each array.

Share this post


Link to post
Share on other sites

×