Rounding when converting from double to float in java - java

I am trying to convert a Minimum Bounding Rectangle from double values to float values. After the conversion, I need the (float) rectangle to be equal to or contain the (double) rectangle (the float rectangle needs to be bigger than or equal to the double rectangle). To do that I want to be able to specify which way to round the double to convert it to float. So, when casting the "Top" of the rectangle, I would round up, but when casting the "Bottom" of the rectangle, I would round down.
Is there a class that allows me to do this?
Thanks.

Math.ceil( double ); - round up
Math.round( double ); - round down

You can compare the float to the double and if it needs to be slightly larger or smaller you can call floatToIntBits and intToFloatBits with an increment or decrement as required.

Related

What is the correct way to rotate a quaternion from its current rotation a certain angle?

I am trying to use quaternion rotation using the quaternion from JOML: https://github.com/JOML-CI/JOML/blob/main/src/org/joml/Quaternionf.java.
I can get objects to rotate but they get stuck and are unable to complete a full rotation. The object is being updated every frame.
Edit:
Removed all euler related code and am simply trying to get the object to rotate on a single axis based on a certain angle.
Edit 2:
Am trying to use the conjugate and multiplying the quaternions together like I have seen in some videos. I'm not quite there though as the model spins itself off the screen for some reason.
Edit 3:
Normalizing the quaternion fixed the disappearing behaviour. The issue seems to be that there's no simple way to rotate a certain amount without either having a timer to lerp over which will not work in my case as I am trying to rotate an object an arbitrary amount with no set beginning and end.
Rotation function
public void rotate(float angle, float x, float y, float z) {
Quaternionf rot = new Quaternionf();
rot.rotateAxis((float) Math.toRadians(angle), x, y, z);
Quaternionf conjugate = rot.conjugate();
rotation = rot.mul(rotation).mul(conjugate);
}
Calling the rotation function
entity.transform.rotate( 1,0,1, 0);
It does not matter whether you transform your Euler angles into a matrix or a quaternion or whatever representation: As long as you use Euler angles to represent an orientation, Gimbal Lock is unavoidable.
So, in order to avoid Gimbal Lock from happening, you must discard using Euler Angles and stay with one representation for an orientation (like a 3x3 matrix or a quaternion) and apply delta changes to them, instead of trying to represent a full orientation as three Euler angles. So, whenever you - let's say - rotate the object a few degrees around a certain axis, you apply that delta change or orientation to the matrix/quaternion.
I believe I have figured it out.
You need to create a quaternion and rotate it to your delta values, do not manipulate quaternion values directly (e.g. use rotationX function instead).
To add quaternions together you multiply them.
Finally you need to use the equation:
delta quaternion * quaternion to rotate * inverse of delta quaternion
Code:
public void rotate(float x, float y, float z) {
//Use modulus to fix values to below 360 then convert values to radians
float newX = (float) Math.toRadians(x % 360);
float newY = (float) Math.toRadians(y % 360);
float newZ = (float) Math.toRadians(z % 360);
//Create a quaternion with the delta rotation values
Quaternionf rotationDelta = new Quaternionf();
rotationDelta.rotationXYZ(newX, newY, newZ);
//Calculate the inverse of the delta quaternion
Quaternionf conjugate = rotationDelta.conjugate();
//Multiply this transform by the rotation delta quaternion and its inverse
rotation.mul(rotationDelta).mul(conjugate);
}

Way to get around integer requirements of g2.drawLine() method

I am currently trying to draw a line and keep the line proportionally the same no matter how the user resizes the JFrame. However, the problem I run into is when I try to draw a line when the user makes the JFrame smaller than the default value, as I end up multiplying the coordinates by fractions under 1, and since g2.drawLine() requires integers, it takes them as 0's and nothing is drawn. I'm wondering if there's a work-around to this little glitch or if you guys have any suggestions of how I should change my logic.
I think what you're seeing is just because of integer division. See Why is the result of 1/3 == 0?. When you have (width / 624), the result of this is always 0 if width is less than 624.
You could:
use (width / 624.0), which performs the division in floating-point (as double), or
you could rearrange your parentheses to be e.g. (int) ((x * width) / 624)) instead of (int) (x * (width / 624)).
However, to answer the question directly, you can draw a line with floating-point coordinates by using java.awt.geom.Line2D:
Line2D line2D = new Line2D.Double(x1, y1, x2, y2);
graphics2D.draw(line2D);
(Also see https://docs.oracle.com/javase/tutorial/2d/geometry/primitives.html.)
multiplying the coordinates by fractions under 1, and since
g2.drawLine() requires integers, it takes them as 0's
That's obviously false! If a coordinates is say, 327, then multiplying it by say 0.7 gives 228.9. That's not an integer but is has integer part, so you can safely convert it to integer:
double factor = ...;
int newCoord, oldCoord = ...;
newCoord = (int)(oldCoord * factor)
will give you the rounded result.
Or something else is wrong...

Java - New Point, X Distance from Latitude / Longitude point

I need to take a point, and determine what the point is that's N miles north-west of it, and N miles south-east of it. It'll essentially create a bounding box around the initial point.
I've looked around a bit, and found some stuff about Haversine, but it seems like all of the code implementations are for the distance between two points, not a new point component from a point.
Is there an existing implementation of such a thing, preferably in Java, that already exists? Or any other language?
Here is the methods I'd imagine that'd I'd need:
public float longitudeFromPoint( float lat, float long, int vertical, int horizontal )
{
// something
}
public float latitudeFromPoint( float lat, float long, int vertical, int horizontal )
{
// something
}
float startLat = 41.829347;
float startLong = -87.633788
float northWestLat = latitudeFromPoint( startLat, startLong, 1, -1 );
float northWestLong = latitudeFromPoint( startLat, startLong, 1, -1 );
float southWestLat = latitudeFromPoint( startLat, startLong, -1, 1 );
float southWestLong = latitudeFromPoint( startLat, startLong, -1, 1 );
This may be worth reading: Finding Points Within a Distance of a Latitude/Longitude Using Bounding Coordinates. It gives a short theoretical background on spherical coordinates and provides some java code.
The link is borrowed from the accepted answer to this thread on SO:
Calculating bounding box a certain distance away from a lat/long coordinate in Java

Find degree at intersection between vectors in convex polygon

It's a bit of a homework question but I've been derping around for a while and haven't been able to get a 100% accurate answer. Given a polygon, I have to find the internal angle of any random vertex within that polygon. What I have been doing is taking the vertex before that and the vertex after it and then calculating the angle of incidence (say I treat my vertex as B), I make the edges AB and BC, then find the magnitude of each, then divide the dot product of the two by the magnitude of each.
I'm still off, particularly in the instance where I have vectors (0,10), (0,0), (10,0). Obviously the interior angle on that middle vector is 90 degrees, but when I compute it using magnitude and dot product I get 45 degrees for some weird reason.
Here is my code
double dx21 = one.x - two.x;
double dx31 = one.x - three.x;
double dy21 = one.y - two.y;
double dy31 = one.y - three.y;
double m12 = Math.sqrt(dx21*dx21 + dy21*dy21);
double m13 = Math.sqrt(dx31*dx31 + dy31*dy31);
double theta = Math.acos((dx21*dx31 + dy21*dy31)/ (m12 * m13));
System.out.println(theta);
System.out.println(Math.toDegrees(theta));
Is there anything blindingly obvious that I've missed? I'm traversing the vertexes counter-clockwise, as that is how the set is organised.
Your code is using point 'one' as the centre point, and then calculates the angle between 'two' and 'three' from that. So, if you put , in the vertices (0,0), (0,10), (10,0), you would get an angle of 90. The actual calculation is fine and works, you just have your vertex order messed up.

Java Floating Point Math Mistake?

I am trying to calculate an aspect ratio for an image:
Log.d("img.width:", String.valueOf(img.getIntrinsicWidth()));
Log.d("img.height:", String.valueOf(img.getIntrinsicHeight()));
float aspect = ((float)img.getIntrinsicWidth()) / ((float)img.getIntrinsicWidth());
Log.d("aspect:", String.valueOf(aspect));
however this produces unexpected results:
img.width: 297
img.height: 167
aspect: 1.0
This seems like it has a simple answer, yet I can't figure it out.
You're dividing width by width. Try substituting one of them with the height.
You have a typo.
float aspect = ((float)img.getIntrinsicWidth()) /
((float)img.getIntrinsicWidth());
You are dividing the width by the width, which will always produce 1, divide by the height instead:
float aspect = ((float)img.getIntrinsicWidth()) /
((float)img.getIntrinsicHeight());
Its a typo, one of them has to be height. You are dividing width by width
float aspect = ((float)img.getIntrinsicWidth()) / ((float)img.getIntrinsicWidth());
have you try float aspect = (new float(img.getIntrinsicWidth())) / (new float(img.getIntrinsicWidth()));
You have a typo, you're dividing width by width. Should probably be width by height.
Also, to make it a bit easier on the eyes, you don't need to cast both sides for a division to use floats; the left side will be converted to float automatically if the right side is one.
float aspect = img.getIntrinsicWidth() / (float)img.getIntrinsicHeight();

Categories