Printing rectangles using graphics java - 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

Related

2D plotting in 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.

Java Convolution

Hi I am in need of some help. I need to write a convolution method from scratch that takes in the following inputs: int[][] and BufferedImage inputImage. I can assume that the kernel has size 3x3.
My approach is to do the follow:
convolve inner pixels
convolve corner pixels
convolve outer pixels
In the program that I will post below I believe I convolve the inner pixels but I am a bit lost at how to convolve the corner and outer pixels. I am aware that corner pixels are at (0,0), (width-1,0), (0, height-1) and (width-1,height-1). I think I know to how approach the problem but not sure how to execute that in writing though. Please to aware that I am very new to programming :/ Any assistance will be very helpful to me.
import java.awt.*;
import java.awt.image.BufferedImage;
import com.programwithjava.basic.DrawingKit;
import java.util.Scanner;
public class Problem28 {
// maximum value of a sample
private static final int MAX_VALUE = 255;
//minimum value of a sample
private static final int MIN_VALUE = 0;
public BufferedImage convolve(int[][] kernel, BufferedImage inputImage) {
}
public BufferedImage convolveInner(double center, BufferedImage inputImage) {
int width = inputImage.getWidth();
int height = inputImage.getHeight();
BufferedImage inputImage1 = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
//inner pixels
for (int x = 1; x < width - 1; x++) {
for (int y = 1; y < height - 1; y ++) {
//get pixels at x, y
int colorValue = inputImage.getRGB(x, y);
Color pixelColor = new Color(colorValue);
int red = pixelColor.getRed() ;
int green = pixelColor.getGreen() ;
int blue = pixelColor.getBlue();
int innerred = (int) center*red;
int innergreen = (int) center*green;
int innerblue = (int) center*blue;
Color newPixelColor = new Color(innerred, innergreen, innerblue);
int newRgbvalue = newPixelColor.getRGB();
inputImage1.setRGB(x, y, newRgbvalue);
}
}
return inputImage1;
}
public BufferedImage convolveEdge(double edge, BufferedImage inputImage) {
int width = inputImage.getWidth();
int height = inputImage.getHeight();
BufferedImage inputImage2 = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
//inner pixels
for (int x = 0; x < width - 1; x++) {
for (int y = 0; y < height - 1; y ++) {
//get pixels at x, y
int colorValue = inputImage.getRGB(x, y);
Color pixelColor = new Color(colorValue);
int red = pixelColor.getRed() ;
int green = pixelColor.getGreen() ;
int blue = pixelColor.getBlue();
int innerred = (int) edge*red;
int innergreen = (int) edge*green;
int innerblue = (int) edge*blue;
Color newPixelColor = new Color(innerred, innergreen, innerblue);
int newRgbvalue = newPixelColor.getRGB();
inputImage2.setRGB(x, y, newRgbvalue);
}
}
return inputImage2;
}
public BufferedImage convolveCorner(double corner, BufferedImage inputImage) {
int width = inputImage.getWidth();
int height = inputImage.getHeight();
BufferedImage inputImage3 = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
//inner pixels
for (int x = 0; x < width - 1; x++) {
for (int y = 0; y < height - 1; y ++) {
//get pixels at x, y
int colorValue = inputImage.getRGB(x, y);
Color pixelColor = new Color(colorValue);
int red = pixelColor.getRed() ;
int green = pixelColor.getGreen() ;
int blue = pixelColor.getBlue();
int innerred = (int) corner*red;
int innergreen = (int) corner*green;
int innerblue = (int) corner*blue;
Color newPixelColor = new Color(innerred, innergreen, innerblue);
int newRgbvalue = newPixelColor.getRGB();
inputImage3.setRGB(x, y, newRgbvalue);
}
}
return inputImage3;
}
public static void main(String[] args) {
DrawingKit dk = new DrawingKit("Compositor", 1000, 1000);
BufferedImage p1 = dk.loadPicture("image/pattern1.jpg");
Problem28 c = new Problem28();
BufferedImage p5 = c.convolve();
dk.drawPicture(p5, 0, 100);
}
}
I changed the code a bit but the output comes out as black. What did I do wrong:
import java.awt.*;
import java.awt.image.BufferedImage;
import com.programwithjava.basic.DrawingKit;
import java.util.Scanner;
public class Problem28 {
// maximum value of a sample
private static final int MAX_VALUE = 255;
//minimum value of a sample
private static final int MIN_VALUE = 0;
public BufferedImage convolve(int[][] kernel, BufferedImage inputImage) {
int width = inputImage.getWidth();
int height = inputImage.getHeight();
BufferedImage inputImage1 = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
//for every pixel
for (int x = 0; x < width; x ++) {
for (int y = 0; y < height; y ++) {
int colorValue = inputImage.getRGB(x,y);
Color pixelColor = new Color(colorValue);
int red = pixelColor.getRed();
int green = pixelColor.getGreen();
int blue = pixelColor.getBlue();
double gray = 0;
//multiply every value of kernel with corresponding image pixel
for (int i = 0; i < 3; i ++) {
for (int j = 0; j < 3; j ++) {
int imageX = (x - 3/2 + i + width) % width;
int imageY = (x -3/2 + j + height) % height;
int RGB = inputImage.getRGB(imageX, imageY);
int GRAY = (RGB) & 0xff;
gray += (GRAY*kernel[i][j]);
}
}
int out;
out = (int) Math.min(Math.max(gray * 1, 0), 255);
inputImage1.setRGB(x, y, new Color(out,out,out).getRGB());
}
}
return inputImage1;
}
public static void main(String[] args) {
int[][] newArray = {{1/9, 1/9, 1/9}, {1/9, 1/9, 1/9}, {1/9, 1/9, 1/9}};
DrawingKit dk = new DrawingKit("Problem28", 1000, 1000);
BufferedImage p1 = dk.loadPicture("image/pattern1.jpg");
Problem28 c = new Problem28();
BufferedImage p2 = c.convolve(newArray, p1);
dk.drawPicture(p2, 0, 100);
}
}
Welcome ewuzz! I wrote a convolution using CUDA about a week ago, and the majority of my experience is with Java, so I feel qualified to provide advice for this problem.
Rather than writing all of the code for you, the best way to solve this large program is to discuss individual elements. You mentioned you are very new to programming. As the programs you write become more complex, it's essential to write small working snippets before combining them into a large successful program (or iteratively add snippets). With this being said, it's already apparent you're trying to debug a ~100 line program, and this approach will cost you time in most cases.
The first point to discuss is the general approach you mentioned. If you think about the program, what is the simplest and most repeated step? Obviously this is the kernel/mask step, so we can start from here. When you convolute each pixel, you are performing a similar option, regardless of the position (corner, edge, inside). While there are special steps necessary for these edge cases, they share similar underlying steps. If you try to write code for each of these cases separately, you will have to update the code in multiple (three) places with each adjustment and it will make the whole program more difficult to grasp.
To support my point above, here's what happened when I pasted your code into IntelliJ. This illustrates the (yellow) red flag of using the same code in multiple places:
The concrete way to fix this problem is to combine the three convolve methods into a single one and use if statements for edge-cases as necessary.
Our pseudocode with this change:
convolve(kernel, inputImage)
for each pixel in the image
convolve the single pixel and check edge cases
endfor
end
That seems pretty basic right? If we are able to successfully check edge cases, then this extremely simple logic will work. The reason I left it so general above to show how convolve the single pixel and check edge cases is logically grouped. This means it's a good candidate for extracting a method, which could look like:
private void convolvePixel(int x, int y, int[][] kernel, BufferedImage input, BufferedImage output)
Now to implement our method above, we will need to break it into a few steps, which we may then break into more steps if necessary. We'll need to look at the input image, if possible for each pixel accumulate the values using the kernel, and then set this in the output image. For brevity I will only write pseudocode from here.
convolvePixel(x, y, kernel, input, output)
accumulation = 0
for each row of kernel applicable pixels
for each column of kernel applicable pixels
if this neighboring pixel location is within the image boundaries then
input color = get the color at this neighboring pixel
adjusted value = input color * relative kernel mask value
accumulation += adjusted value
else
//handle this somehow, mentioned below
endif
endfor
endfor
set output pixel as accumulation, assuming this convolution method does not require normalization
end
The pseudocode above is already relatively long. When implementing you could write methods for the if and the else cases, but it you should be fine with this structure.
There are a few ways to handle the edge case of the else above. Your assignment probably specifies a requirement, but the fancy way is to tile around, and pretend like there's another instance of the same image next to this input image. Wikipedia explains three possibilities:
Extend - The nearest border pixels are conceptually extended as far as necessary to provide values for the convolution. Corner pixels are extended in 90° wedges. Other edge pixels are extended in lines.
Wrap - (The method I mentioned) The image is conceptually wrapped (or tiled) and values are taken from the opposite edge or corner.
Crop - Any pixel in the output image which would require values from beyond the edge is skipped. This method can result in the output image being slightly smaller, with the edges having been cropped.
A huge part of becoming a successful programmer is researching on your own. If you read about these methods, work through them on paper, run your convolvePixel method on single pixels, and compare the output to your results by hand, you will find success.
Summary:
Start by cleaning-up your code before anything.
Group the same code into one place.
Hammer out a small chunk (convolving a single pixel). Print out the result and the input values and verify they are correct.
Draw out edge/corner cases.
Read about ways to solve edge cases and decide what fits your needs.
Try implementing the else case through the same form of testing.
Call your convolveImage method with the loop, using the convolvePixel method you know works. Done!
You can look up pseudocode and even specific code to solve the exact problem, so I focused on providing general insight and strategies I have developed through my degree and personal experience. Good luck and please let me know if you want to discuss anything else in the comments below.
Java code for multiple blurs via convolution.

How to draw rectangles using a loop?

I need to create a loop which draws rectangles in a vertical line with alternating color (e.g. black, white, black, white). Can anyone tell me how this is done?
I have tried numerous ways but can't seem to get the loop to work, thanks.
for (int x = 0; x>10;x++) {
int y= 180;
graph2D.drawRect(170, y, 20, 50);
y = y + 45;
}
This is what I have, it won't draw the rectangles for some reason and I cant get it to alternate colors.
You've got a few issues here.
Your for loop will not perform any iterations, as your condition is x > 10 instead of x < 10.
Change the first line from:
for (int x = 0; x>10;x++){
To:
for (int x = 0; x < 10; x++) {
Also, you reset y to 180 every iteration, so once your loop does start, all of the rectangles will be drawn on top of each other. Declare y outside of the loop, or use x to calculate the rectangles position.
Either like this:
int y = 180;
for (int x = 0; x < 10; x++) {
graph2D.drawRect(170, y, 20, 50);
y = y + 45;
}
Or like this:
for (int x = 0; x < 10; x++) {
graph2D.drawRect(170, (x * 45) + 180, 20, 50);
}
The above math (x * 45) + 180 is a super simple way of saying that the first rectangle will be at (x * 45) + 180 = 0 + 180 = 180, the second will be at (x * 45) + 180 = 45 + 180 = 225 and so on and so on.
To change the color of the rectangles, you'll need to make a list or array of Colors, and use a different Color from the list, in each iteration.
//Make the list
Color[] colors = {Color.black, Color.blue, Color.cyan, Color.darkGray,
Color.green, Color.lightGray, Color.magenta, Color.magenta,
Color.orange, Color.pink, Color.red, Color.white, Color.yellow};
//Draw each rectangle
for (int x = 0; x < 10; x++) {
//Change the color
g.setColor(colors[x]);
//Draw the rectangle
graph2D.drawRect(170, (x * 45) + 180, 20, 50);
}
Of course if you want the colors to be random, you can look into using the Random class, and generating a random number between 0 and the length of your colors array. Also note that I use x as an index for the colors array, and if your loop increments x to be higher than the number of colors in the array, you'll get an ArrayIndexOutOfBoundsException.
I also assumed you named your instance of Graphics as g, since it is done that way most of the time.
Why do you use the y variable instead of x that you are looping though?
#Override
public void paint(Graphics graph2D) {
for (int y=0; y<10; y++) {
int height = 50;
if (y%2==0) {
graph2D.setColor(Color.white);
} else {
graph2D.setColor(Color.black);
}
graph2D.fillRect(170, 180 + y*height, 20, 50);
}
}
Also mind the difference while drawing a rectangle:
.drawRect(..) draws the border of a rectangle.
.fillRect(..) draws the rectangle itself.
In case you want to switch between black and white color, change the color with every loop. Every even number y%2 == 0 of loop will have the one color, otherwise the second one (also mentioned in the code above):
if (y%2==0) {
graph2D.setColor(Color.white);
} else {
graph2D.setColor(Color.black);
}

Determine touch/click of 4 Polygons from a Rectangle using libgdx

I'm currently working with libgdx, and am trying to get 4 equal Polygons from a Rectangle:
Rectangle myRect = Rectangle(0, 0, 171, 171);
I am looking to determine the 4 Polygons that represent each side of the Rectangle
This is my first day working with this engine, and I am a bit rusty on my geometry, so I'm looking for any help I can get. Essentialy, I'm going to use these Polygons to determine whether a specified X,Y pair is within them.
Thanks for the help.
You could find the mid point of the rectangle fairly easily, just average the height and width. From there you could manually construct a polygon, jumping from corner to corner to midpoint. You would lose some precision due to rounding, but you can use getX() and getWidth() if you need double precision.
public Polygon[] findTris(Rectangle rectangle){
//Creating a list of the x points of the rectangle, ordered clockwise.
new int[] xpoints = new int[5];
xpoints[0] = rectangle.x;
xpoints[1] = rectangle.x+rectangle.width;
xpoints[2] = rectangle.x+rectangle.width;
xpoints[3] = rectangle.x;
xpoints[4] = rectangle.x;
//Doing the same for y points.
int[] ypoints = new int[5];
ypoints[0] = rectangle.y;
ypoints[1] = rectangle.y;
ypoints[2] = rectangle.y+rectangle.height;
ypoints[3] = rectangle.y+rectangle.height;
ypoints[4] = rectangle.y;
//Finding the midpoint.
int midx = (rectangle.x+rectangle.width)/2;
int midy = (rectangle.y+rectangle.height)/2;
//Creating an array to hold the polygons.
Polygon[] polys = new Polygon[4];
//Creating the polygons.
for(int i = 0; i < 4; i++){
int[] triXPoints = {xpoints[i], xpoints[i+1], midx};
int[] triYPoints = {ypoints[i], ypoints[i+1], midy};
polys[i] = Polygon(xpoints,ypoints,3);
}
return polys;
}
Now that will work fine, but if all you are trying to do is find the mouse position in a square, you can use mouse maps. A mouse map is an image with distinctly different colors in each region that you want to be able to recognize the mouse in. You would store the map as a BufferedImage and whenever you needed to find the region the mouse was in, you can get the color of the buffered image at the appropriate position on the BufferedImage.
Here is the idea:
http://i.stack.imgur.com/iFPsl.png

how to generate random numbers of random colors for canvas.drawColor

I am still new at android development and all the app i've been dealing with so far are not graphical related. Now i am making a app that displays a graph, pie graph to be exact and im making this without any 3rd party libs. This is the tutorial which i followed.
Now the problem is the data which i will be using to construct the graph is dynamic, and so to assign each item with a color for the graph i need to generate a number of random colors for the canvas.drawColor. the number of colors will of course depend on my dynamic data which is determined at run time and the color value also needs to be generated.
Also it would be nice if the colors generated are vibrant colors that stands out.
I've never dealt with canvas, any idea how this can be done? Example code would be much appreciated.
Thanks
It would be quite hard to get different and usefull colors at runtime. The best is not to use so much randomness, but make an array of let's say 20 fixed colors quite distinct and use the X first ones for your data. If you need more, then maybe use real random colors using random RGB values :
Random r = new Random();
Color c = new Color( r.nextInt(255), r.nextInt(255), r.nextInt(255) );
You should take a random float for each color component:
Random rand = new Random();
float r = rand.nextFloat();
float g = rand.nextFloat();
float b = rand.nextFloat();
Since you want vibrant colors, you could use the Color.brighter() method.
Color c = new Color(r, g, b);
c = c.brighter();
Otherwise you could set a threshold, so that the color values have a minimum value (higher is brighter):
float minimumBrightness = 0.6; //higher is more vibrant
float r = rand.nextFloat(1-minimumBrightness) + minimumBrightness; //for each component
This will ensure vibrant colors.
I wouldn't use just completely random colors. You'd get completely different saturations and brightnesses which will look plain ugly.
You could fix a saturation (choose a high value for vibrant colors) and brightness and choose a random hue value, but you would run the risk of getting two consecutive pie-slices with almost the same color.
I would compute a set of spread out hue-values as shown in the answer to this question:
How to dynamically compute a list of colors?
Reposting the answer below
import java.awt.*;
public class TestComponent extends JPanel {
int numCols = 6;
public void paint(Graphics g) {
float h = 0, dh = (float) getHeight() / numCols;
Color[] cols = getDifferentColors(numCols);
for (int i = 0; i < numCols; i++) {
g.setColor(cols[i]);
g.fillRect(0, (int) h, getWidth(), (int) (h += dh));
}
}
public static Color[] getDifferentColors(int n) {
Color[] cols = new Color[n];
for (int i = 0; i < n; i++)
cols[i] = Color.getHSBColor((float) i / n, 1, 1);
return cols;
}
public static void main(String s[]) {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(new TestComponent());
f.setSize(400, 400);
f.setVisible(true);
}
}
If you need like more than 30 colors, you could of course change the brightness and perhaps the saturation as well, and have, for instance, 10 dark colors, 10 midtone colors, and 10 bright colors.

Categories