Solved Finding out how much to add to a vector

Discussion in 'Plugin Development' started by afistofirony, Sep 23, 2013.

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

    afistofirony

    Hey. I've been doing some pretty complex math lately, but I'm a bit stuck at this point. I'm creating a ray-trace function (somewhat like in Bukkit, but independent of the blocks aspect), and I've been having issues figuring out how much to add to a vector per unit traveled.

    If that's as confusing to you as it is to me, let me explain:

    I have a function with which a user can specify a block a certain distance away. So, I have to find a Vector which can translate their location to a vector. This function is actually quite simple:

    Code:
    Vector increment;
    result.add(increment.getX() * dist, increment.getY() * dist, increment.getZ() * dist);
    The only issue I'm having is calculating an appropriate vector.

    Let's say the player is looking straight up. In this case, the vector would be (0, 1, 0): For every unit the ray-trace travels, the x and z components aren't changed, but the y component is increased by one.


    So the challenge here is trying to find out how much to increment X, Y, and Z based on yaw and pitch (so that the distance between a zero vector and a vector with these three components is 1). Here's my current code (I'm not very good with this kind of math yet):
    Show Spoiler
    Code:
    public Vector trace (double distance) {
     
            Vector result = this.clone();
     
            while (pitch > 90) pitch -= 90;
     
            double yaw = this.yaw;
            Quadrant quad = Quadrant.getByDegree(this.yaw);
     
            while (yaw > 90)
                yaw -= 90;
     
            double x, z, y = Math.cos(pitch);
     
            switch (quad) {
                default:
                case I:
                case III: // x increment is parallel to x axis, so z incr. must be difference between yaw & 90
                    x = Math.cos(yaw);
                    z = Math.cos(90 - yaw);
                    break;
     
                case II:
                case IV: // x increment is perpendicular to x axis, so x incr must be difference between yaw & 90
                    x = Math.cos(90 - yaw);
                    z = Math.cos(yaw);
            }
     
            // need this to compensate for vectors that point to negative infinity
            x *= quad.properValue(false);
            z *= quad.properValue(true);
     
            result.add(x * distance, y * distance, z * distance);
     
            return result;
        }
     
        enum Quadrant {
            I, II, III, IV;
     
            static Quadrant getByDegree (double deg) {
                while (deg >= 360)
                    deg -= 360;
     
                if (deg <= 90) return I;
                if (deg <= 180) return IV;
                if (deg < 270) return III;
     
                return II;
            }
     
            double properValue (boolean z) {
                switch (this) {
                    default:
                    case I: // +x, +y
                        return 1;
     
                    case II: // -x, +y
                        return z ? 1 : -1;
     
                    case III: // -x, -y
                        return -1;
     
                    case IV: // +x, -y
                        return z ? -1 : 1;
                }
            }
        }


    Any ideas? Any help is much appreciated. :)
     
  2. Offline

    nisovin

    You can get a vector of unit one that points in the direction the player is facing very easily. It's just player.getLocation().getDirection(). So, if you have a Vector v, and you wish to add one unit in the direction the player is facing, you simply add the vectors:

    v.add(player.getLocation().getDirection());
     
    afistofirony likes this.
  3. Offline

    afistofirony

    Ahh, okay. Thank you very much! :D
     
  4. Offline

    TehVoyager

    afistofirony I'm having problems with vectors so i was looking around and I found this. Sense you solved yours I wanted some help.
    I want to make the player go forward 2 blocks when they click an item, I have the item could be I need a direction or 'F'. I can't use player.getLocation().getDirection() because if they are looking up it launches them up. thanks
     
  5. Offline

    afistofirony

    TehVoyager Well, based on the source code of Bukkit's Location class, you can try something like this:

    Code:
            double rotX = yaw, rotY = pitch, cosY = Math.cos(Math.toRadians(rotY));
     
            double x = (-cosY * Math.sin(Math.toRadians(rotX))), z = (cosY * Math.cos(Math.toRadians(rotX)));
     
            return new Vector(x, 0, z);
    This way you don't have any vertical output. You may even want to try small amounts (like 0.15) to launch them a little bit off the ground as if they were "hopping".
     
  6. Offline

    Janmm14

    TehVoyager
    use player.setVelocity(player.getLocation().getDirection().setY(0).normalize().multiply(howFar));
    the value of howFar need testing
     
Thread Status:
Not open for further replies.

Share This Page