Hello i'm currently working on a 2D Game Engine written entirely in java. Is there a way to centre a Graphics Object (g.drawString(x,y,z).
It would be preferably if this could be done through Graphics and the DefaultToolkit.
Thankyou very much :)
Simple mathematics. We have the object to be centered and the area where it should be centered.
Object width - w
Object height - h
Area width - aW
Area height - aH
//Follow center coordinates are coordinates where top left corner should be placed in order for the object to lie in center
centerWidth = (aW - W) /2
centerHeight = (aH - H) /2
As you can see, you MUST know the metrics of area you are placing your object on !
If that area is just the screen, then screen dimension can be used like this.
//Some dummy object metrics
int w = 30;
int h = 60;
//Now we find out the area metrics
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
int aW = screenSize.width;
int aH = screenSize.height;
//Apply our common formula
int centerWidth = (aW - w) / 2;
int centerHeight = (aH - h) /2;
This works well for objects you know (their width and height).
Text centering
If you want to center text, you can use FontMetrics class, which allows you to measure size of text.
Related
I have coordinates of rectangle to draw and I want to centre some text inside this rectangle.
int x, y, width, height;
String str = "This is a text";
x = 15;
y = 15;
width = 20;
heights = 30;
g.drawRect(x, y, width, height);
g.drawString(str, x + width/2, y + height/2);
If you want to center the text then you need to know the length of the text so you know its width relative to the width of the rectangle. This is done by getting the FontMetrics instance from the Graphics object.
So the basic code would be:
FontMetrics fm = g.getFontMetrics();
int stringWidth = fm.getStringWidth(...);
int xDiff = (width - stringWidth) / 2;
g.drawString(str, x + xDiff, ...);
Of course you will also need to center based on the height.
Doc says...
public abstract void drawString(String theString,
int x,
int y)
Renders the text of the specified iterator applying its attributes in accordance with the specification of the TextAttribute class.
The baseline of the leftmost character is at position (x, y) in this graphics context's coordinate system.
So... you are drawing your string starting at the center point of the rect but not the string.
https://docs.oracle.com/javase/7/docs/api/java/awt/FontMetrics.html - get the font metrics from the gc and figure out how wide the string is. Then subtract half of that from the start x. Do something similar for y (remember that height doesn't start at base.)
I am tring to draw a square in the center of the screen. I want there to be a slight margin to the left and right of the square so that is is away from the edge, the way I am trying to create it is below. The problem is that it will not display properly on all devices and that when the screen is tilted some of the square is cut off. I think this is because I use rectSide = 1000. does anybody know a better way to do this that will work on any screen size?
int rectside =1000;
canvas.drawRect(width/2 - rectSide/2,
height/2 - rectSide/2,
width/2 + rectSide/2,
height/2 + rectSide/2, paint);
You need to get height and width of device programmatically like this
DisplayMetrics displaymetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
int height = displaymetrics.heightPixels;
int width = displaymetrics.widthPixels;
Update:As pointed out by #Der Golem take the smaller between width and height so that all sides should be equal
Get the device's dimension:
DisplayMetrics displaymetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
int height = displaymetrics.heightPixels;
int width = displaymetrics.widthPixels;
Next, get the smallest dimension:
int diameter = width;
if (height < width){
diameter = height;
}
Now get an offset, I suggest using some kind of percentage of the device, e.g.
int offset = (int) (0.05*diameter);
diameter -= offset;
Finally draw it:
canvas.drawRect(width/2 - diameter/2 ,
height/2 - diameter/2,
width/2 + diameter/2,
height/2 + diameter/2, paint);
You are right, using an absolute number of pixel is not the good way.
You should adapt your rectSide using display height & width. How to get screen size attributes has already been discussed here.
I also strongly recommend you to read this, to get a better understanding of how to manage multiple screen sizes.
I have a 2D tile map (made of 25 tiles, each 30*30 pixels) drawn on a JPanel. How can I get the rectangular coordinates of each tile?
The "basic" approach might be do something like...
int tileWidth = 30;
int tileHeight = 30;
// Coordinates in the physical world, like a mouse point for example...
int x = ...;
int y = ...;
int col = (int)Math.floor(x / (double)tileWidth);
int row = (int)Math.floor(y / (double)tileHeight);
This will return the virtual grid x/y position of each tile based on the physical x/y coordinate
You can then use something like...
int tileX = col * tileWidth;
int tileY = row * tileHeight;
The tile rectangle then becomes tileX x tileY x tileWidth x tileHeight
Now, while this works. A better solution would be to use something like java.awt.Rectangle and maintain a List of them, each would represent a individual tile in the real world.
You could then use Rectangle#contains to determine if a given tile contains the coordinates you are looking for.
The other benefit of this, is Rectangle is printable using Graphics2D#draw and/or Graphics2D#fill
I'm trying to draw an arc based on two given points and a given height describing a circle segment. To acomplish this I would use the following method from java.awt.Graphics.
drawArc(int x, int y, int width, int height, int startAngle, int arcAngle)
First I observe that the x, y, width and height values describes a rectangle containing the circle.
The center of the arc is the center of the rectangle whose origin is (x, y) and whose size is specified by the width and height arguments. (http://docs.oracle.com/javase/7/docs/api/java/awt/Graphics.html)
So first I start by calculating the x,y,width and height values. The picture below describes how I would do this.
The first picture shows what values I've already got. The arc in the first picture is exactly what I'm trying to draw. In picture number two I calculate the lenght of a line between the two points. My code to perform this step would look like this:
int dx = p1.x- p2.x;
int dy = p1.y - p2.y;
double len = Math.sqrt(Math.pow((double)dx, 2) + Math.pow((double)dy, 2));
As shown in picture three I can now calculate the radius of the circle by using the following function.
radius = h/2 + len^2 / 8h
The first problem I encounter is to calculate the CenterPoint of the circle. This is partly where I need help.
If I was to calculate the Center Point I can then easily find the x, y, whith and height coordinates.
x = centerPoint.x - radius;
y = centerPoint.y - radius;
width = radius * 2;
height = radius * 2;
The last part is to calculate the startAngle and arcAngle based on the values we already calculated.
TL;DR I need help with calculating the angles and the center point.
Thanks in advance!
There's a well-known relationship (see here, for instance) between the chord half length, the height of the arc (also called the sagitta), and the radius. Let the chord length (the distance between p1 and p2 be l = 2 d, let the arc height be h, and let the radius be r. Then
r = (d 2 + h 2) / (2 h)
The center is on the perpendicular bisector of the chord, at a distance r - h from the chord, on the opposite side from the arc.1 You can then use standard inverse trig functions to get the start and end angles for the chord.
1 Note that it is not enough to know p1, p2, and h; you need some way of identifying which side of the chord has the center and which side has the arc.
What is a method in Java that draws a rectangle given the following:
The coordinates of the center of the square
The angle of the rectangle from vertical, in degrees
To draw a rectangle in the way you suggest you need to use the class AffineTransform. The class can be used to transform a shape in all manner of ways. To perform a rotation use:
int x = 200;
int y = 100;
int width = 50;
int height = 30;
double theta = Math.toRadians(45);
// create rect centred on the point we want to rotate it about
Rectangle2D rect = new Rectangle2D.Double(-width/2., -height/2., width, height);
AffineTransform transform = new AffineTransform();
transform.rotate(theta);
transform.translate(x, y);
// it's been while, you might have to perform the rotation and translate in the
// opposite order
Shape rotatedRect = transform.createTransformedShape(rect);
Graphics2D graphics = ...; // get it from whatever you're drawing to
graphics.draw(rotatedRect);
For the first point, you can just figure out the coordinates of the center of the square by using a distance formula, (int)Math.sqrt((x1 - x2)*(x1 - x2) + (y1 - y2)*(y1 - y2)); them divide by 2. you can do this for the width and height. I don't know enough about Java draw to give you better answers based on what was in your question but I hope that helps.
For the second, you would need to just create a polygon right?