java3d

I'm trying to rotate text around a unknown 3d line to face the player


I aim to create 3D lines that provide the unit measurement of said line on the line. I've already gotten the line and text to render, but I want some way to lock the text's rotation to the line and have it face the player. I've tried to use the player's Pitch and Yaw rotation to have the text face them; however, rotating it that way causes it to overlap nearby measurement units easily. In addition, I'd also need to tell if the player is in front or behind the line's face to flip the rendered text. I've experimented with rotating vectors around matrixes with little luck. Either I am not doing it right, or the method I used isn't the solution. If anyone has any suggestions, please let me know. I am at my witts end. What I have thus far

I've tried to get the point that is perpendicular to the midpoint so I could get the angle from the midpoint, perpendicular point, and the player camera. Then, with the angle, I could rotate the text. But each time I tried different solutions I found on this site and others, they never seemed to stay consistently perpendicular to the line. It would work when the line had a direction vector of 1,0,0, but as soon as the y or z-axis had a shift, it broke.


Solution

  • I don't exactly know what your text is made up of (points, lines, vertices), but if you have a method that can rotate your text in 3d (z-axis rotation and x-axis rotation) then you can find the 2 angles as follows.

    Please note that in this example Z axis faces upwards, so adjust any values to your needs.

    First compute the x, y, and z distances from the shape that you want to rotate, (in this case your words) to whatever point you want to rotate it to (in this case the player). The x distance and y distance will be used to compute to compute the z-axis rotation using trigonometry (making a triangle along the x and y axis and solving for the angle). you can use the Math.atan2(y_dist, x_dist) function to find the z-axis rotation. Then you're going to have to find the distance from the shape (your text) to the player ignoring z distance. You can do this by subtracting the z difference between the shape and the player and then doing the distance formula on the resulting point and the player. This will get you the diagonal distance on the x-y plane ignoring z distance. You can then use the Math.atan2(zdist, distance_ignoring_Z) again to find the x-axis rotation. I've included some code that I wrote for a 3d engine of mine where I solved the same problem.

    //turns the shape about itself torwards a point
    public void turnTowards(Point3D p) {
        Point3D centroid = this.getCentroid();
        //finds the x, y, and z distances to the point from the centroid of this shape
        double xdiff = centroid.getX()-p.getX();
        double ydiff = centroid.getY()-p.getY();
        double zdiff = centroid.getZ()-p.getZ();
        //then finds a point that is on the same z level as the point it is rotating towards
        Point3D sameZLevelPoint = centroid.add(new Point3D(0, 0, -zdiff));
        //then finds the distance from the same z level point to the point we are rotating to. this is so when we do the atan2 function, we are performing it on a triangle directly between the two points rather than axis aligned to the x or y axes
        double diagdiff = sameZLevelPoint.distance(p);
        //finds the two angles it needs to rotate by
        double zrot = Shape.radtodeg(Math.atan2(ydiff, xdiff));
        double xrot = Shape.radtodeg(Math.atan2(zdiff, diagdiff));
    }
    

    I know this is a bit late, I was trying to help out anyone who may come to this post in the future, but if you are still trying to solve this problem, ask any clarifying questions you need.