Why does order matter for Sinusoidal paths in Unity - unity3d

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.

Related

Equations of motions vs Verlet: Collision ignored?

I initially coded my simulation using the standard equations of motions, but as is known, it ended up being quite unstable, even if it technically worked.
If we take x(t) to be the position-function of the equations of motion, I calculated my "next" position in the simulation by re-factoring x(t+delta), as follows:
x(t+delta) = x(t) + (1/2)*a*delta^2 + a*t*delta
t = t + delta
Most importantly, a is calculated as NetForce/Mass. If my system/particle encounters a collision, a normal force influences the net force in such a way that it is 0 on the axis of the collision (ie if it falls on the ground, force of gravity is pulling down, normal force of floor cancels gravity). So far, this has worked splendidly with any kind of collision.
However, I decided to switch to Verlet integration as it is known to be more stable, and for some reason, it completely ignores collision. I use the following formulas:
x(t+delta) = x(t) + v(t) * delta + .5*a(t)*delta^2
v(t+delta) = v(t) + .5 * (a(t) + a(t+delta)) * delta
a(t+delta) = NetForce / Mass
t = t + delta
Where v(0)=0, a(0)=0. As such, in addition to old position, I also store old acceleration and velocity.
However, I get the aforementioned problem: It just doesn't work properly, as it ignores collision. Even though it should be factored in into the acceleration already...
How should I approach this?
Isn't it suppose to be:
if x(t) is a position of collision:
v(t+delta) = v(t) - 2*( dot(normal_at(x(t)), v(t)) / norm(normal_at(x(t))^2 )*normal_at(x(t))
x(t+delta) = x(t)
else:
x(t+delta) = x(t) + v(t) * delta + .5*a(t)*delta^2
a(t+delta) = NetForce( x(t+delta) ) / Mass
v(t+delta) = v(t) + .5 * (a(t) + a(t+delta)) * delta
t = t + delta

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

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.

Point of intersection between two vectors when the direction of one vector is not known

Problem: I have two vectors. I know the starting point of one vector, its direction, its magnitude. I know the starting point of the other vector and its magnitude. I need to find the direction of second vector as well as the position of intersection.
Vector A: Vector B:
Position = Known Position = Known
Direction= Known Direction= UNKNOWN
Magnitude= Known Magnitude= Known
To Find: Point of intersection.
Is it possible to find the point of intersection, with the given parameters? If so then how?
Application: I want to find the position where a player would be found based on the velocity he is moving, and shoot a bullet at him at the moment he would be found, taking into account the time taken for the bullet to reach that virtual target position.
Following on from the comments I'm going to take a leap here and answer your ultimate question directly.
Say the player is, at the initial time, at a point p and travelling with velocity v; your gun is at position q and shoots a bullet in any direction at speed s:
The length of OP is vΔt and that of Q sΔt. The angle a is given by the dot product:
We can then use the cosine rule to solve for Δt:
Written in this form, we can easily see that it is a quadratic equation, and thus directly solve for Δt using the Quadratic formula:
There are a few cases we need to consider here:
v < s: need to take the positive root only as otherwise we would get negative time.
v > s and dot(PQ, s) < 0: the bullet will never catch the player.
v > s and dot(PQ, s) > 0: take the negative root this time, as the positive root is for a backwards travelling player (longer time; this is also the case presented in the diagram above).
Having the correct value for Δt from above will then enable us to find the intersection point o, and therefore the intended direction d:
Note that d is not normalized. Also, this solution works for 3D too, unlike an approach with angles.
Let subscript 1 mark the player, and subscript 2 mark the AI:
initial: position (x_i, y_i)
angle: alpha_i
speed: u_i
The positions as a function of time t are :
player: (x_1 + u_1 * t * cos(alpha_1), y_1 + u_1 * t * sin(alpha_1))
AI's bullet: (x_2 + u_2 * t * cos(alpha_2), y_2 + u_2 * t * sin(alpha_2))
You have 2 uknowns:
t - the time of collision
alpha_2 - the angle the AI should shoot
The collision happens when Xs and Ys match. i.e.:
x_1 + u_1 * t * cos(alpha_1) = x_2 + u_2 * t * cos(alpha_2)
y_1 + u_1 * t * sin(alpha_1) = y_2 + u_2 * t * sin(alpha_2)
So,
alpha_2 = arcos( (x_1 + u_1 * t * cos(alpha_1) - x_2) / u_2 * t )
and also
alpha_2 = arcsin( (y_1 + u_1 * t * sin(alpha_1) - y_2) / u_1 * t )
substitue your values and equate these to expressions of alpha_2 to obtain t, then you can substitue t in either expression to obtain the angle alpha_2.

Earth goes out of orbit in java simulation

Firstly I'm very new to java, apologies. I'm trying to simulate the Earth going around the sun. After plotting the results, its apparent the Earth spirals out of orbit just after one revolution!
I've checked and double checked the constants such as the mass of the sun and the Earth as well as the initial velocity and position. I'm not sure where I'm going wrong the equations are also correct confirmed by colleagues and the lecturer.
Code consists of 4 classes:
find.
Bad:
y += yVelocity * timeStep;
x += xVelocity * timeStep;
As you are using discrete timesteps, you must not only add the velocity to your position, but also the effect that acceleration will have on your velocity during that time.
Better:
yAccel = Sun.componentY();
xAccel = Sun.componentX();
y += (yVelocity + yAccel * timeStep * 0.5) * timeStep;
x += (xVelocity + xAccel * timeStep * 0.5) * timeStep;
yVelocity += yAccel * timeStep;
xVelocity += xAccel * timeStep;
This assumes the acceleration to remain constant throughout the duration of the timestep, which in reality it doesn't. Still, it should get much closer to the goal you want to achieve.
Best:
Using integrals you should be able to model the real behaviour perfectly (ignoring floating point issues).
Acceleration, velocity and position can all be expressed using integrals, which then you should be able to solve for the per-frame simulation range of t to t+dt. I've found that a trial license of Mathematica can be very helpful in such situations.

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