2D plotting in Java - java

Maybe this is only my problem, but I simply can't find this while searching on Google, and it shouldn't be that hard.
I'm looking for a Class/API for 2D plotting.
I need a method in which I give a series of int or double values, and it plots them in a 2-coordinate plane, and draws the plane on a JFrame or JPanel.

Here's a method:
public void plot(String ints, Graphics g) {
ints = "put all nums here (e.g. 4,3;9,1;1.1,2)";
String[] Part1 = ints.split(";");
String coor1 = Arrays.(Part1[0]);
String coor2 = Arrays.(Part1[2]);
g.drawLine(50, 0, 2, heightOfFrame);
g.drawLine(0, 50, widthOfFrame, 2);
g.drawLine(45, 40, 10, 2);
g.drawLine(40, 45, 2, 10);
int coord1 = Integer.parseInt(coor1) * 10;
int coord2 = Integer.parseInt(coor2) * 10;
g.drawOval(coord1-1, coord2-1, 2, 2);
}
In theory, this should work - though I haven't tested it - so please tell me about any bugs in this and I'll fix it.
BTW: this only covers 0 and 1 x and y; but it's the general idea to get you started.

Related

Growing textSize in Processing

I am trying to write a program where the text is growing so that the larger the number, the larger the font size.
I have an array from 0-9 showing on my screen but struggle to have the growth of the font size.
Does anyone have a hint for me?
My current code is:
int[] numbers = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
void setup() {
size(800, 500);
}
void draw() {
background(28, 130, 42);
for (int i = 0; i < numbers.length; i++) {
textSize(32);
fill(51, 102, 104);
text(""+(i), 100+(i)*50, height/2);
}
}
textSize(32) is hardcoded and not dynamic, do something like this:
for (int i = 0; i < numbers.length; i++) {
textSize(3 * i + 3);
// Your code that draws to screen
}
I've changed 32 to 3 * i + 3 so your textSize will range from 3-30.
Ofcourse this can be anything you want, just make sure it's some calculation based on i, as the loop continues i will increase and fontSize will too.
Try to use this function, where 'fontSize' is the value of the array (times n, depending on how big you want your font).
.setFont(new Font("TimesRoman", Font.PLAIN, fontSize));

How to Render a Hex Grid

I am currently working on a game that requires a hexagon grid to be rendered in order to provide a place for the game to take place. I am using offset coordinates to store the hex grid in memory. When I attempt to render the grid, I get a result like the following with space between the hexes. I want the hexes to perfectly align so that all of the neccessary are at the exact same points, and so that their lines overlap and there is no space between the hexes
The coordinates inside each hex represent the offset coordinates of the hex.
I am using the distances shown in the following image (source) to decide where to render each hex.
The only StackExchange question I was able to find that addresses a problem that sounds like this one is here. It, however, only talks about a data structure to store the hexes in and not how to render them from said structure. I am attempting to render them as described here, however, I get the buggy result shown above.
Here is the portion of my code that handles rendering (it should be easy to infer what the various custom methods do, if there is any confusion please let me know):
#Override
public void paint(Graphics g){
int quarterHexSize = 32; //using non static final member variables because I want to make this dynamically determine the largest size of the hexagons that will fit on the screen later
int halfHexSize = quarterHexSize * 2;
int hexSize = halfHexSize * 2;
int cx, cy, renderX, renderY;
g.setColor(Color.DARK_GRAY);
g.fillRect(0, 0, getWidth(), getHeight());
g.setColor(Color.WHITE);
for(cx=0;cx<5;cx++){
for(cy=0;cy<5;cy++){
Hex hex = board.getHexAt(cx, cy);
if(hex != null){
renderX = cx * 2; //multiplying by 2 rather than using floats to represent half offset to simplify code and because IIRC integers are faster, I got the same error when using floats
renderY = cy * 2;
if(renderY % 4 != 0){
renderX++;
}
//converts the somewhat arbitrary units into the actual display size units using the values from the image in the question
renderX *= hexSize;
renderY *= quarterHexSize * 3f;
//the numbers are divided by 2 to make up for the offset
renderX /= 2;
renderY /= 2;
//64 is added to both dimensions to shift the grid inside the window
renderX += 64;
renderY += 64;
drawHex(new RenderPoint(renderX, renderY), halfHexSize, g);
g.drawString(cx + ", " + cy, renderX, renderY);
}
}
}
}
private void drawHex(RenderPoint center, int hexSize, Graphics g){
drawHexLine(center, hexSize, 0, 1, g);
drawHexLine(center, hexSize, 1, 2, g);
drawHexLine(center, hexSize, 2, 3, g);
drawHexLine(center, hexSize, 3, 4, g);
drawHexLine(center, hexSize, 4, 5, g);
drawHexLine(center, hexSize, 5, 0, g);
}
private void drawHexLine(RenderPoint center, int hexSize, int firstCornerNum, int secondCornerNum, Graphics g){
RenderPoint firstCornerNumHexPoint = getHexCorner(center, hexSize, firstCornerNum);
RenderPoint secondCornerNumHexPoint = getHexCorner(center, hexSize, secondCornerNum);
g.drawLine(
firstCornerNumHexPoint.getX(), firstCornerNumHexPoint.getY(),
secondCornerNumHexPoint.getX(), secondCornerNumHexPoint.getY()
);
//g.drawString(String.valueOf(firstCornerNum), firstCornerNumHexPoint.getX(), firstCornerNumHexPoint.getY());
}
private RenderPoint getHexCorner(RenderPoint center, int hexSize, int cornerNum){
return RenderPoint.doublesToInts( //simply rounds the provided doubles and creates a RenderPoint object with these new rounded values
center.getX() + hexSize * Math.sin(cornerNum * 60 * 0.0174533), //decimal number converts from degrees to radians
center.getY() + hexSize * Math.cos(cornerNum * 60 * 0.0174533)
);
}
I have determined what the error was. I had missed a specific detail in the webpage when I assumed that the diagram I posted in the question completely explained the placement of the hexagons.
I have changed the variable renderX to:
renderX *= Math.round(HALF_SQRT_THREE * hexSize);
HALF_SQRT_THREE is a constant I defined in the variable to avoid recalculating it each time a hexagon is rendered. It is defined as Math.sqrt(3)/2.0.
Here is the quote from the webpage:
The width of a hexagon is width = sqrt(3)/2 * height. The horizontal distance between adjacent hexes is horiz = width.

Printing rectangles using graphics java

I am trying to draw multiple rectangles using separate integer values.
BufferedImage rectImage = bimage.myBImage;
BufferedImage pointImage = bimage.myBImage;
Graphics g = rectImage.createGraphics();
Graphics h = pointImage.createGraphics();
Color rectangle = Color.CYAN;
g.setColor(rectangle);
int alon = -118;
int alat = 34;
int x = (int) Math.round((alon-UL_Lon)/dXLon);
int y = (int) Math.round((UL_Lat-alat)/dYLat);
g.drawRect(x - 5, y - 5, 10, 10);
Color point = Color.BLUE;
h.setColor(point);
h.drawLine(x, y, x, y);
I have multiple values for alon and alat that I would like to be able to input without having to rewrite the code over and over again.
How should I go about doing something like this?
This question is pretty vague and not worded very well. I'm presuming from what I've gathered you want to render multiple rectangles at different places with different sizes. You should first define how many rectangles you want:
int numberOfRectangles = 5;
Then you should create an array that can hold the number of rectangles you defined:
Rectangle rectangles[] = new Rectangle[numberOfRectangles];
Now, you must define the rectangles:
rectangles[0] = new Rectangle(7, 64, 32, 32);
rectangles[1] = new Rectangle(64, 18, 4, 32);
You appear to also want to set colors? So you can do that by making an array:
Color rectangleColors[] = new Color[numberOfRectangles];
Then also defining them:
rectangleColors[0] = new Color(255, 48, 128);
rectangleColors[1] = Color.GREEN;
Because of the system you don't have to define all the rectangles at once. Now, you must cycle through the rectangles array and render each of the defined rectangles using the render method:
for (int i = 0; i < numberOfRectangles; i++)
{
g.setColor(rectangleColors[i]);
g.fillRect(rectangles[i].getX(), rectangles[i].getY(), rectangles[i].getWidth(), rectangles[i].getHeight());
}
This should work, though I haven't tested it out in Java.
If the values that you want to give your Rectangles completely random, then you'll have to copy-paste the code and change the values. However, if the values are a sequence (like you want to create 20 rectangle adjacent to each other for instance) You can use a for loop.
for(int i=1; i<11; i++){
int x = (int) Math.round((alon-UL_Lon + i)/dXLon);
int y = (int) Math.round((UL_Lat-alat + i)/dYLat);
g.drawRect(x - 5, y - 5, 10, 10);
}
Like this

Turn an Integer into a set of pictures

I am making a minecraft mod that implements a new system of "energy" for the player. There are various ways to acquire this energy and I want it to display the player's amount of energy onto the screen. My plan for this is to make a GUI (with OpenGL, as minecraft uses) that uses a file called "energybar.png":
to print numbers. This is the code I have for the method that will do as described.
#SubscribeEvent
public void onGUIRenderEvent(RenderGameOverlayEvent event){
if(event.isCancelable() || event.type != RenderGameOverlayEvent.ElementType.EXPERIENCE)
{
return;
}
int xPos = 10;
int yPos = 10;
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
GL11.glDisable(GL11.GL_LIGHTING);
mc.renderEngine.bindTexture(energybar);
String energyString = Integer.toString(Energy.PlayerTotalEnergy);
for(int i=0; i < energyString.length(); i++) {
LogHelper.info("Energy: " + energyString);
drawTexturedModalRect(xPos, yPos, (Energy.PlayerTotalEnergy / (int)Math.pow(10, i))*16, 0, 16, 16);
xPos += 16;
}
}
Each number in the photo is spaced out so it should be in its respective 16 pixels (ie: 0 is x positions 0-16, 1 is x positions 17-32, etc). The photo is 256x256 as defined by the standards of minecraft's GUI system. This is the layout of the method to draw a picture:
void drawTexturedModalRect(int xPosition, int yPosition, int uPosition, int vPosition, int width, int height)
The problem I have with this is that the U Positions for the numbers i need to print onto the screen are not working right.
I have also tried passing:
energyString.substring(i, i)
to a method that takes the substring and converts it back to an integer and multiplies it by 16 to get the uPosition, but when I do the:
String energyString = Integer.toString(Energy.PlayerTotalEnergy);
the Integer.toString() and also String.valueOf() methods have trouble with zeros. For example if Energy.PlayerTotalEnergy was just 0, they would not return a string "0", they just return "".
If someone could help me figure out why I can't get this to work or come up with a better idea of how I can use Minecraft and OpenGL to print this number onto my screen. The reason I'm not just printing it as a number is because I want to keep the red numbers as they look.
This is more of a guess.
It seems to me that if Energy.PlayerTotalEnergy was, let's say, 327, then your uPosition will be:
i=0: u= 327*16
i=1: u= 32*16
i=2: u= 3*16
Did you mean for them to be 7*16, 2*16, and 3*16?
In that case you should mod them with 10:
drawTexturedModalRect(xPos, yPos, ( (Energy.PlayerTotalEnergy / (int)Math.pow(10, i))%10)*16, 0, 16, 16);

Poor render performance in LibGDX with hexagonal map

So I am making a simple game using LibGDX which involes a 150*150 hexagonal map, and various types of cell, rocky, clear etc.
Problem is when i load the map, my computer almost completely freezes up and any movement thats supposed to be fluid (character moving, button highlights) take 5+ seconds longer than they should.
Here's the relevant code:
public void render(float deltY){
Gdx.gl.glClearColor(255, 255, 255, 100);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
stage.act();
polygonSpriteBatch.begin();
for (int j = 0; j < 150; j++) {
for (int i = 0; i < 150; i++) {
offset = i%2 == 0 ? multipleX/2 : 0;
if (mc.getMap().getRow(i).getTile(j).getTileType().equals(TileType.Rocky)) {
drawCell(Color.BLACK, j, i);}
if (mc.getMap().getRow(i).getTile(j).getTileType().equals(TileType.Clear)) {
drawCell(Color.LIGHT_GRAY, j, i);}
}
}
polygonSpriteBatch.end();
stage.draw();
}
private void drawCell(Color color, int x, int y) {
polySprite = new PolygonSprite(makePoints(color));
polySprite.setX(mc.getMap().getRow(y).getTile(x).getTilePosition().get_x() * multipleX + offset);
polySprite.setY(mc.getMap().getRow(y).getTile(x).getTilePosition().get_y() * multipleY);
polySprite.draw(polygonSpriteBatch);
}
public PolygonRegion makePoints(Color color){
side = 5;
h = CalculateH(side);
r = CalculateR(side);
multipleX = (float)Math.sqrt(3)*side;
multipleY = side+(side/2);
float[] points = { // vertices
x, y,
x+r, y+h,
x+r, y+side+h,
x,y+side+h+h,
x-r, y+side+h,
x-r, y+h};
return new PolygonRegion(new TextureRegion(getTexture(color)),points
, new short[] { //4 triangles using vertices to make hexagon
0, 1, 5,
1, 4, 2,
5, 1, 4,
2, 3, 4});
}
public Texture getTexture(Color color){
Pixmap pix = new Pixmap(1, 1, Pixmap.Format.RGBA8888);
pix.setColor(color);
pix.fill();
textureSolid = new Texture(pix);
return textureSolid;
}
I'm new to coding and LibGDX so there's probably something stupid i'm doing. Is there any way to render the map once and only redraw the polygons if they change?
Thanks
Looking at your code, you are computing a square root for each cell, for each rendering pass.
So your code currently involves more than 22500 square root operations for each frame you render and is creating as many objects, that's quite a lot !
You should compute the points for your hexagons only once.

Categories