Trouble with rotating vectors

So I am trying to get a dynamic rotated rectangle with velocity to glide along a static rectangles surface after collision, but I am having trouble with rotating the surface normal vector to the surface vector.

Here is how I am doing the rotation:

            System.out.println("Normal Angle:");
            System.out.println(Utility.radToDeg(minTime.getStaticAxis().angleBetween(Vector3f.UNIT_X)));
            
            Quaternion rot90 = new Quaternion().fromAngleAxis(Utility.degToRad(90), Vector3f.UNIT_Z);
            Vector3f perpAxis = rot90.mult(minTime.getStaticAxis());
            
            System.out.println("Surface Angle:");
            System.out.println(Utility.radToDeg(perpAxis.angleBetween(Vector3f.UNIT_X)));
            velEntity.set(new Velocity(vel.project(perpAxis)));

where minTime.getStaticAxis() is the normal vector to the surface of collision. Now for some surfaces it outputs the correct transformation:

Normal Angle:
49.999996
Surface Angle:
140.0

but as the slope increases past 180 degrees I get numbers like this:

Normal Angle:
140.0
Surface Angle:
130.0

Where the Surface angle I am looking for would be either 230 degrees or 50 depending on which way you want the surface vector to face.

If it helps this is how I convert radians to degrees and vice-versa:

public static float degToRad(float deg){
    return (float)(deg * (StrictMath.PI / 180));
}

public static float radToDeg(float rad){
    return (float)(rad * (180 / StrictMath.PI));
}

So this is all effectively in 2D?

A picture might help us visualize what you are doing and what your values are meant to indicate.

Yes it is all essentially 2D however I use Vector3f because I plan on making it graphically a 3D game. Hopefully this diagram helps.

Hopefully this helps. minTime.getStaticAxis() above would be the green vector in this picture and I am having a problem rotating the green vector to the yellow vector. Essentially after i get the yellow vector I will project the blue vector (velocity) onto the yellow vector (or its negative if it matters).

Part of the problem may be that you are wrapped up in angles… which 99.9% of the time is a sign you are doing something wrong already (unless you are doing it to display in a UI.)

For example, if the yellow vector is 90 degrees from the green and you want to know the yellow vector:
Vector3f yellow = green.cross(Vector3f.UNIT_Z).normalizeLocal();

(which is really just a fancy way of swapping x, y to -y, x)

Note: yellow may be 180 degrees rotated in which case you can do Vector3f.UNIT_Z.cross(green) instead… I always have to try both before I get it right.

…the point is that you never need to leave the vectors as the angles are irrelevant. They are an unnecessary step.

But if you do want to know the angle in x,y for a vector (maybe for debugging) then that’s easy enough:
float rads = FastMath.atan2(yellow.y, yellow.x);

By the way, if you ever intend to do anything more advanced than this, I can highly recommend dyn4j as a 2D physics engine:
http://www.dyn4j.org/

…it’s not hard to adapt it to JME.

Turns out that what I originally did was correct, however I prefer your way. The tip on using atan2 rather than anglebetween() showed that the error was in angleBetween(), it did not say whether the angle was negative or not.

I am still running into some problems (sometimes the dynamic rectangle gets stuck on the surface) but these are most likely from not adding enough of a “buffer” to seperate the shapes that I am playing with now.

I heard many good things of dyn4j but I need my physics for this game to be deterministic across machines, I am even going to fork jme vector3f down the road and add strictfp and replace fastMath with StrictMath. This example is also getting close to the end of what i need for physics.

Turns out the only thing working is if I find surface vector (yellow) by rotating just shy of 90 degrees to help it get out of the way of. Is there a way to do this with cross products? or just go back to quaternion?

EDIT: SCRATCH THIS, was just something silly on my part it works without varying degrees.