What is wrong with my vector 3 speed-cap formula? - gdscript

3D movement. If the player moves left-backwards, they will go at double the speed of any other direction. MoveDirection.x and z are equal to the respective analog stick directions, ranging from 1 to -1.
MoveDirection = Vector3(MoveDirection.x - (MoveDirection.z / 2 * MoveDirection.x), MoveDirection.y, MoveDirection.z - (MoveDirection.x / 2 * MoveDirection.z))
I thought that the results would be something like 0.5, 0, 0.5 if moving diagonally but that isn't the case.

Are you sure it doesn't also occur in the right-backwards direction as well? I'm thinking that this could likely be be related to how Godot handles arithmetic order. For example, if Godot does multiplication before division (like I think it does), then assuming we use whole values (1 or -1), then Godot would process the first Vector3 coordinate in your code this way::
Using - (MoveDirection.x - (MoveDirection.z / 2 * MoveDirection.x)
Substitute values for - (x,z)
FOR VALUES (1 , -1)
(1) - (-1 / (2 * 1))
(1) - (-1) / (2)
(1) - (-0.5)
= 1.5 <<<<<<----------- THIS IS YOUR PROBLEM (I THINK)
FOR VALUES (-1, 1)
(-1) - (1 / (2 * -1))
(-1) - (1) / (-2)
(-1) - (-0.5)
= -0.5
FOR VALUES (1 , 1)
(1) - (1 / (2 * 1))
(1) - (1) / (2)
(1) - (0.5)
= 0.5
FOR VALUES (-1, -1)
(-1) - (-1 / (2 * -1))
(-1) - (-1) / (-2)
(-1) - (0.5)
= -1.5 <<<<<<----------- THIS SHOULD ALSO BE A PROBLEM (I THINK)
If my math is wrong, please forgive me, it's 5:00AM where I am. If I am wrong, let me know and I'll delete this answer.
EDIT: It turns out arithmetic order doesn't even matter, it does the same thing with division first. My suggestion would be to find a way to subtract 1 from (or add 1 to) the affected results. Maybe something like: if (MoveDirection.x > 0) AND (MoveDirection.z < 0), subtract 1 from result.

Related

Why does order matter for Sinusoidal paths in Unity

just a quick question regarding possibly how Unity2D engine compile or runtime works, or maybe something I don't understand at all, so the following code works properly:
pos -= Time.deltaTime * moveSpeed * transform.right;
transform.position = magnitude * pos + axis * Mathf.Sin(Time.time * frequency);
However if I move the pos + axis (both are Vector3) then the pathing does not do what is expected, I was just wondering why this is the case. For example the following code would not work how I want it to:
pos -= Time.deltaTime * moveSpeed * transform.right;
transform.position = magnitude * Mathf.Sin(Time.time * frequency) * pos + axis;
If anyone has any insight I'd like to know.
Thank you.
Unity will resolve math equations following the pemdas order of operations. To clarify, it will handle everything in the order of:
Parathesis
Exponents
Multiplication / Division
Addition / Subtraction
Along with this, the order of operations are read left to right, so whatever appears on the left will be handled first, which is how the tie breakers of Addition / Subtraction and Multiplication / Division are handled.
In your example case, moving the variables as you have results in a completely different operation. For simplicity, I will substitute the vectors for whole numbers and just write out the multiplication as vector * vector and vector * scalar are just scaled vectors, so I can equally substitute all of them for ints.
pos = 5
axis = 3
Mathf.Sin(frequency * Time.time) = 2
magnitude = 12
Now substituting these values into your two equations:
12 * 5 + 3 * 2 (12 * 5 is handled first, next 3 * 2 and then 60 + 6 = 66)
12 * 2 * 5 + 3 (12 * 2 is handled first, next 24 * 5 and then 120 + 3 = 123)
Following the pemdas rule I explained above, the solutions would work out to be:
66
123
If you would like an explanation using vectors I can write one out.

Fixed point multiplication of negative numbers

I have the following method to multiply two 32 bit numbers in fixed point
19.13 format. But I think there is a problem with this method:
1.5f is rounded up to 2.0f, while -1.5f is rounded up to -1.0f.
It seems to me that -1.5 should be rounded down to -2.0f.
First, does the current rounding make sense, and if not, how can I change it
to be more consistent?
static OPJ_INT32 opj_int_fix_mul(OPJ_INT32 a, OPJ_INT32 b) {
OPJ_INT64 temp = (OPJ_INT64) a * (OPJ_INT64) b ;
temp += 4096;
assert((temp >> 13) <= (OPJ_INT64)0x7FFFFFFF);
assert((temp >> 13) >= (-(OPJ_INT64)0x7FFFFFFF - (OPJ_INT64)1));
return (OPJ_INT32) (temp >> 13);
}
Since you are always adding 4096, code is doing rounding half-way cases toward positive infinity. It is kind of odd.
To round toward positive infinity, I'd expect
temp += 4096 + 4095;
To round in the usual fashion (to nearest), use instead add a bias away from 0.
temp += (temp < 0) ? -4096 : 4096;
To round to nearest and ties to even is more work. Not certain OP desires that.

Take value from float number after dot

How correctly extract second valued after coma in Float value.
Example:
var value = 5.435
And I would like to take value second value after coma, that is 3.
How to do this properly?
In case you want to handle both positive and negative values:
(Int)( abs(value) * 100 ) % 10
If you want to keep the sign, just remove abs
Maybe this: (int)( value * 100 ) % 10.
If its always going to be the third decimal, I would do it like this.
var value = 5.435
value *= 100
var digit = value % 10
Mod is an expensive operation, instead do
(Int(value * 100)) - (Int(value * 10) * 10)
In your scenario we get
(Int(5.435 * 100)) - (Int(5.435 * 10) * 10);
(Int(543.5)) - (Int(54.35) * 10);
(543) - (54 * 10);
(543) - (540);
3

Please explain this effect, Unity Textures

The following code was taken from here. How Does this Particular Line Work -
texture.SetPixel(x, y, new Color((x + 0.5f) * stepSize % 0.1f, (y + 0.5f) * stepSize % 0.1f, 0f) * 10f); Multiplying Color with 10 and modulus with 0.1f is confusing me ?
All he's done in that line is have the color pattern repeat itself ten times over.
By calculating the modulo with 0.1, each loop of 0 - 1 will yield ten values (0, 0.1, 0.2...)
Further, by multiplying by 10, the color stays visible, and the result is the 10 x 10 grid pattern
Just take a look at the images the author has put up

How to swap negative rotation values over to positive rotation values?

Example: I have a circle which is split up into two halfs. One half goes from 0 to -179,99999999999 while the other goes from 0 to 179,99999999999. Typical example: transform.rotation.z of an CALayer. Instead of reaching from 0 to 360 it is slip up like that.
So when I want to develop a gauge for example (in theory), I want to read values from 0 to 360 rather than getting a -142 and thinking about what that might be on that 0-360 scale.
How to convert this mathematically correctly? Sine? Cosine? Is there anything useful for this?
Isn't the normalization achieved by something as simple as:
assert(value >= -180.0 && value <= +180.0);
if (value < 0)
value += 360.0;
I'd probably put even this into a function if I'm going to need it in more than one place. If the code needs to deal with numbers that might already be normalized, then you change the assertion. If it needs to deal with numbers outside the range -180..+360, then you have more work to do (adding or subtracting appropriate multiples of 360).
while (x < 0) {
x = x + 360;
}
while (x > 360) {
x = x - 360;
}
This will work on any value, positive or negative.
((value % 360) + 360) % 360
The first (value % 360) makes it to -359 to 359.
The + 360 removes any negative number: Value now 1 to 719
The last % 360 makes it to 0
to 359
Say x is the value with range (-180, 180), y is the value you want display,
y = x + 180;
That will change shift reading to range (0, 360).
If you don't mind spending a few extra CPU cycles on values that are already positive, this should work on any value -360 < x < 360:
x = (x + 360) % 360;
I provide code to return 0 - 360 degree angle values from the layer's transform property in this answer to your previous question.