java instant double to int - java

I have looked around but all conversions have used more than one line and variables. I am trying to paint objects in a certain co-ordinates times a double that changes when you change the size of the frame.
Width = getWidth();
Height = getHeight();
cWidth = 1900/Width;
cHeight = 1030/Height;
Inside the paint class,
g.fillOval (PlayerX/cWidth, PlayerY/cHeight, 50/cWidth, 50/cHeight);
but I get the error:
The method fillOval(int, int, int, int) in the type Graphics is not applicable for the arguments (double, double, double, double).
Would I have to make a separate variable for all 4 for every object painted or is there an easier way?

You have to cast them to int.
g.fillOval ((int)(PlayerX/cWidth), (int)(PlayerY/cHeight), (int)(50/cWidth), (int)(50/cHeight);

If your dont have a method like:
fillOval(double a, double b, double c, double d)
you can not do
g.fillOval (PlayerX/cWidth, PlayerY/cHeight, 50/cWidth, 50/cHeight);
you need to pass integers not doubles, if loosing the presision is not a problem then try casting
g.fillOval ((int)(PlayerX/cWidth), (int)(PlayerY/cHeight), (int)(50/cWidth), (int)(50/cHeight));
Note:
you need to cast carefully grouping the result.
the reason is:
PlayerX is a double, same as cWidth,
so doing :
(int)PlayerX/cWidth
will not work, since the result is the same as int/double → double
PlayerX/(int)cWidth
will not work either, since the result is the same as doublet/int → double
the option that will work is
(int)(PlayerX/cWidth)

Related

Typecasting int to float before division. Which casts do I really need and which can I remove and why?

When dividing by ints and I want the result to be a float I can end up with something like this.
float ratio = landscape ?
((float) image.getWidth()) / ((float)image.getHeight()) :
((float)image.getHeight()) / ((float)image.getWidth());
However I think I don't need every cast. When diving sometimes it seems to be auto casted. What are the rules, when does this happen?
You need to cast at least one operand per division. The other operand will be promoted automatically.
I'd personally extract local variables though, at which point it's all implicit (which is why I'd have a comment):
// Use floating point promotion to avoid integer division
float width = image.getWidth();
float height = image.getHeight();
float ratio = landscape ? width / height : height / width;
For each division, you need only 1.
So it should be:
float ratio = landscape ?
((float)image.getWidth() / image.getHeight()) :
((float)image.getHeight() / image.getWidth());

Spread an array into multiple arguments for a function

How can I pass an array as three arguments to a function in Java? (Forgive me, I'm very new to Java).
I have the following function which takes float r, float g, float b, float a as arguments.
renderer.prepare(r, g, b, 1);
And I want to pass the output from this function in. (Or figure out how to return three separate unpacked floats).
public static float[] rgbToFloat(int r, int g, int b) {
return new float[] {(float) r / 255f, (float) g / 255f, (float) b / 255f};
}
How can I do this? In some other languages it would look something like this:
renderer.prepare(...rgbToFloat(25, 60, 245), 1);
This is a typical example of an "X-Y Problem". Your original quest was to somehow group the 3 different parameters that you want to pass to a function. That's "problem X". Then you came up with the idea of using an array for this, but you were still unsure how to go about it, so you posted this question asking how to best use an array to achieve what you want. But that's "problem Y", not "problem X".
Using an array may and may not be the right way of solving "problem X". (Spoiler: it isn't.)
Honoring the principle of the least surprise, the best way of solving your problem "X" in my opinion is by declaring a new class, FloatRgba which encapsulates the four floats in individual float members: final float r; final float g; final float b; final float a;.
So, then your rgbToFloat() method does not have to return an unidentified array of float, instead it becomes a static factory method of FloatRgba:
public static FloatRgba fromIntRgb( int r, int g, int b )
{
return new FloatRgba( r / 255f, g / 255f, b / 255f, 1.0f );
}
Finally, you introduce a utility function prepareRenderer which accepts a Renderer and a FloatRgba and invokes renderer.prepare(float, float, float, float) passing it the individual members of FloatRgba.
This way you keep everything clear, self-documenting, and strongly typed. Yes, it is a bit inconveniently verbose, but that's java for you.
Maybe late for the original question, might help late readers stumbling over here (like me), though: I rather recommend converting just one single parameter to float:
public static float rgbToFloat(int value)
{
return value / 255.0f;
// don't need the cast, value will be promoted to float anyway
// as second parameter is already
}
Call now gets to
renderer.prepare(rgbToFloat(25), rgbToFloat(60), rgbToFloat(245), 1);
Sure, the draw back is that you have to call it three times now (as the other way round, you would have had to store the array in a temporary as shown in the comments, you wouldn't, in comparison, have gained much either), in the end, you gain flexibility for and additionally avoid the temporary array object when none is needed.
If you still insist on the array, you'll need a temporary
float[] rgb = rgbToFloat(r, g, b);
renderer.prepare(rgb[0], rgb[1], rgb[2], 1.0f);
But then I wonder why you don't consider alpha as well:
public static float[] rgbToFloat(int r, int g, int b)
{
return rgbToFloat(r, g, b, 255);
}
public static float[] rgbToFloat(int r, int g, int b, int a)
{
return new float[] { r / 255.0f, g / 255.0f, b / 255.0f, a / 255.0f };
}

.getWidth(), .getHeight() in Java

So I just started learning Java yesterday coming from a different language, and I am reading through my textbook and finding it to be pretty nice so far. However I did an exercise that basically required me to create a new Object use Rectangle and find the area. Below is the working code I came up with.
Now coming from other programming languages I was just toying around with this and did int area,width,height;and then it gave me an error saying that I had to use double in order to utilize .getWidth();, .getHeight(). I couldn't find anything in my book telling me why I had to make this a double and I started looking online and found this link
Now I found some documentation online where It told me to use double as well, but I'm not really sure why would I need to set these as doubles. Is it because the people who made Java, knew that precision is needed when we are working with coordinates and doing math with widths, heights and coordinates? My book says that it takes more memory to make a double variable rather than an int ( I come from doing lots of javascript and PHP, so reading on what a float and double does was something good for me).
I.E. Why do I need to make my area,height,width variable doubles in order to use .getWidth,.getHeight
package keepo;
import java.awt.Rectangle;
public class tuna{
public static void main(String [] args){
Rectangle rect = new Rectangle(10,20,50,40);
double area,width,height;
width = rect.getWidth();
height = rect.getHeight();
area = width * height;
System.out.println("Width is : " + width + "Height is : " + height);
System.out.println("Area is : " + area);
}
}
It is because this is how these methods have been defined in the java api. As you can see under the modifier and type column that the methods getWidth(), getHeight() all return value of type double.
Because in this case, you should not use those methods. The AWT class Rectangle does store coordinates as ints. You can easily read them back as ints if that's what you want to do, by accessing the fields instead of calling the getter methods:
int area, width, height;
width = rect.width; // not getWidth()
height = rect.height; // not getHeight()
area = width * height;
The getWidth() and getHeight() methods serve zero purpose here, as they will always return the same value as the fields, except as a different type (and you can already assign any int value to a double anyway, when a double is what you want to use).
So why do those two methods (along with getX() and getY()) exist at all? Because in Java 1.2 the geometry stuff in the API was expanded. People wanted to be able to work with floating-point coordinates, which Rectangle cannot do. And the Java maintainers couldn't change the fields of Rectangle from int to double because that would break backwards compatibility with how old code was already using it. So two new classes, Rectangle2D.Float and Rectangle2D.Double were added, which store coordinates as floats and doubles respectively.
But what if you want to work generically with any rectangle, without writing separate code for all the rectangle flavors? A new abstract class, Rectangle2D was also added, as the superclass of the three rectangle classes. This class is abstract (meaning it cannot be created on its own, as it is incomplete) and it does not store any coordinates itself. It does however, specify a contract that its subclasses follow (meaning that any Rectangle2D method is available in all three of its implementations). That includes the getWidth() and getHeight() methods that return doubles, regardless of the actual storage type of the particular rectangle.
Taking the abstraction an extra, perhaps superfluous, level, they also added RectangularShape as the superclass of several shapes with rectangular bounds: Rectangle2D, RoundRectangle2D, Ellipse2D and Arc2D. That is the class that actually declares the getWidth() and getHeight() methods, which all RectangularShape subclasses must provide:
// What's this shape? A rectangle? An ellipse? Does it use ints? floats? doubles?
RectangularShape something = ......;
// We don't care!
System.out.println("The shape (whatever it is) occupies an area of:");
System.out.println(something.getWidth() + " × " + something.getHeight());
So you can call those getter methods on any rectangle (or "rectangular shape") to get its coordinates, but if you know you have a particular shape class, you can/should access its fields directly, as that is simpler, and it gives you the values without converting them to a different type.
P.S. It is a similar story with Point, which uses int coordinates, but provides double getX() and double getY() methods, because of the later-added classes Point2D.Float, and Point2D.Double, and the abstract superclass Point2D.
P.P.S. There is actually a small advantage to using double (or long) for your rectangle's area, even if your rectangle coordinates are ints. Large multiplications could overflow the 32-bit range of an int, producing the wrong result. If you convert at least one of the values to a larger type, it will cause the multiplication to be done in that larger type, which you can then safely store without overflow:
Rectangle big = new Rectangle(0, 0, 1000000, 1000000);
int area = big.width * big.height;
long bigArea = (long)big.width * big.height;
System.out.println(area); // -727379968 (uh oh!)
System.out.println(bigArea); // 1000000000000
Imran Ali is right.
This is java documentations for getHeight() and for getWidth() it's same.
java.​awt.​Rectangle
public double getHeight()
Returns the height of the bounding Rectangle in double precisionReturns:
the height of the bounding Rectangle.
But if you want/need to use int instead of double, use following codes for height and repeat them for width too:
using getSize() method which returns rectangle dimension then use it's fields (width and height)
int height = rect.getSize().height;
using data type casting
int height = (int) rect.getHeight();
int height = (int) rect.getSize().getHeight();
The Rectangle.getWidth() and Rectangle.getHeight()methods both return their values with double precision, as stated by others. It is easier if you just keep using them, in order to prevent the Rectangle's values from being changed on accident, by simply casting the value to an int:
int width = (int)rect.getWidth()
and int height = (int)rect.getHeight()

Convert Dimension to int in Java?

absolute java noob here. I was messing with some code and wondering if there is a way to convert a Dimension value to an integer or string.
I was using this line
int i = (int) frame.getSize();
to get the size of a window but it cannot convert a dimension to int. Any help?
You cannot "convert" a Dimension to int, because it is something different. It is meant to store information about a rectangle.
You can calculate the area of the rectangle:
double size = frame.getSize().getHeight() * frame.getSize().getWidth();
Of cause you can also store the information as a string:
String sizeStr = frame.getSize().getHeight() +" X " + frame.getSize().getWidth();
Now you could store the Dimension (but you would need to split the string again, to get the value.
You cannot cast an Dimension to a primitive. What you could do, however, is use the access methods, such as getHeight() and getWidth() to calculate it:
// No need to explicitly cast, Java will do that automatically
// (although it will issue a warning on lost precision)
int size = frame.getHeight() * frame.getWidth();
frame.getSize();
This is returning an Dimension object. You cannot convert and object to primitive type.
The Dimension have two attribute, height and width. You can use getter methods to access them.
double getHeight() : Returns the height of this Dimension in double precision.
double getWidth() : Returns the width of this Dimension in double precision.
The size of the Window can be calculated using Height and Width. As both are of double type, you need to store the size in double type.
Dimension dim = frame.getSize();
double size = dim.getHeight() * dim.getWidth();
The dimension object instantiated as follows;
Dimension dim = new Dimension(100, 50);
That means, there are two factors, which you should think of, these are height and weight.
If you simply say,
int i = (int) frame.getSize();
it is like;
int i = (int) height, weight.
Briefly, you cannot assign two values to one variable. You should make some calculation(s) to have one value from these two values.

Why is the output this? (Java)

This is an instance method from a Rectangle class where we modify the x and y coordinates of the rectangle and its width and height
public void modify(int newX, int y, int width, int h) {
int x = newX;
this.y = y;
width = width;
this.height = height;
}
Rectangle r3 = new Rectangle(0, 0, 10, 10);
r3.modify(5, 5, 50, 50);
System.out.print(r3.getX() + " " + r3.getY() + " ");
System.out.println(r3.getWidth() + " " + r3.getHeight());
I have this code and I know that the output is 0 5 10 10 but i'm not entirely sure why. can anyone explain why?
public void modify(int newX, int y, int width, int h) {
int x = newX; // the value isn't saved to the class members
this.y = y; // this is saved, hence you see the change in the y value
width = width; // meaningless, the variable is overwritten with it's own value
this.height = height; // who is height? the function receives h
}
You have created a new object of type "int" for X within the modify method. This means that it only exists within that method since you're not passing it by reference. So, the newX value is only 5 within the modify method, but does not exist as '5' outside of it. this.y works fine because you've called that specific instance of the object and modified it's value. Therefore, it's retained outside the method. 'width = width' doesn't work because you're simply assigning 50=50 (since you've inputted 50 as the width). 'this.height = h' would be fine, but you've said 'this.height = height'. But, from the code you've given, 'height' doesn't exist.
y is the only instance variable that is actually modified in the modify method. The other the arguments passed in have no net effect on the state of the object.
Actually, the code shouldn't compile. height isn't defined in your method call. Unless this is another property that you didn't include in your code snippet.
int x = newX creates a new int named x that you then do nothing with. That's why r3.getX() returns 0, since you never modified it.
this.y = y changes the value of the field y within the Rectangle class. This is why this change is shown in your output as 5.
width = width changes the method parameter named width to itself. It doesn't change the value, but it also doesn't set the field width within Rectangle. No change shown, original value of 10 prints.
If height is a field elsewhere, then it makes sense that r3.getHeight() wouldn't update the field, since the parameter in the method call is for h, not height. If not, then I don't know how the code compiles since height isn't mentioned anywhere.
The "int x = newX" line creates a variable "x" on the stack that exists only for the duration of the current method call.
"this.x" would refer to the "x" created by the classes constructor. Which is probably what "getX()" returns.
This code shows the difference between the function stack variable and object variable. For function modify, the four passing variables are on the stack. The line declares a stack variable x and set its value as newX. The second line uses the object variable this.y and set to passing variable y. The third line is to assign the width to its self on stack. The fourth line uses the object variable height and assign to its self. Once the program goes out of the scope of function modify, all its stack variables' value are whacked. So the result is 0 5 10 10 because only the second line which is not stack variable this.y retains its value after calling function modify.
I would venture to say your issue is in how you are assigning the new values of x, y, width and height to your rectangle object.
Assuming that your modify method is in the rectangle class your code currently looks like this (I added comments on the mistakes:
public void modify(int newX, int y, int width, int h) {
int x = newX; //you are declaring a new x here...not assigning newX to rectangle's x
this.y = y; //this is correct
width = width; //here you're just assigning the parameter width its current value
this.height = height; //here you are assigning the rectangles height value to itself
}
I would HIGHLY advise finding a naming convention and sticking with it as it would help tremendously here.
Try something like this:
public void modify(int x, int y, int w, int h) { //changed names of parameters
this.x = x; //removed the int type declaration and used this. prefix
this.y = y; //changed nothing
this.width = w; //adjusted for renamed parameter, used this. prefix
this.height = h; // adjusted for renamed parameter, again used this. prefix
}
As you can see, sticking to a convention makes the code less confusing and easier to read. This also allows you to see your mistakes more easily as they will usually stick out from your convention like a sore thumb. Don't worry it comes with practice.

Categories

Resources