Earth goes out of orbit in java simulation - 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.

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

Calculate acceleration from data points

I have a servo motor, and this servo motor I would like to make it follow a "motion pattern" as closely as possible, and use the same value for acceleration and deceleration.
The attach picture illustrates the "motion pattern" (Y = velocity, X = Time)
motion pattern:
accelerates 0m/s to 0.100m/s.
constant velocity 0.100m/s for 4 sec.
decelerates to negative ?m/s.
accelerates to 0m/s, and motor position = 0.
How can i calculate the acceleration and deceleration?
What i have tried so far is:
Time = (total time - constant velocity time) 10 - 4 = 6sec.
Distances = (total distances - constant velocity distances ) 1 - 0.4 = 0.6meter.
acceleration = (2 * distances / (time^2) 2 * 0.6 / sqr(6) = 0.0333m/s.
But with this acceleration it over shoots in the negative direction by 500mm.
Take a look at the PLC Open motion function blocks, for example the MC_MoveRelative and the MC_MoveContinuesRelative block:
(Beckhoff documentation)
As Sergey already stated you can use those blocks to create a motion profile by entering all the parameters you need and integrating the blocks in a step chain.

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.

Unity predict endpoint from current velocity

My rocket's rigidbody velocity is Vector2(0,100) when I call a function. How can I calculate the world coordinate (enpoint) when the velocity reaches 0?
Gravity should be included in the formula.
Thanks!
It sounds like you want the integral of the velocity function, which should provide the total distance respective to time.
Your velocity is going to be v = (100 - ('t'ime * 'g'ravity)). We can solve for time like t = (-v + 100)/g -> t = (0 + 100)/g = 100/g. So you should reach zero velocity at t = 100/g (assuming all the same units).
The integral of your velocity will give you distance traveled. An integral calculator is here: http://www.integral-calculator.com/
The integral function of your velocity is 100t - (g*t^2)/2
From zero to a particular time t, you can just plug and play. So for example, if for a particular gravity you reach zero velocity at t = 10 seconds, you will have traveled (100 * 10) - ((g * 10^2)/2) distance. (so for gravity 9, you would get 1000 - (9 * 100)/2 = 550 units
Edit: To be clear - first you want to calculate how long it takes to get to velocity zero at a particular starting velocity and gravity:
t = vStart/g
Then plug that time value into the integral function above:
distance = (vStart * t) - ((g * t^2)/2)
(or clearly you could turn it into one function by replacing t with vStart/g in the second function, but if I were coding I would definitely calculate them in two steps to provide a sanity check in case my units were wrong)

Cartesian Coordinate System in Perspective Projection

I'm still implementing a perspective projection for my augmented reality application. I've already asked some questions about the viewport-calculation and other camera stuff, which is explained from Aldream in this thread
However, I don't get any useful value at the moment and I think this depends on my calculation of the cartesian coordinate space.
I had some different ways to transform latitude,longitude and altitude to a cartesian coordinate space, but nothing of them seems to work properly. Currently I'm using ECEF(earth centered), but I also tried different calculations like a combination of the haversine-formula and trigonometry (to calculate x and y from the distance and the bearing between two points).
So my question is:
How does the cartesian coordinate space affect my perspective projection? Where do I have to "compensate" my units?(When I'm using meter or centimeter for example)?
Lets say I'm using ECEF, than I get values in meter, so for example, my camera is at (0,0,2m height) and my point is at (10,10,0). Now I can easily use the function mentioned on wikipedia and afterwards using the conversion of dx,dy,dz explained in my other thread (mentioned above). What I still don't get: How does this projection "know" what my units in the coordinate system are? I think this is the mistake I'm currently doing. I don't handle the units of my coordinate system and therefore, cannot get any good value from my projection.
When I'm using a coordinate system with centimeter as unit, all of my values from my perspective projection are increasing. Where do I have to "resolve" this unit-problem? Do I have to "transform" my camera-width and camera-height from pixel to meter? Do I have to convert the coordinate system to pixel? Which coordinate-system should be used to handle this situation? I hope you can understand my problem.
Edit:I solved it myself.
I've changed my coordinate system from ecef to a own system (using haversine and bearing and then calculating x,y,z) and now I get good values! :)
I'll try another way to explain it here then. :)
The short answer is: the unit of your cartesian positions doesn't matter as long as you keep it homogeneous, ie as long as you apply this unit both to your scene and to your camera.
For the longer answer, let's go back to the formula you used...
With:
d the relative Cartesian coordinates
s the size of your printable surface
r the size of your "sensor" / recording surface (ie r_x and r_y the size of the sensor and r_z its focal length)
b the position on your printable surface
.. and do the pseudo dimensional analysis. We have:
[PIXEL] = (([LENGTH] x [PIXEL]) / ([LENGTH] * [LENGTH])) * [LENGTH]
Whatever you use as unit for LENGTH, it will be homogenized, ie only the proportion is kept.
Ex:
[PIXEL] = (([MilliM] x [PIXEL]) / ([MilliMeter] * [MilliMeter])) * [MilliMeter]
= (([Meter/1000] x [PIXEL]) / ([Meter/1000] * [Meter/1000])) * [Meter/1000]
= 1000 * 1000 / 1000 /1000 * (([Meter] x [PIXEL]) / ([Meter] * [Meter])) * [Meter]
= (([Meter] x [PIXEL]) / ([Meter] * [Meter])) * [Meter]
Back to my explanations on your other thread:
If we use those notations to express b_x:
b_x = (d_x * s_x) / (d_z * r_x) * r_z
= (d_x * w) / (d_z * 2 * f * tan(α)) * f
= (d_x * w) / (d_z * 2 * tan(α)) // with w in px
Wheter you use (d_x, d_y, d_z) = (X,Y,Z) or (d_x, d_y, d_z) = (1000*X,1000*Y,1000*Z), the ratio d_x / d_z won't change.
Now for the reasons behind your problem, you should maybe check if you apply the correct unit to the position of your camera / to its distance to the scene too. Check also your α or the unit of the focal length, depending on which one you use.
If think the later suggestion is the most likely. It can be easy to forget to also apply the right unit to the characteristics of your camera.