wok 1 Posted November 14, 2013 I am trying to draw an arrow on the screen and the arrow points to a certain angle, and since I will have more than one arrow I can't draw them all directly on the center of the screen because they look all bunched up on top of each other. So I though about an imaginary circle which center is the center of the screen, and the arrows would be placed on this circle circumference. An image that explains it what I am trying to calculate. Google teach me that I can find those points using: x = circleCenterX + radius * cos( angle in radians );y = circleCenterY + radius * sin( angle in radians ); So I am trying to use that in Arma with DrawIcon3D (since this command allow me to set the angle of the arrow): onEachFrame { _angle = 180; _radian = _angle * pi / 180; // rad _angle _xx = 0.5 + 0.2 * cos(_radian); _yy = 0.5 + 0.2 * sin(_radian); _pos = screenToWorld [_xx, _yy]; drawIcon3D ["\A3\ui_f\data\map\Markers\Military\arrow2_ca.paa", [1, 1, 1, 1], _pos, 1, 1, _angle, "", 0, 0.03, "default"]; }; That results is: If I change the _angle to -90 (angle seems to be reversed and positive 90 acts like 270, but idc about that right now), this is the result: No matter what value I set in the _angle variable, the arrow is always on the same position, which seems to be the position corresponding to _angle = 90 (or -90). Does anyone knows how could I get this working? Share this post Link to post Share on other sites
Larrow 2828 Posted November 14, 2013 angle for screen orientation 0 is east rotation is clockwise angle for icon orientation (default arrow points up) 0 is north, rotation is anticlockwise. onEachFrame { { _angle = _x; _xx = 0.5 + 0.2 * cos( _angle-90); _yy = 0.5 + 0.2 * sin( _angle-90); _pos = screenToWorld [_xx, _yy]; drawIcon3D ["\A3\ui_f\data\map\Markers\Military\arrow2_ca.paa", [1, 1, 1, 1], _pos, 1, 1, 360-_angle, "", 0, 0.03, "default"]; }foreach [0,90,180,270]; }; Share this post Link to post Share on other sites
wok 1 Posted November 14, 2013 angle for screen orientation 0 is east rotation is clockwiseangle for icon orientation (default arrow points up) 0 is north, rotation is anticlockwise. onEachFrame { { _angle = _x; _xx = 0.5 + 0.2 * cos( _angle-90); _yy = 0.5 + 0.2 * sin( _angle-90); _pos = screenToWorld [_xx, _yy]; drawIcon3D ["\A3\ui_f\data\map\Markers\Military\arrow2_ca.paa", [1, 1, 1, 1], _pos, 1, 1, 360-_angle, "", 0, 0.03, "default"]; }foreach [0,90,180,270]; }; Thanks a lot! I couldn't apply your code sample directly because of the way I am getting the angle on my real code, I had to do some extra calculations, but knowing that one angle goes clockwise and the other anticlockwise made it easy to fix. Share this post Link to post Share on other sites
wok 1 Posted November 15, 2013 I am having a new issue with this, the (x,y) points I am calculating seem to "draw" an ellipse around the screen center and not a circle. Here's an image and code sample to explain it: onEachFrame { drawIcon3D ["\A3\ui_f\data\map\Markers\Military\circle_ca.paa", [0, 1, 0, 1], screenToWorld [0.5, 0.5], 4, 4, 0, "", 0, 0.03, "default"]; { _angle = _x; _xx = 0.5 + 0.2 * cos( _angle-90); _yy = 0.5 + 0.2 * sin( _angle-90); _pos = screenToWorld [_xx, _yy]; drawIcon3D ["\A3\ui_f\data\map\Markers\Military\arrow2_ca.paa", [1, 0, 0, 1], _pos, 1, 1, 360-_angle, "", 0, 0.03, "default"]; }foreach [0,45,90,135,180,225,270,315]; }; As you can see in the image or the code result, the more horizontal the arrows gets, the further away it is from the circle. I suspect this is because screens are not a square so the radius number represent a bigger part of the screen when used horizontally. So I would need to adjust the X depending of the angle, decreasing the radius as the angle gets more horizontal, but I couldn't find a way to get it working yet. Anyone has some ideas on how to get the points for a perfect circle? Share this post Link to post Share on other sites
das attorney 858 Posted November 15, 2013 (edited) I haven't got the time to check properly, but maybe you can use this command and get some coefficients from it: http://community.bistudio.com/wiki/getResolution Try this - works on my screen to get a Perfect Circle: onEachFrame { drawIcon3D ["\A3\ui_f\data\map\Markers\Military\circle_ca.paa", [0, 1, 0, 1], screenToWorld [0.5, 0.5], 4, 4, 0, "", 0, 0.03, "default"]; { _values = getResolution; _coeff_y = _values select 5; _angle = _x; _xx = 0.5 + ((0.2 * _coeff_y) * (cos( _angle - 90))); _yy = 0.5 + (0.2 * (sin( _angle - 90))); _pos = screenToWorld [_xx, _yy]; drawIcon3D ["\A3\ui_f\data\map\Markers\Military\arrow2_ca.paa", [1, 0, 0, 1], _pos, 1, 1, 360 - _angle, "", 0, 0.03, "default"]; }foreach [0,45,90,135,180,225,270,315]; }; Photo: https://www.dropbox.com/s/5oiako9nu6mqo2z/arma3%202013-11-15%2017-05-58-75.png Edited November 15, 2013 by Das Attorney Share this post Link to post Share on other sites
Larrow 2828 Posted November 15, 2013 (edited) Its due to the aspect ratio of the display 4:3, 16:9 , 16:10 etc divide the addition to screen x by screen width / screen height. ratio = safezonew / safezoneh; onEachFrame { { _angle = _x; _xx = 0.5 + (0.2 * cos( _angle-90)) / ratio; _yy = 0.5 + 0.2 * sin( _angle-90); _pos = screenToWorld [_xx, _yy]; drawIcon3D ["\A3\ui_f\data\map\Markers\Military\arrow2_ca.paa", [1, 1, 1, 1], _pos, 1, 1, 360-_angle, "", 0, 0.03, "default"]; }foreach [0,45,90,135,180,225,270,315] }; EDIT : I see Das has posted similar , i had typed all this out but got interrupted by a house guestand forgot to click post :) Edited November 15, 2013 by Larrow Share this post Link to post Share on other sites
wok 1 Posted November 15, 2013 Oh damn, I went right into testing getResolution and missed the updated posts, I was able to get it working using screen width and height from getResolution: onEachFrame { drawIcon3D ["\A3\ui_f\data\map\Markers\Military\circle_ca.paa", [0, 1, 0, 1], screenToWorld [0.5, 0.5], 4, 4, 0, "", 0, 0.03, "default"]; { _angle = _x; _res = getResolution; _h = _res select 0; _w = _res select 1; _radiusx = ( 0.0004 * ( _w / 2 ) ); _radiusy = ( 0.0004 * ( _h / 2 ) ); _xx = 0.5 + _radiusx * cos( _angle-90); _yy = 0.5 + _radiusy * sin( _angle-90); _pos = screenToWorld [_xx, _yy]; drawIcon3D ["\A3\ui_f\data\map\Markers\Military\arrow2_ca.paa", [1, 0, 0, 1], _pos, 1, 1, 360-_angle, "", 0, 0.03, "default"]; }foreach [0,45,90,135,180,225,270,315]; }; I wanted a solution, now I have 3 :P Thanks a lot guys. ---------- Post added at 17:53 ---------- Previous post was at 17:18 ---------- After doing some tests I found that: [b]Das code[/b] works on [color="#008000"]4:3[/color] and [color="#008000"]16:10[/color] but not in [color="#B22222"]16:9[/color] [b]Larrow code[/b] works on [color="#008000"]16:9[/color] and [color="#008000"]16:10[/color] but not in [color="#B22222"]4:3[/color] [b]My code[/b] works on [color="#008000"]4:3[/color] but not in [color="#B22222"]16:9[/color] or [color="#B22222"]16:10[/color] I haven't tested other aspect ratios, I guess I have more work to do, will see if I can get a code that works for all aspects, otherwise I could just switch(case) the different codes that works for each ratio. Share this post Link to post Share on other sites
Larrow 2828 Posted November 15, 2013 (edited) Do the UI ratio instead of the screen ratio = (getresolution select 2) / (getresolution select 3); onEachFrame { { _angle = _x; _xx = 0.5 + (0.2 * cos( _angle-90)) / ratio; _yy = 0.5 + 0.2 * sin( _angle-90); _pos = screenToWorld [_xx, _yy]; drawIcon3D ["\A3\ui_f\data\map\Markers\Military\arrow2_ca.paa", [1, 1, 1, 1], _pos, 1, 1, 360-_angle, "", 0, 0.03, "default"]; }foreach [0,45,90,135,180,225,270,315] }; Tested in 4:3 , 16:9 and 16:10. All ok ____ Is there any reason why your faking a 2D display by manipulating 3D world icons rather than making a display?? Other than the limits on ctrl creation being how ever many you make? ( Really have not done alot of UI experimentation but not being able to template ctrl's seems a major setback, unless im missing something). Edited November 15, 2013 by Larrow Share this post Link to post Share on other sites
wok 1 Posted November 15, 2013 Awesome, thanks a lot Larrow and Das! Share this post Link to post Share on other sites
wok 1 Posted November 16, 2013 (edited) Sorry Larrow I missed your question. I am using DrawIcon3D instead of dialogs for a few reasons: I don't know how to control the arrow angle using dialogs. ALso, the arrows would only be on the center of the screen when the unit/object is outside the visible screen, and when this unit become visible the arrow kinda animate from the center of the screen circle to the unit position, and then it follows it while it's inside the visible screen, when I do that using dialogs it looks all laggy, DrawIcon3D is much smoother. I had a few other reasons but can't think about them right now. ----------------------------------------------------------------------------------- I almost have it all working but there's one last major problem. Using Larrow's last posted code to test, when you look above the horizon the arrows will stop moving in the Y-axis. It looks like this: I found some code snippet on the feedback page that makes an object stay (kind of) on the screen center even when looking above the horizon line: oneachFrame { _camDir = ([(positionCameraToWorld [0,0,0]), (positionCameraToWorld[0,0,1])] call BIS_fnc_vectorDiff); _pos = ASLToATL ([eyePos player, _camDir] call BIS_fnc_vectorAdd); drawIcon3D ["\A3\ui_f\data\map\Markers\Military\arrow2_ca.paa", [1, 1, 1, 1], _pos, 1, 1, 180, "", 0, 0.03, "default"]; }; But still haven't figured how to implement both codes together. ----------------------------------------------------------------------------------- EDIT: Now that I think about it, since I am using the arrows to point at units/objects direction, it wouldn't make sense to keep them on the same position on the circle when looking up, instead I should adjust the angle to point at the unit/object position relative to the center of the screen. I gotta go out now, I will try to do some test and post the code if I manage to get something working when I come back at night. Edited November 16, 2013 by wok Share this post Link to post Share on other sites
Larrow 2828 Posted November 17, 2013 God i wish i had never read this thread, my brain is now fried and im down half a note book :D My trigonometry / unit circle theory is rubbish, this is the closest i can get. onEachFrame { { _camDir = ([(positionCameraToWorld [0,0,0]), (positionCameraToWorld[0,0,1])] call BIS_fnc_vectorDiff); _pos = ([positionCameraToWorld [0,0,0], _camDir] call BIS_fnc_vectorAdd); _angle = _x; _pos set [0, (_pos select 0) + (0.2 * sin ( (getDir player + _angle)))]; _pos set [1, (_pos select 1) + (0.2 * cos ( (getDir player + _angle)))]; _pos set [2, (_pos select 2) + (0.2 * cos ( _angle))]; drawIcon3D ["\A3\ui_f\data\map\Markers\Military\arrow2_ca.paa", [1, 1, 1, 1], _pos, 1, 1, 360-_angle, "", 0, 0.03, "default"]; }foreach [0,45,90,135,180,225,270,315] }; The angle arrows stay orientated correctly with in the cirlce (90 degrees is always to your right, although using the free look view to look say over your shoulder the arrow is in the right place but icon rotation is incorrect) but the pitch of the camera needs to be worked out and introduced into pos 0 to get the circle to stay perpendicular to the view. As this involves drawing the arrows at the players position your old method of screenToWorld really does not fit in here. Heres another that although nowhere near what you need gives a decent effect to show what it is your actually looking at onEachFrame { { _camDir = ([(positionCameraToWorld [0,0,0]), (positionCameraToWorld[0,0,1])] call BIS_fnc_vectorDiff); _pos = ([positionCameraToWorld [0,0,0], _camDir] call BIS_fnc_vectorAdd); _angle = _x; _pos set [1,(_pos select 1) + 0.2 * cos( _angle-90)]; _pos set [2,(_pos select 2) - 0.2 * sin( _angle-90)]; drawIcon3D ["\A3\ui_f\data\map\Markers\Military\arrow2_ca.paa", [1, 1, 1, 1], _pos, 1, 1, 360-_angle, "", 0, 0.03, "default"]; }foreach [0,45,90,135,180,225,270,315] }; Hopefully someone with alot more trig/unit circle theory knowledge can chip in for you. Share this post Link to post Share on other sites