Vector Programming for Beginners

Discussion in 'Wiki Discussion' started by jflory7, May 26, 2015.

  1. jflory7

    jflory7 Retired Moderator
    Retired Benefactor

    Vector Programming for Beginners

    Vector Programming for Beginners

    Learn what vectors are and how understanding them will benefit your code

    What is a vector?(top)

    A vector is represented by a length and a direction and always describes a movement from one point to another. Most of you will already have heard about vectors or seen some strange arrows representing them. Let's have a look at the vector in Spigot.

    The vector in Spigot(top)

    The vector in Spigot can be found in org.bukkit.util (JavaDoc) package and can be created the following ways:

    Code (Java):
    Vector v = new Vector();  //Creates a vector with length 0 and NO direction
    Vector v = new Vector(x, y, z);  //Creates a vector with defined direction and length
    Each vector has three values that represent the vector, called X, Y, and Z (the 3 directions). Also important to know is that you can get the length of a vector by calling .length() and subsequently get / set the value of every axis by calling .getX(), .getY(), .getZ(), and .setX(x), .setY(y), .setZ(z).

    What is the use of a vector in Spigot?(top)

    Whenever an entity moves or the target you're are looking at has to be calculated, a vector is used. At the end of this tutorial, you should be able to do both.

    Let's explain the possible calculations.

    * The blue arrow is always the result of the calculation.


    This calculation is very basic. You got one arrow and add it to another. Lets code it!

    Code (Java):
    Vector first = new Vector(1, 3, 2);
    Vector second = new Vector(3, -1, 4);

    // Let's add them together!

    Vector result = first.add(second); // Result is now a Vector of 4, 2, 6
    // NOTE: The #add method modifies the vector it's called on
    //       Thus, result and first now refer to the same vector
    In order to avoid changing the vector, one needs to clone it first using the Vector#clone method.



    The second simple (and essential) calculation. Just multiply the length of the vector. When the value given is NEGATIVE, the vector switches its direction.

    Code (Java):
    Vector v = new Vector(3, 4, 2);

    Vector result1 = v.clone().multiply(2);  // Vector of 6, 8, 4
    Vector result2 = v.clone().multiply(-1); // Vector of -3, -4, -2
    // NOTE: Since the multiply method modifies the vector,
    //       we need to clone it in order to get a new one
    As you see, every value of the vector is being multiplied with the value you specify.


    Sets the vectors length to 1. For example, you have a vector (3, 3, 3). Then, its length is the √( (3*3)+(3*3)+(3*3) ) = √(27) = 5.19, so the vector's length is 5.19.

    Normalizing now has to divide the vector's length by its length to get the resulting vector. So normalizing calls .multiply(1/5.19) resulting in a vector of (0.57, 0.57, 0.57).

    Code (Java):
    Vector v = new Vector(3, 3, 3);

    Vector result = v.normalize();  // Returns vector of length 1 and movement of 0.57, 0.57, 0.57



    This calculation returns a vector that is orthogonal to both of the previous vectors. Its length is the area of the light blue parallelogram. This can be used to compare if two vectors are nearly the same (for example, when targeting a player).

    Code (Java):
    Vector first = new Vector(1, 2, 3);
    Vector second = new Vector(-7, 8, 9);

    Vector result = first.crossProduct(second); // Will return vector of -6, -30, 22
    Source of example: Wikipedia (didn't want to draw these brackets)


    This is easy! Take one vector, add it to another, and divide by 2. Then you have your midpoint!

    You have two vectors, the black and the orange one. You add them together and get the green vector. You divide the green vector by 2 or multiply it by 0.5 and get your midpoint.

    Code (Java):
    Vector first = new Vector(1, 3, 4);
    Vector second = new Vector(4, 3, 1);

    Vector midpoint1 = first.midpoint(second); // Vector of 2.5, 3, 2.5
    Vector midpoint2 = first.add(second).multiply(0.5); // Vector of 2.5, 3, 2.5
    Now you know how to use vectors! Time to practice a bit!


    Let's check if a player targets another location!

    Code (Java):
    public boolean doesPlayerTarget(Player p, Location target){
            //p is your player
            //target is the location the player might target

            //Check if they are in the same world
            if(!target.getWorld().equals(p.getWorld()))return false;

            //Let's begin!
            //Get the players head location
            Location head = p.getLocation().add(0, p.getEyeHeight(), 0);
            //Get the players looking direction as vector and
            // shorten it to a length of 1 by using normalize()
            Vector look = p.getLocation().getDirection().normalize();

            //Get the direction of the target from the player by substracting his location with the target
            //Again use normalize() of course, to shorten the value
            Vector direction = head.subtract(target).toVector().normalize();

            //Lets build our crossProduct. When the crossProduct's length is 0, the player
            //is exactly targeting our target location
            //why? because then the parallelogram shown above has an area of 0 :)

            Vector cp = direction.crossProduct(look);

            //Lets get the length from the vector
            double length = cp.length();

            //If the length is bigger than 0.1 the player is probably
            //Not targeting our location. Choose this value appropriate
            return (length < 0.1);
    #1 jflory7, May 26, 2015
    Last edited: May 27, 2015
    • Like Like x 6
    • Useful Useful x 3
    • Informative Informative x 2
  2. jflory7

    jflory7 Retired Moderator
    Retired Benefactor

    Thanks for the contribution, @Friwi! :) I created a discussion thread for your wiki article.
  3. First one here! :eek:
    • Like Like x 2
    • Friendly Friendly x 1
    • Optimistic Optimistic x 1
  4. Don't forget you can use vector manipulation to make black holes, :p
    • Funny Funny x 1
    • Winner Winner x 1
  5. jflory7

    jflory7 Retired Moderator
    Retired Benefactor

    I wiki-ified the article and made it a little more organized. :)
    • Like Like x 2
  6. Can vectors manipulate anything? And I mean ANYTHING?
  7. Any something that has kind of movement or direction. You can give movements to stuff too.
  8. Flying cows and sheep?
  9. Yeah, you can do that.

    Code (Text):
    public void makeFly(final EntityLiving e){
       new BukkitRunnable(){
          public void run(){
             e.setVelocity(new Vector()); //new Vector() is vector of 0, 0, 0
       }.runTaskTimer(PLUGIN, 1, 1);
  10. With this someone can make a plugin so that wherever a player walks it throws mobs into the air :eek:
  11. Thanks been looking for this!
  12. Awesome, thank you!
  13. graywolf336


  14. I've noticed that almost all operations that return a vector actually modify the vector you call them on, such as multiply() and most disgustingly crossProduct(). This behavior has cost me hours of time trying to debug code (thanks to Bukkit's atrocious javadocs). For example:
    Code (Text):
     public Vector crossProduct(Vector o) {
            double newX = y * o.z - o.y * z;
            double newY = z * o.x - o.z * x;
            double newZ = x * o.y - o.x * y;

            x = newX;
            y = newY;
            z = newZ;
            return this;
    The easiest solution is to simply call clone() after every vector that you don't want to mess with. Inefficient, but necessary since the behavior has become a feature (plugins rely on it, anyways).

    This is otherwise a very nice tutorial, but unfortunately the results are all going to be wrong because the Bukkit methods modify the left hand operand, making everything a +=, -=, *=, /=, x=, etc operation.
    • Agree Agree x 1
  15. I'd quite imagine the above is due to pass by value of reference. Whoever thought that was a good idea for vectors does indeed need to be shot, though. You should consider the object you are getting as the object and not a copy unless stated otherwise.