Use Math.cos and Math.sin to rotate even in Y axis

Discussion in 'Plugin Development' started by Unknown123, Nov 7, 2017.

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

    Unknown123

    I have code to rotate a Location so the particles will spawn particles left and right at the player.
    But I also want to Rotate it on the Y axis so if my head is moved, the particles are also moved.
    Code:
    Code:
                    double offset = 0.5D;
                    for (double x = 0D; x <= 20; x++) {
                        for (double y = 0D; y <= 20; y++) {
                            double angleYaw = Math.PI * 2D * (loc.getYaw() + 180D) / 360D;
                            double anglePitch = Math.PI * 2D * (loc.getPitch() + 90D) / 180D;
                            Location particleLoc = new Location(world,
                                    loc.getX() + (x * offset - 20D / 2D * offset) * Math.cos(angleYaw),
                                    loc.getY() + (y * offset - 20D / 2D * offset),
                                    loc.getZ() + (x * offset - 20D / 2D * offset) * Math.sin(angleYaw));
                            p.playEffect(particleLoc, Effect.HEART, null);
                        }
                    }
     
  2. Offline

    MightyOne

    Have you tried (y * offset - 20D / 2D * offset) * Math.sin(anglePitch) ?
     
  3. Offline

    Side8StarLite

    @Unknown123
    Do you mean when you turn your head left and right, or up and down?
    I used a few methods for rotating particles; I used this one to turn particles left and right based on a yaw.
    Show Spoiler

    Code:
    
        public static Location turnAboutY(Location loc, double yaw)
        {
            double yx = loc.getX();
            double yz = loc.getZ();
            double x = loc.getX();
            double z = loc.getZ();
            z = yz * Math.cos(yaw) - yx * Math.sin(yaw);
            x = yx * Math.cos(yaw) + yz * Math.sin(yaw);
           
            Location location = loc.clone();
            location.setX(x);
            location.setZ(z);
            return location;
        }

    If you're talking about up and down AND left and right, the way I approached this is to make the particles face south (positive z), turn the coordinates about the x axis (the horizontal axis parallel to you, if you're facing south) , THEN turn the particles around the Y axis using the above methods.
    The following is the method I used to turn locations about the x axis
    Show Spoiler

    Code:
        public static Location turnAboutX(Location loc, double pitch)
        {
            double py = loc.getY();
            double pz = loc.getZ();
            double y = loc.getY();;
            double z = loc.getZ();
            z = pz * Math.cos(pitch) + py * Math.sin(pitch);
            y = py * Math.cos(pitch) - pz * Math.sin(pitch);
           
            Location location = loc.clone();
            location.setY(y);
            location.setZ(z);
            return location;
        }

    The above methods rotate a location about the origin, so you'll have to do a little more math to center it around a player.
    In addition, I found this and this post also interesting, if you need some more explanation.
    Apologies if this is considered spoonfeeding :p.
     
  4. Offline

    MightyOne

    Ok i founf a solution but maybe try it out yourself:
    First I converted the x and y of the postion of your partivle to a org.bukkit.util.Vector :
    Code:
    Vector vec = new Vector(0, (x - width/2)  * offset,
                               (y - height/2) * offset);
    
    Then I rotated the vector's coordinates with the given pitch and yaw:
    Code:
    pitch rotation:
    x = x * cos(pitch) - y * sin(pitch)
    y = x * sin(pitch) + y * cos(pitch)
    
    yaw rotation:
    x = x * sin(yaw) - z * cos(yaw)
    z = x * cos(yaw) + z * sin(yaw)
    
    In the end add this vector to a copy of a players eye location and spawn the particle there again.

    I guess if you really want to have your picture you should be willing to do it yourself.
    If you can achieve the rotation but it is inverted or anything else akward maybe look at this Tutorial on how to get the radians pitch and yaw from a bukkit Location. Maybe you did a mistake there
     
    Last edited: Nov 8, 2017
  5. Offline

    Unknown123

    @MightyOne is there a way to do this without using a Vector
     
  6. Offline

    MightyOne

    They are not that complicated and if you want to work with locations you should get used to work with vectors. There is nothing bad about them
     
  7. Offline

    Unknown123

    @MightyOne i didn't need a Vector for only the X and Z axis
     
  8. Offline

    MightyOne

    yeah but now it will be maybe... more compact. just combining all the x y z values to one vector makes it more structured to my mind. Do you need help to understand the concept of vectors or anything?
     
  9. Offline

    Unknown123

    @MightyOne Sorry, I don't want to use Vectors for that. Bump!
     
  10. Offline

    MightyOne

    Every Vector can be translated to single doubles. If you are so interested in avoiding Vectors just do that.
     
  11. Offline

    Unknown123

    @MightyOne Sorry, can you edit this code for me? You can use Vectors if you want to
    Code:
            for (int x = 0; x < width; x++) {
                for (int y = 0; y < height; y++) {
                    double angleYaw = Math.PI * 2D * (loc.getYaw() + 180D) / 360D;
                    double anglePitch = Math.PI * 2D * (loc.getPitch() + 180D) / 360D;
                    Location spawnLoc = new Location(world,
                            loc.getX() + (x * offset - width / 2D * offset) * Math.cos(angleYaw),
                            loc.getY() - (y * offset - height / 2D * offset) * Math.sin(anglePitch),
                            loc.getZ() + (x * offset - width / 2D * offset) * Math.sin(anglePitch));
                    world.playEffect(spawnLoc, effect);
                }
            }
        }
     
    Last edited: Nov 21, 2017
  12. Offline

    Unknown123

    @MightyOne @Side8StarLite Solved it! Thanks for helping me :D
    EDIT: OOPS, still some bugs in it, can anyone check my methods?
    Code:
        private static Vector rotateVectorAroundXAxis(Vector vec, double angle) {
            double cos = Math.cos(angle);
            double sin = Math.sin(angle);
            double y = vec.getY() * cos - vec.getZ() * sin;
            double z = vec.getY() * sin + vec.getZ() * cos;
            return vec.setY(y).setZ(z);
        }
    
        private static Vector rotateVectorAroundYAxis(Vector vec, double angle) {
            double cos = Math.cos(angle);
            double sin = Math.sin(angle);
            double x = vec.getX() * cos + vec.getZ() * sin;
            double z = vec.getX() * sin + vec.getZ() * cos;
            return vec.setX(x).setZ(z);
        }
    
        private static Vector rotateVectorAroundZAxis(Vector vec, double angle) {
            double cos = Math.cos(angle);
            double sin = Math.sin(angle);
            double x = vec.getX() * cos + vec.getY() * sin;
            double y = vec.getX() * sin - vec.getY() * cos;
            return vec.setX(x).setY(y);
        }
    
        private static Vector rotateVector(Vector vec, double angleX, double angleY, double angleZ) {
            rotateVectorAroundXAxis(vec, angleX);
            rotateVectorAroundYAxis(vec, angleY);
            rotateVectorAroundZAxis(vec, angleZ);
            return vec;
        }
     
    Last edited: Nov 22, 2017
    MightyOne likes this.
Thread Status:
Not open for further replies.

Share This Page