Parabolic motion with maximum distance

Discussion in 'Plugin Development' started by Betagear, Dec 14, 2015.

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

    Betagear

    Hi.
    I just wanted to make some kind of thing that would fire a block down at a certain speed and would then go back up, by using vectors, but I do not know how vectors reacts when added to a location.
    The movement would be the exact opposite of when you throw something in the air, with the exception that the second part of the movement (when it goes back) would be slower than the launch.
    It would be in limited time, and 1/3 of the time would be used to go down to a certain postion, then the remaining 2/3, the block would go back up to one block upper than the starting postion.
    So, anyone knows how I could do that ?
    Or just tell me how vectors reacts with locations.
    By exemple, if my location is (50, 50, 50) and I add the vector (0, -1, 0), what will the final location be ?
     
  2. Offline

    mcdorli

    The location IS a vector. In programming, a vector has an x, a y, and a z value. If you add a vector to a vector, then you basically add the x to the x, the y to the y, etc.
    basically,
    (50, 50, 50) + (0, -1, 0) = (50 + 0, 50 + -1, 50 + 0) = (50, 49, 50)

    BTW.: You should learn about vectors (and matrices if you like to), at least the part you understand. They open a bib gate in programming
     
    ChipDev likes this.
  3. Offline

    Betagear

  4. Offline

    mcdorli

    I extend my post above with this little code snippet I got from the official github page
    Code:
    public Location add(Vector vec) {
        this.x += vec.getX();
        this.y += vec.getY();
        this.z += vec.getZ();
        return this;
    }
    
    
    I think you see, what's happening there.
     
    ChipDev likes this.
  5. Offline

    Betagear

    Well, I tried to do it, but i don't find the solution to it in a function.
    It would be, as stored as : Time, Yvelocity, DistanceY
    0, -1, 1 -> 1/3 Time, 0, MaxDistance -> Time, 1, 0
    Can anyone tell me how I should do that to place a block at each point of the course of this vector, considering 2 variables (Time and MaxDistance) ?

    @mythbusterma Well, using a vector to store 3 data is more sexy than using one for each.
    As functions, I think i'll use (x^[1/3] -1) * -distance from 0 to 1/3, then i'll use (x^[3] -1) * -distance with x ranging from 0 to 1 appropriately.

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Nov 26, 2017
  6. Offline

    mythbusterma

    @mcdorli

    Actually, in programming, a Vector is a data structure that is irrespective of the types of data contained within it (similar to an ArrayList in Java). Ex: https://en.wikipedia.org/wiki/Sequence_container_(C++)#Vector

    In Bukkit, it is a 3D vector that follows the more general definition of a vector, a sequence of numbers, particularly, a member of R3 vector space.

    @Betagear

    I don't understand why everyone thinks Vectors are so magical. It is a series of numbers that represent X, Y, and Z. Adding together two vectors simply adds the corresponding components of the two Vectors.

    A Vector can be used to represent many things, as it is just 3 numbers put together. A few common examples are offset from zero, a.k.a. location, velocity, and direction (usually represented by a unit vector, i.e. a vector that has been normalised).

    A Vector, however, cannot represent a trajectory. Which is what you're trying to make it do. Also, all entities on Minecraft are affected by drag and gravity differently, so you would have to know what you want it to behave like (or make up some numbers to have it behave in it's own way).

    So, to define a trajectory absolutely, you need: a starting location, a drag constant, an acceleration vector, and an initial velocity vector. These make up the parts of the newtonian position equation (except the drag component):

    [​IMG]

    By using those you can find the position at any point in time, and therefore estimate the trajectory of an object (assuming no drag).

    There's two issues with this:
    1. This does not consider drag. To consider drag in the equation you would need to do some calculus (or look up the equation after it's solved on the internet).
    2. The Minecraft world is not static and it is impossible to deterministically determine the the trajectory of an object before the trajectory is complete. For example, a block might be placed in the way, a Creeper might be in the way, etc.
    To alleviate these problems, you can not determine the trajectory beforehand, and instead just move the entity along a path each tick, moving it by it's velocity and adding the acceleration to the velocity.
     
  7. Offline

    mcdorli

    Sorry, I make myself clear. I meant graphical programming.
     
  8. Offline

    mythbusterma

    @Betagear

    Literally no idea what you said. I didn't say to not use Vectors?
     
  9. Offline

    Betagear

    @mythbusterma Don't worry, I'll not use vectors anymore, just functions, as they can handle curves very well and more simply.
     
  10. Offline

    mythbusterma

    @Betagear

    Again, you're not making any sense at all. They are not alternatives to one another, and it's pretty ambiguous what you mean by "function." It could have two meanings in the context, one mathematical and the other programatical, either way, they don't serve the same purpose as a vector, as a vector is merely a collection of numbers, and a function is a relation of numbers.

    You would need to use a function on each element of a vector, as the motion/acceleration is not uniform.
     
  11. Offline

    mcdorli

    You need:
    1 gravitational vector (in minecraft, it should be (0, 10, 0) or (0, 9.88, 0))
    1 speed vector
    1 location vector

    each frame add the gravitational vector to the speed vector, and then the speed vector to the location vector. That's it.
     
  12. Offline

    Betagear

    @mcdorli Ok, but how can I calculate the speed to make the block go to a certain point at a certain time ? There would be slower movements, who would need to get to a certain point.
     
  13. Offline

    mcdorli

    I don't really know. Ask somebody, who have higher education than me (I'm in 1st class in high school, so...), like @mythbusterma or @timtower
     
  14. Offline

    CraftCreeper6

  15. Offline

    Betagear

    @CraftCreeper6 Thanks so much for that amazing answer.

    @mcdorli I'm in 1st class too :)
    Speed : 1 (means 1 block/tick)
    Gravity : Speed*Distance/Duration
    After each tick, add -Gravity to Speed, and then it would be good.
    I think.

    So, in my case (Just speaking to myself) :

    Having maxduration, distance as values as inputs
    speed and grav
    • First third :
      • speed : 1
      • grav : 1*(distance-1)/(maxduration/3)
    • Then :
      • grav : 1*distance/(maxduration*2/3)
    And it should work, normally.
     
    Last edited: Dec 15, 2015
  16. Offline

    CraftCreeper6

    @Betagear
    That's fine. Here I'll finish the line for you. </sarcasm>
     
  17. Offline

    mythbusterma

    @Betagear

    Since when is acceleration measured in m^2/s^2, did you even bother to read what I said?

    You don't understand enough physics to be doing this.

    No, I don't think you understand what I'm trying to say. The maximum duration of the flight has no bearing on the rate at which it flies, unless you are scaling the speed based on how long it will take so that it will always go the same distance.
     
  18. Offline

    Betagear

    @mythbusterma That's what i'm doing. And it's not an entity so it's ok, nothing will pull it except my plugin.
     
  19. Offline

    mythbusterma

    @Betagear

    That's fine, still has nothing to do with what I said.
     
  20. Offline

    Betagear

    I used that :
    Code:
        private Location NextLoc() {
            if (currentduration < maxduration /3) {
                grav = (distance)/maxduration/3;
            }else {
                grav = distance/maxduration*2/3;
            }
            currentlocation.setY(currentlocation.getY() - speed);
            System.out.println("Grav : " + grav);
            speed = speed - grav;
            currentduration++;
            return currentlocation;
        }
    but grav is always equal to 0 but it is a double. How and why is it hapenning ?

    EDIT : Changed duration and distance to double, and it works.

    Well, now it's working but the block is going back up too fast.

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Dec 16, 2015
  21. Offline

    mythbusterma

    @Betagear

    I can't even follow what that suppose to do. Completely unreadable code, and doesn't really correspond to any real-world physics. So I couldn't help you.
     
  22. Offline

    Betagear

    @mythbusterma Well, I tried a lot of way to do it, it looks like having 2 arguments can't be possible. I removed distance and it worked well.
    It does that :
    But I can't make it go down as I would have liked.
     
  23. Offline

    mcdorli

    So, does that work like you wanted?
     
    Last edited: Dec 17, 2015
  24. Offline

    Betagear

    @mcdorli Yep. I fount a way.
    First, Grav = 2.0/maxduration and Speed = -1
    This will create a simple parabolic motion that will go away then go back in the certain time.
    Code:
        private Location NextLoc() {
            double divider = 2;
            double grav = divider/maxduration;
            currentdistance = currentdistance - speed;
            speed = speed - grav;
            currentduration++;
            return block.getLocation().add(0, currentdistance * distancemultiplier, 0);
        }
    Then, if you want to make it go to a certain distance, pre-calculate it, get the max distance form the starting point you can get.
    Then, divide the distance you wanted to get by the maximum distance you got, and multiply all the distance you get then when reloading by this one.
    Code:
                double gravt = 2.0/maxduration;
                double speedt = 1;
                double distancereached = 0;
                double distancet = 0;
                while (distancet <= distancereached) {
                    distancet = distancet - speedt;
                    speedt = speedt - gravt;
                    if (distancet < distancereached) {
                        distancereached = distancet;
                    }
                }
                distancemultiplier = Maxdistance / (-distancereached);
    I'm sure this code will help some people.
     
  25. Offline

    ChipDev

    You just busted a myth. Nice
    What does that L shape symbol do that looks like:
    t
    -
    /
    |
    |
    /
    -
    0

    Just from a math standpoint: what are they called?
     
  26. Offline

    CraftCreeper6

    @ChipDev
    You'll get it when you do calculus.

    It's to do with integrals.
    "∫ f(x) dx means a function whose derivative is f."
     
    ChipDev likes this.
  27. Offline

    Zombie_Striker

  28. Offline

    mythbusterma

    @ChipDev

    It's an elongated 'S,' and it comes from an abbreviation of "summation." It is denoted this way because it refers to the summation of all the values of a curve, each over an infinitesimal area (read: area under a curve). This allows us to relatively simple algebra and translate an acceleration graph into position and velocity.
     
    ChipDev likes this.
Thread Status:
Not open for further replies.

Share This Page