setVelocity(<Vector>) and Parabolic Motion

Discussion in 'Plugin Development' started by Donald Scott, Jul 15, 2012.

Thread Status:
Not open for further replies.
  1. Offline

    Donald Scott

    Vector start = currentlocation.toVector();
    Vector destination = somelocation.toVector();

    The goal? Go from start to destination in a parabolic arch.

    We know that in Minecraft: g=18m/s^2

    It's easy to get some basic calculations for a 2d plane:
    double deltaZ = destination.getZ() - target.getZ();
    double deltaX = destination.getX() - target.getX();
    double angle = Math.atan2(deltaY, deltaX);

    But really how do I go about launching the player and making them land on the destination when we evoke the setVelocity method?

    Any ideas?

    Yes, obviously this requires physics and some real thinking. ;)

    ModEdit (c0mp): Removed monetary discussion, per Bukkit TOS and Rules
     
  2. Offline

    meme.eater

    I don't have access to my computer right now, but I can give you a general algorithm for doing this. I hope this will be helpful.

    Remember the kinematics equation:

    Final Position = Initial Position + Initial Velocity*Time + .5*Acceleration*Time^2

    You can rearrange this equation into a standard quadratic equation (ax^2 + bx + c = 0)
    A = .5*Acceleration
    B = Initial Velocity
    C = Initial Position - Final Position
    -Or-
    A = .5 * -18 (Minecraft's value of g)
    B = Initial Y velocity (You get to choose! Choose something positive that will allow players to clear mountains and obstacles, etc.)
    C = Initial Y - Final Y

    Plug these values into the quadratic equation, and solve. The positive solution is the one we want. This is the amount of time the player will be travelling through the air.

    Next, use the kinematics formula above to solve for the initial velocity you want to impart to the player in the x and z axes. No need for inverse trig here!

    The only part that may be tricky here is the reverse acceleration due to air friction, which will play a huge role in long flights. I recommend playing around with this until you can get a good landing accuracy.

    The initial and final x/z positions, time, and acceleration (due to air friction) are all known. All that's left to do is solve for the initial velocities in the x/z axes.

    After doing all this, you should have the player's launch velocities in the three axes.

    Due to lag and rounding errors, the player may veer from the calculated course. If this happens, you may have to teleport the player to their correct position after landing. For a distance of several blocks, this should not be a problem and the slight nudge will be acceptable.

    I don't have anywhere to put a hundred bucks right now, sadly. If I helped you, I would be grateful for a server sponsorship, as I have no other visible means of gathering funding for one.

    Email me at [email protected] if you have any other questions.
     
    Chr0mosom3 likes this.
  3. Offline

    Donald Scott

    Yea I (kindof) figured it out. The real issue is that air resistance is calculated per block in minecraft which makes it difficult to accurately predict. I will also add that a raft player DOES NOT accelerate downward at 18 m/s^2 when the player also has forward motion.

    Thanks!
    -Don Scott
     
  4. Offline

    meme.eater

    Sorry for the double-post, but the other post is getting quite long. :D

    If you would really prefer actual Java code, just ask.
     
  5. Offline

    Donald Scott

    No, I have working code already. ;)
     
  6. Offline

    meme.eater

    Oh... right. I ran a test on level ground, and my player was landing about one block short of the landing spot on a 20-block launch. This is highly consistent, happening at all angles (even diagonally). Right now, I have no air resistance fudge factor. I am sure that without calculus, it will be extremely difficult to convert the 0.999389...blahblahblah... speed multiplier per tick into m/s^2. Stupid Notch. You will probably be forced to trial-and-error on this part.
     
  7. Offline

    Omnitv

    Im sorry but I specifically came here not to learn math.
     
    Chr0mosom3 likes this.
  8. Offline

    meme.eater

    Tested with much greater distances (~100 blocks?) and was disappointed. Varying the launch distance by just one block caused wildly varying rates of error. 100 blocks, 4 block error. 101 blocks, 3 block error. 102 blocks, 4 block error. WTF? I will probably resort to in-flight correction, by sending "perfect" positions and velocities every 100 milliseconds or so. Which leads us to... derivatives.

    I'm curious as to what you need this for. I'm working on a plugin that makes item fountains (water items shoot out of one hole, fall into another and despawn). The physics for items are much more reliable, and the distances required are minimal, so my code is more than sufficient for my purposes. I would be happy to keep helping you with yours though.


    BTW, I realized why Minecraft clones like Steincraft and Eden World Builder (on ios) feel so "bouncy". They try to use the real-world value of g (9.8) instead of Notch-g (18), so you stay in the air longer. Minecraft throws physics in the trash in an effort to be more playable.

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: May 27, 2016
  9. Offline

    Ellacohed

    how does this get 10 comments afeter like 20 mnutes and mine getnone???? can someone help me????
     
  10. Offline

    ImminentFate

    Firstly: Wrong section :p - should be under Plugin Development
    Secondly: Will not work, since players can move while in the air, unless you prevent that.
    Major Issue with this: What if you're sending a player to a location underground? You'd be screwed then, lol.
     
  11. Offline

    c0mp

    Moved to Plugin Development
     
  12. Offline

    andf54

    From where are you getting this?

    I suspect that g=0m/s^2, because mc doesn’t seem to have any acceleration. It seems that when an entity falls it moves with constant speed.
     
  13. Offline

    meme.eater

    That is due to Minecraft's "air resistance", which causes a terminal velocity just like in real life. I can assure you that objects fall faster over time.
     
  14. Offline

    andf54

    You are right. Did an experiment and verified it.

    I'm not sure how air resistance works. Does the air resistance decrease the speed by 0.0001 block/s per block? (<-random number)

    Tried to solve the problem for downward motion. The resulting differential equation was solvable.
    Here are the results:
    Differential equation: dy/dt = -g t + K y (It's supposed to be K*speed! Damn you Notch!)
    Solution: y = 18/K^2 + 18 y / K - 18 exp(K t) / K^2
    K is the speed reduction per block.
    The solution has weird behaviour at large t and isn't usable when K = 0, but gives reasonable results.
    Graph:
    http://www.hot.ee/lostinthecraft/down.jpg


    @Donald_Scott meme.eater
    I cant help you if I don't know how you calculate the target.
     
  15. In the latest video from SethBling he created a filter for MCedit doing the same. I ported it from the python script to Java. All credits go to him.

    But keep in mind that this is for the potion gravity only. And I did not test it at all, gonna test it tomorrow.

    Code:java
    1. import org.bukkit.util.Vector;
    2.  
    3. public class VelocityUtil
    4. {
    5. public static Vector calculateVelocity(Vector from, Vector to, int heightGain)
    6. {
    7. // Gravity of a potion
    8. double gravity = 0.115;
    9.  
    10. // Block locations
    11. int endGain = to.getBlockY() - from.getBlockY();
    12. double horizDist = Math.sqrt(distanceSquared(from, to));
    13.  
    14. // Height gain
    15. int gain = heightGain;
    16.  
    17. double maxGain = gain > (endGain + gain) ? gain : (endGain + gain);
    18.  
    19. // Solve quadratic equation for velocity
    20. double a = -horizDist * horizDist / (4 * maxGain);
    21. double b = horizDist;
    22. double c = -endGain;
    23.  
    24. double slope = -b / (2 * a) - Math.sqrt(b * b - 4 * a * c) / (2 * a);
    25.  
    26. // Vertical velocity
    27. double vy = Math.sqrt(maxGain * gravity);
    28.  
    29. // Horizontal velocity
    30. double vh = vy / slope;
    31.  
    32. // Calculate horizontal direction
    33. int dx = to.getBlockX() - from.getBlockX();
    34. int dz = to.getBlockZ() - from.getBlockZ();
    35. double mag = Math.sqrt(dx * dx + dz * dz);
    36. double dirx = dx / mag;
    37. double dirz = dz / mag;
    38.  
    39. // Horizontal velocity components
    40. double vx = vh * dirx;
    41. double vz = vh * dirz;
    42.  
    43. return new Vector(vx, vy, vz);
    44. }
    45.  
    46. private static double distanceSquared(Vector from, Vector to)
    47. {
    48. double dx = to.getBlockX() - from.getBlockX();
    49. double dz = to.getBlockZ() - from.getBlockZ();
    50.  
    51. return dx * dx + dz * dz;
    52. }
    53. }
     
  16. Offline

    chasechocolate

    SethBling makes my mind explode... Again... :p
     
    ChipDev likes this.
  17. For anyone who wants to see this code in action, here is the video from SethBling... Any btw, this is the gravity for snow: 0.075

     
    fromgate likes this.
  18. Offline

    fromgate

    Hellsing

    This video and code looks great.

    I'm trying to calculate parabolic motion velocity for players.

    But... did you know how was found gravity constant for potion bottle? I picked a value 0.18, looks like it works right. But how I can calculate it rather than guessing?

    Another question is player's horizontal acceleration. It looks like player need more boost than a potion entity, so I think there must be an additional multiplier that will be used in addition to slope variable to increase player horizontal acceleration?

    Any idea how I can calculate this multiplier?
     
  19. Offline

    LucasEmanuel

    Very interesting, this should be moved to the resource section if you ask me :)
     
    fromgate likes this.
  20. Offline

    fromgate

    LucasEmanuel
    I will agree with you.. after finding answer to my question :D
     
    PQE likes this.
  21. Offline

    Garris0n

    Either look at the code or make something that prints out their velocity every tick?
     
Thread Status:
Not open for further replies.

Share This Page