How do I implement wind in a trajectory equation?

Asked

Viewed 2,243 times

62

Has a game of tank 2D, using the Unityengine in C#, in which it is played on the side of the screen, seeing only the sides of the tanks, in which has the green and red tank. The green need to shoot and hit the red target. The game gives you the force and angle, both vary according to your aim, in some turns a random time is defined that varies from 0 à 100, but in this application that I am creating is possible manually you can set the wind and your direction, not to say that the wind of the game is changed, but rather the trajectory that the application is calculating.

Note: The wind is already generated in a random way from 0 to 100. With this app I’m creating, you just calculate the trajectory to help you in the game.

Note that the angle is mirrored, but I’ve implemented a function that gives us the exact angle.

inserir a descrição da imagem aqui

The game is divided by turns. In every turn the wind changes along with its direction. The wind varies from 0 to 100, in the direction right or left, never greater or less than this.

inserir a descrição da imagem aqui

The dotted trajectory is what is designed in this app. The process is ready, the trajectory is being displayed, the problem is that she is not influenced by the wind, any change in the wind she will remain being influenced only by angle and the force, not by wind, that is the problem.


Big update on the question

I put an important part that was missing in the question: the horizontal calculation:

// i seria a posição horizontal(?)
for(int i = 1; i <= 1000 - Xpos; i += 1) {
    // tempo do projétil, que é calculado em base do I
    float t = i / (float) ((power + powerSalt[(int) power]) * Mathf.Cos(angle));
    // altura do projétil, calculada com base no tempo
    float Y = (float) (((power + powerSalt[(int) power]) * Mathf.Sin(angle)) * t - (0.5 * g * t * t));
    // adiciona o ponto obtido, abaixo no "i + Xpos" se ocasiona o ponto horizontal, então o "player.y + y" seria a cordenada vertical
    Vector3 point = new Vector3(Map.toWorldX((float) i + Xpos), Map.toWorldY(player.y + Y));

    // enfim, adiciona o ponto (x, y) da linha
    tracer.line.points3.Add(point);
}

Basic summary: The value Y is calculated on the basis of the flight time for each X, basically between 1 to 1,000 (as shown in the lopping statement above) which are the horizontal limits of the game. The value t represents the flight time of 0 for position i (x).


How the trajectory is affected by the wind?

Below is my trajectory (the continuous line) and the trajectory of the shot (the dotted line). The wind that was present in the game was 71.

inserir a descrição da imagem aqui

It is noticeable that beyond the height (y), the shape and distance of the trajectory were also changed with the wind.

Soon, my question is:

  • How I implement wind in these formulas?
  • 4

    The aerodynamic drag is proportional to the square of the relative speed, so it would be an additional force, added to what you already have, you have to take the square of the difference between the object’s current speed and the wind speed. It is also necessary to consider the various cases (as favor wind, which can even accelerate the object instead of braking it)

  • Is some C# implementation of something similar to Robocode in Java? If so, it would be nice to share with the community. :)

  • 2

    The question is super interesting and very cool. But you can improve the clarity in some things. 1) Should I consider images as a top view (I’m looking at the tanks from above) or side view? 2) From the second image, it seems that the tank throws up (that is, side view and with the projectile making a parabola), but the angle of the shot considers a 3D axis or only 2D? 3) When you say that "the game gives the force and the angle", it means that it is already calculated and that the player has no control (it seems that the player only controls the wind...)?

  • In the reply of colleague @zwitterion you commented: "The variables Voxt and Voyt are also not stated in my context...". Of course not. The colleague just tried to explain the calculation to you - you need to try to implement it in your code. It’s still a little hard to understand exactly what you want. I’m not a physicist, but the formula you use only considers the vector of gravity, so it doesn’t even have a force component on any axis other than the vertical one. There is missing some important information on how your projectile today already travels some horizontal distance.

  • 3

    In fact, I just realized that you are not implementing this natively in C#, but using Unity3d (by using Vector3 there and by the tag you added later). You should have made the question clearer from the beginning. By the way, since you use Unity, is the projectile using the native physics of the engine? If so, you should indicate this! Another thing, it would make it a lot easier for someone to help you if you provide a [mcve] to facilitate testing and implementation.

  • What is the range of the force variable?

  • Manually from 0 to 100.

  • The current answers may not even contain enough details, but your question also does not contain the necessary details. For example, you still haven’t answered whether the actual trajectory (that of the projectile, wind and all) is calculated by you or by Unity physics. The impression I get is that you have no idea how the code you have works (because it was a "guy" who did it). And then, my dear, it gets really hard for anyone to help you.

  • 1

    I insist: if the excerpt of code you posted is really enough to explain the co-production of your project today, try to prepare a [mcve] with it. If I can, I I pledge myself testing here and trying to help you.

  • 1

    Looking at all the comments and formulations, I miss an acceleration force. If you implement an acceleration force you can apply the force of gravity and wind speed to it.

  • 1

    Hello again. Today I answered to that question, and I think what you have there can help you with your doubt here (if you still have it, of course). I don’t know the details of your implementation, but you might want to compare the codes.

  • For you to implement a "simple" wind in the code I posted there in the other answer, do the following: create a Vector2 with the wind force you want to use, add it to the variable m_force, just before it was used. The wind will count as a positive force (if in the same direction as the current force) or negative force (if against the current force), on both axes. Note that: an active wind works more or less like gravity: it is constantly influencing the projectile - gravity only influences the Y axis, while the wind influences the two axes.

  • look at github, a library that has a chaos theory implementation. convert the library to c#. and try in some way to modulate the wind behavior as it seeks, and see which formula or set of formulas based on that same principle, which better of the answer to what it seeks

  • I appreciate the feedback. was the best solution I could find, and it would be exactly this way that I would solve the problem if I were in the same situation. so I even suggested this solution as a possible answer to the problem. I understand that I don’t get the kind of response that maybe you’re waiting for, but once I can have a solution that goes through invoking either a function or an obggecto that someone else stuttered, I save a little bit of trouble. attentively, without any other subject

  • take a look at this https://github.com/krlgrgn/OpenGL-Particles

  • 2

    @Thiagomoraismorgado Read what permagreff said. The question here is not just getting the result, but knowing how to calculate. But even if using a third-party solution helped, your original answer just says "go and find another library that calculates it for you," which doesn’t answer either. It could be a comment at most. You can edit your reply explaining better what you meant by linking to the code you found and preferably some code or some indication of the snippet that solves the problem. This would work well as a complement.

Show 11 more comments

4 answers

38


Understanding the code

This is your code snippet:

for(int i = 1; i <= 1000 - Xpos; i += 1) {
    // tempo do projétil, que é calculado em base do I
    float t = i / (float) ((power + powerSalt[(int) power]) * Mathf.Cos(angle));
    // altura do projétil, calculada com base no tempo
    float Y = (float) (((power + powerSalt[(int) power]) * Mathf.Sin(angle)) * t - (0.5 * g * t * t));
    // adiciona o ponto obtido, abaixo no "i + Xpos" se ocasiona o ponto horizontal, então o "player.y + y" seria a cordenada vertical
    Vector3 point = new Vector3(Map.toWorldX((float) i + Xpos), Map.toWorldY(player.y + Y));

    // enfim, adiciona o ponto (x, y) da linha
    tracer.line.points3.Add(point);
}

The first line makes a loop that ranges from 1 to 1000, and you said yourself that this is the spatial limit of your playing field. So, the variable i represents a discrete division of the horizontal space, i.e., the values of the X axis (perhaps if tievsse called the variable i of x that would be even clearer).

The second line, already inside the loop, calculates the time. As the movement on the horizontal axis (X) is uniform (i.e., the speed of the horizontal movement is constant, i.e., there is no acceleration/deceleration), this time is calculated based on the following formula:

inserir a descrição da imagem aqui

Formula (2) is the trigonometric variation of the formula (1), and is the one you use in your code. After algebraic manipulation, and considering that the initial space is 0 (since everything begins at the origin), one has:

inserir a descrição da imagem aqui

In your case, space is i, and the speed is power + powerSalt[(int) power]. Naturally, as you have the angle (in radians), the angle cosine is Mathf.Cos(angle).

Once having the time that the projectile will travel to space i (note how the calculation is repeated for each crescent path), the third line calculates the position of the projectile on the Y axis (vertical) in time, using the formula of the uniformly varied motion (where the speed of vertical motion is not constant, as there is deceleration in the ascent and acceleration in the descent - the acceleration of gravity):

inserir a descrição da imagem aqui

The formula (4) is the trigonometric variation of the formula (3), and is the one used in the code. Again, the initial space is 0 (origin) and its velocity is power + powerSalt[(int) power] (yes, initially the same, although the actual speed is weighted by the acceleration at each time interval). In addition, the acceleration of gravity (commonly called g instead of a) is negative, since it pulls the projectile downwards (contrary to the launch direction). So there is a sign of - in place of singla de + in the code. The code line also does t * t to calculate the square of time, and multiply the gravity by 0.5 to divide by 2.

Note: it should be obvious that multiplying by 0.5 is equivalent to split by 2:

inserir a descrição da imagem aqui

Finally, in the fourth line of code, the point in two-dimensional space is constructed from the values of X and Y calculated earlier. Remember that X is the value given in i (its code adds such a Xpos I don’t know what it is, but it must be some fixed difference value). This line also mapped the X and Y values from a local metric to global as an object position adjustment player (that I suppose is the tank). This mapping is probably due to the use of these coordinates outside the scope of the tank (maybe the camera uses them, and therefore the mapping is necessary).

Adding wind

A rather simplified way of adding wind would be to consider it as an additional force which acts only horizontally, that it would be favorable (if it had blown in the same direction as the movement) or contrary (if it had blown against the direction of movement). As you said your wind only occurs on the X axis, simply add a positive (if favorable) or negative (if otherwise) value to your initial speed (that is, use power + powerSalt[(int) power] + <VELOCIDADE DO VENTO> wherever the speed appears). Even though the wind speed is only horizontal, it is not a problem to use its value also in the calculation of Y (the component of the vertical movement), since the position will be weighted by the inclination of the pitch angle.

If, on the other hand, the wind can have any direction and direction, I would say it is more appropriate for you to use vector algebra (considering both the velocity of the projectile and the wind velocity as vectors and adding them together to have the resulting vector for point-to-point application in the calculation of the trajectory). In that case, use the non-trigonometric versions of the formulae (formulae (1) and (3)), because the inclination angle will be "embedded" in the vector direction.

For example, suppose you have your projectile and wind velocity defined as vectors, as follows:

Vector2 veloc = new Vector2(10, 20)
Vector2 vento = new Vector2(2, 0);
Vector2 res = veloc + vento;

When making a vector sum you get a new vector (res) which is a "combined" speed. Note the graph below:

inserir a descrição da imagem aqui

The velocity vector of the projectile (veloc) is in purple, drawn from the origin (0, 0). The vector of the wind (vento) is in green, also drawn from the origin (0, 0). This same wind vector was also drawn from another origin, the "final tip" of the velocity vector (i.e., point (10, 20)), in a light blue, only to demonstrate graphically the idea of vector sum. The result of this sum is a new vector (res), drawn in red, resulting in point (12, 20). See how the resulting vector (in red) "points" to the same location as the "path" traveled by the two vectors that were added (purple + green).

In this example, the wind speed vector (vento) had a value of 0 in the vertical component (the value of Y), so it is a merely horizontal wind (as you can see clearly in the graph). But he could have any direction and sense. For example, if instead of blowing right horizontally with force 2, the wind blew northwest:

Vector2 veloc = new Vector2(10, 20)
Vector2 vento = new Vector2(-5, 7);
Vector2 res = veloc + vento;

The following resulting graph would have been:

inserir a descrição da imagem aqui

Note that the projectile’s original velocity (in purple) was affected by the wind (in green) to produce an appropriate resulting velocity (in red), as previously described.

If you use vectors instead of unique values for the speeds, you can use the above formulas to do something like this:

Vector2 veloc = new Vector2(10, 20)
Vector2 vento = new Vector2(-5, 7);
Vector2 s = 0 + (veloc + vento) * t - (g * t * t);

Note in the last line how the application of the physical formula (3) remains equal, with the difference that the resulting spatial value (s) is now a vector (which contains both components X and Y).

Also note that the variable g, that today in its code is a unique value, could also be a vector. "natural" gravity would be something like Vector2 g = new Vector2(0, -9.8) (remember that you would need to get back the signal from + in the formula calculation, since the negative sign is embedded in the vector direction), because it acts only on the Y axis and downwards. But you could even implement a different gravity in a space game, for example, doing something like Vector2 g = new Vector2(2, 7) (this crazy "gravity" in a game would pull everything up, and slightly to the right). :)

Finally, note that, although several people have commented, until today you don’t describe question how the projectile moves in your game. You say you use Unity, but you don’t explain whether the motion of the projectile is controlled by you (that is, doing the calculations in the same way as described so far and the translation manually), or whether you simply apply an initial impulse force and Unity physics takes care of the rest. Since "wind" is not a feature that exists natively in Unity physics, we would also need to know if the wind you say already works on the projectile (so much so that the actual stroke does not match what you draw) is constantly applied to the rigid body of the projectile by some code of yours. In the real world the wind is a constantly active force, similar to gravity, and is therefore constantly applied to the moving projectile. If you want to reproduce this, you will have to consider the wind not as a speed, but as an acceleration. In that case, it would make more sense to have something like:

Vector2 veloc = new Vector2(10, 20)
Vector2 vento = new Vector2(2, 0);
Vector2 g = new Vector2(0, -9.8);
Vector2 s = 0 + veloc * t + ((g + vento) * t * t);

That is, adding the vectors of wind acceleration and gravity to have the correct acceleration being applied at each time instant.

For information on formulas, see this website. If need, compare what has been explained here with the explanations in this my other answer.

  • 1

    @Cypherpotato Have you tried this approach? Explain if the result was as expected.

  • 2

    This is the most complete answer and the one that most adapts to the question, so it will be marked as correct, greatly facilitated the calculation, now all that remains is to convert these vectors to the coordinates on the map :P (I’ll try to do this, if I can’t, it’s another question :D). Thank you!

  • show, keep us updated!

  • 1

    @Cypherpotato vc approached the expected result with the answer?

  • 2

    I accidentally deleted the project... : P

26

Looking at your calculations we can see that you have two ways to do this, the easy (moving directly at speed) and the correct one is to create a endurance force. And also from what you see in your image the change in height is not caused by the change in angle. On this website you can see didactically that you can reach the same result in two different ways by changing either the velocity of the projectile or the air resistance.

Let’s start by imagining that the project you’re trying to copy uses the change in speed, so the question is, how do you change the wind by impacting the speed at which your projectile is launched?

The following answer is partial to get a complete answer we would need some (not necessarily all) of the following information I did not find in the description:

  • Distance units driven without wind
  • Distance difference with wind having a value of 71
  • The interval of force
  • The value of strength in the examples
  • Height units achieved without wind
  • Difference between wind and windless height

Remembering that if the strength in the chart displayed in the launch is not the same with and without wind, only the previous variables may not allow us to arrive at the desired result.

Since we don’t have the original definition to base ourselves on we have two options for the wind to have an effect on speed, the first is:

float force = (float) (pw + powerSalt[power]) + windForce(100);

While the second is:

float Vi = (float) (force + windForce(100)) * Mathf.Sin(angle);

where the function windForce has a definition similar to the following:

float windForce(int max){
 Random rnd = new Random();
 int random = rnd.Next(-max, max + 1);
 float force = random * constant;  
 return force;
}

Heed: Although we can apply the function in two places, I believe that the second option is incorrect, because it does not consider the change of force equally in all variables.

The only thing missing for this to work is to find the constant that multiplies the force, it needs to be relative to the interval of the force of the launch (so that the effect of the wind is not disproportionate). You can try to figure this out in trial and error (by kicking), but I recommend using the difference between height and/or distance traveled by the projectile in the same launch with and after without wind to reach the constant by applying oblique launch formulas. What I believe is quite simple to be applied because it is high school/pre-vestibular content.

In case this nobody in the O.R. Physics Stack Exchange someone can give you a hand to reach your desired constant.


Now that we have a partial response within the possible data, we can see how it would be the correct way to implement considering drag (originated from fluid mechanics), and as air is also a fluid this can be used. The main difference between calculating the wind force in this way when comparing with the form presented above, is that using the arasto the lower the speed, the lower the effect of the event applied to the projectile, that is, the wind force changes at each moment (In real life this is the same thing that doesn’t allow a skydiver to gain speed forever).

We have the arasto equation:

inserir a descrição da imagem aqui

Where F(D) is the strength of the arasto p is the density of Fluid v is the velocity of the object, A is the contact area C(D) is the drag coefficient.

There are some discussions but for a sphere another equivalent formula can be used. The equation for calculating the arasto of a sphere is known as Law of Stokes and it is as follows.

inserir a descrição da imagem aqui

Where the variables necessary for you to apply this formula are: Speed.

  • μ is the drag coefficient. (objects of different shapes have different drag coefficients)
  • R is the radius (the larger the object, the greater the resilience)
  • V is the current speed

Note that as previously said, if we increase the area, speed or arasto coefficient, the resistance force becomes greater. Because these values are considered in this case I seriously believe that this is not the approach adopted by your original game. Anyway I believe that in the answer you already have the minimum to calculate the arasto momentaneo, since you have the necessary values defined.

Also be aware that this approach will require you to calculate the arasto basically as a sum of each displacement from the previous displacement, not obligatorily to cada deslocamento but the closer the interval the more accurate the result, see more in reference 4, however the fact that we have to recalculate the value already enough to increase the computational cost.

I believe this is also one of the reasons why some game libraries that I found on the Internet use formulas that simulate the arasto’s behavior but in a similar way and not equivalent to the actual behavior caused by air resistance.

I hope it has helped to clarify your doubt and hope that when you arrive at an acceptable answer you can share with us.


Although I believe you already know something about so you could get to the current state of your game, you can check out some material on oblique release that might help you get a complete solution on the missing links.


References

1 - How do I generate a Random int number in C#? - English

2 - Arasto

3 - Arasto - In English (much more detailed)

4 - Falling Body with Air Resistance - English

22

It depends on the direction (or position) of the point that generates the wind. See in this example.I made a circle with uniform rectilinear motion and a wind source in a central region of the route. Note that during the time of the displacement the wind will act, at first accelerating the movement, then slowing the movement. Soon you can make a function to have random wind direction (if you want more excitement). Use var angulo Math.random()*360 if it is in JS. Angle can vary randomly between 0-360 degrees relative to the horizontal component of the offset. If you want to use fixed steering example 180 degrees (against movement) simply do var angulo=180. The rest is no longer programming but physical. It works in the same logic as a frictional force (if the direction is contrary to the movement. According to the laws of aerodynamics you apply deceleration or acceleration if you want to be precise or use constant acceleration wind force to facilitate. At this point it is only synples kinematics.

V=Vot(+/-)(Vt 2)/2. Let’s take into account only the horizontal component and vc extrapolates to the compound movement.

var angulo = Math.random()*360;//http://www.w3schools.com/jsref/jsref_random.asp
var Vx=0;
var Vy=0;
if(angulo = 0){//Movimento acelerado Vx
   Vx=VoxT+((Vxt^2)/2)
}
else if(angulo = 180){//Movimento retardado
   Vy=VoyT-((Vyt^2)/2)
}

//Note que 90 e 270 não interfere em Vx

Extrapolate to Vx or Vy, Vx and Vy, to make the game interesting.


Notice of amendment: Where I write var angulo - I’m referring to the angle of the wind with the horizontal component of velocity and not the angle of shot. Then it would be better to call the variable anguloV or even wind. Then it would look like this: var vento = Math.random()*360 to randomly calculate the veto action on the bullet. It has a physics-javascript library very cool, but I suggest searching others or create your own. Matter.JS

Other good examples of using mathematicalXphysicsXcription(javascript). Author Billy Lamberta.

Trigronametry for animations

  1. Rotate an object around a point - using the mouse. Ex, code.
  2. Smooth vertical movement. Ex, code.
  3. Application, speed and center of displacement. Ex, code.
  4. Mov in wave form. Ex, code
  5. Pulse mov. Ex, Code.
  6. Wave mov using 2 angles. Ex, code.
  7. Draw a wave. Ex, code.
  8. Circular uniform mov. Ex, code.
  9. Mov Elliptical. Ex, code.
  10. Pythagorean theorem - calculate point distance. Ex, code.
  11. Distance between point and mouse. Ex, code.

Speed and acceleration

  1. MU 1 axis. Ex, code.
  2. MU 2 axes. Ex, code.
  3. Angular mov following the mouse. Ex, code.
  4. Rotation. Ex, code.
  5. MUV 1 axis. Ex, code.
  6. Interactive acceleration (this is very good). Ex, code.
  7. MUV 2 axes - Interactive. Ex, code.
  8. Gravity - Interactive. Ex, code.
  9. Mouse-guided angular acceleration. Ex, code.
  10. Spacecraft - Ex, code.
  • 1

    Your answer does not make sense with my question. I already have the formulas ready, in this same formula a guy implemented wind but I do not know how. The variables VoxT and VoyT are also not stated in my context, something exact.

  • The cara who made his formulas implemented wind in the last line float y = (float) ((Vi * t) - 0.5 * g * Math.Pow(t, 2)); with the negative sign. Intreferindo in Vy and consequently in the distance y and dx. His formula does not interfere in Vx. I thought your question was how to implement the wind action and not show where the wind action is.

12

Dude, if your project is from a college where calculations should be calculated as an engineer would "calculate" in real life taking into account physics variables and so on, disregard what I’m going to tell you, but if you just need logic you can try this...

I would indicate that the wind can range from -100 to 100 (having 0 as without wind, 1 with very strong wind in favor and -1 with very strong wind against), multiply this value by the time the projectile would stay in the air and add an X as effect/scale variable, increasing or decreasing as you wish, would add the product in strength.

From what I understand, your projectile doesn’t fly, you just need the line, neah? This might work.

The X would act as a gauge of the intensity of the physics of the wind on the projectile, if you want the projectile to suffer much influence, increase... if you want it to suffer little influence, decrease.

  • How do I calculate the time the projectile would be in the air? The variable t what do you refer to? In what mode of time? Milliseconds? Seconds? Minutes? Could be explicit?

  • I didn’t have a stackoverflow account and I just created it, so I can’t comment... I’m the Vitor who replied. haha. So man, as for the time I referred to variable T, however, you can put as long as it gets better... Wind = 30 <br> Time = 2 <br> X = 1.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.