Jump to content
Sign in to follow this  
Prodavec

Vector magnitude

Recommended Posts

Well, I want to use "native" engine method to get vector magnitude by using DISTANCE command for perfomance reasons.

_vector distance [0, 0, 0];

but for some reasons DISTANCE works strange for me in that case. It returns something random if called few times in a row. For example:

[2, 2, 2] distance [0, 0, 0];

you will get values between 3.4 and 3.5. +/- 0.1 m is very bad when using DISTANCE to calculate tiny vectors and small angles between them.

Classic way works pretty fine:

sqrt (2^2 + 2^2 + 2^2);

RESULT: 3.4641

But it impacts on perfomance more than DISTANCE comamnd because contains more operations executed in not "native" environment.

Any suggestions gents?

Share this post


Link to post
Share on other sites

Wild and crazy suggestion: Try to run this on Takistan? For some reason it looks like it has something to do with water waves height.

----

Its really is! Distance is dependent on water waves height. I captured some data with:

for "_i" from 0 to 1000 do {diag_log ([0,0,0] distance [2,2,2]); sleep 0.01;};

and then drew a quick graph for it:

269625_graph.png

Edited by SaMatra

Share this post


Link to post
Share on other sites
Wild and crazy suggestion: Try to run this on Takistan? For some reason it looks like it has something to do with water waves height.

----

Its really is! Distance is dependent on water waves height. I captured some data with:

for "_i" from 0 to 1000 do {diag_log ([0,0,0] distance [2,2,2]); sleep 0.01;};

and then drew a quick graph for it:

http://img.ii4.ru/images/2012/09/28/269625_graph.png

What environmental parameters did you use for testing? I just loaded up Takistan and used default date and weather conditions. My result were quite consistent, 1001 values in my rpt with the number '3.36036'. No variation at all.

Also that graph would be more useful if you told us how much it varies. Is the top of the peak +0.1, +0.01, +0.001, ...., + 0.0000000000000000001 ???.

Maybe the issue is processor dependent. High performance applications like games, might configure the CPU to to perform floating point calculations much faster at the cost of accuracy.

Share this post


Link to post
Share on other sites

Chernarus. Trying Takistan now.

Min value: 3.42047

Max value: 3.50886

----

Tried Takistan, results for

[0,0,0] distance [2,2,2]

are always: 3.36036

Edited by SaMatra

Share this post


Link to post
Share on other sites

From BIKI

Rommel - This returns the map distance, not the vector distance, [0,0,0] distance [0,0,1] can be >1 or <1, not exactly 1; unlike the vector math.

Seems to suggest it indeed is related to the map. However, how map distance differs from normal distance (at least for the case with 3 dimensional vectors), I don't know.

Share this post


Link to post
Share on other sites

Tried Chernarus again:

for "_i" from 0 to 500 do {diag_log ([0,20000,0] distance [2,2 + 20000,2]); sleep 0.01;};

All returned values are 3.49582 now since [0,20000,0] is not over water.

----

However, how map distance differs from normal distance (at least for the case with 3 dimensional vectors), I don't know.

It has something to do with PositionASL, PositionATL and way position converts input positions before calculating

----

Tried

ATLToASL([0,0,0]) distance ATLToASL([2,2,2])

and

ASLToATL([0,0,0]) distance ASLToATL([2,2,2])

both are affected by waves height as well

----

Alright, algebraic [2,2,2] vector magnitude is

3.4641016151377544

and

(ASLToATL([0,20000,0]) distance ASLToATL([2,20000+2,2]))

always returns exactly that: 3.4641

In other words you need positions that are not over water and convert positions to ATL to get accurate values.

Edited by SaMatra

Share this post


Link to post
Share on other sites

Also for some reasons it is not constant (even it's mystical map distance and on the LAND) and differs like SaMatra described. Looks like the water waves are the border of the world. So no way to calculate vector magnitude by single command? :(

Got it. That's weird. It is called the crutches.

Edited by Prodavec

Share this post


Link to post
Share on other sites

Looks like we could use vectorMagnitude scripting command since there is no reliable way to get proper result with "distance" since it depends on map and environment alot. I will not be surprised if result of "distance" depends on weather overcast too (iirc more overcast makes higher waves).

Share this post


Link to post
Share on other sites

It is realy dependent from the weather lol. Just tested.

0 setOvercast 1;
0 setRain 1;
[2, 2, 2] distance [0, 0, 0]

Distance varies between ~3.33 and ~3.61

Share this post


Link to post
Share on other sites

If you want very good accuracy then it seems you would have to calculate it manual in sqf. If you are desperate for speed then you could make an extension although that seems like extreme overkill.

Here is my crazy third suggestion that still uses distance, so you don't have to take the exponents and square root manually is to basically reduce the error portion. I'm guessing that the error is somehow related to the heights not actually being 0 and 2, but something else when calculated because of map parameters. So in order to minimize that error we just make or values large and then scale the result back down. Eg.:

#define VECTORMAG_SMALL(VEC) (([0,0,0] distance [(VEC select 0)*1000, (VEC select 1)*1000, (VEC select 2)*1000]) / 1000)

_vec = [2,2,2];
_dist = VECTORMAG_SMALL(_vec);

//On: Chernarus (the one affected by water, eg. the sine curve).
//_dist-> MIN: 3.46405  ---- MAX:  3.46415 

//So a typical value of: 3.46409
//Real value of sqrt(2^2 + 2^2 + 2^2) = 3.46410
//These values are pretty darn close: +/- 0.0005

If you decide to go with this then note that 1000 is a pretty good value. With 10000 then floating point calculations become too inaccurate when scaling up and down. If 100 then the "error value" becomes too significant.

Edited by Muzzleflash

Share this post


Link to post
Share on other sites

Did you test it? I mean perfomance of 3x select, 3x multiplying, 1x dividing, 1x distance VS 3x exponents, 3x addition, 1x sqrt?

Share this post


Link to post
Share on other sites

Got following results on my machine and test map with constant conditions:

1 million iterations

[0, 0, 0] distance _vector;
// 55s

sqrt ((_vector select 0)^2 + (_vector select 1)^2 + (_vector select 2)^2);
// 97s

([0,0,0] distance [(_vector select 0)*1000, (_vector select 1)*1000, (_vector select 2)*1000]) / 1000;
// 136s

(ASLToATL [0, 20000, 0]) distance (ASLToATL [(_vector select 0), 20000 + (_vector select 1), (_vector select 2)]);
// 130s

PS _vector is predefined as _vector = [2, 2, 2] outside of the testing loop.

UPDATE

Nice testing. Although to be fair the test should then be:

Yeah! Recalculated.

Edited by Prodavec

Share this post


Link to post
Share on other sites

Nice testing. Although to be fair the test should then be:

[0, 0, 0] distance _vector;
// 61s

sqrt ((_vector select 0)^2 + (_vector select 1)^2 + (_vector select 2)^2);
// 67s

([0,0,0] distance [(_vector select 0)*1000, (_vector select 1)*1000, (_vector select 2)*1000]) / 1000;
// 140s

(ASLToATL [0, 20000, 0]) distance (ASLToATL [(_vector select 0), 20000 + (_vector select 1), (_vector select 2)]);
// 109s

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  

×