Draw and get OpenSimplexNoise result - java

I want to generate a random terrain with OpenSimplexNoise. To start I just want to get a result and draw it to a window.
My question is now: How can I get the correct output of OpenSimplexNoise (cause there are many methods and I just don't know which is the correct one) and how to draw this result.
It should look like this:
public double[][] generateMap(long seed, int width, int height) {
double[][] map = new double[width][height];
// start generating things here, just how?
OpenSimplexNoise simplex = new OpenSimplexNoise(seed);
return map;
}
public void drawMap(double[][] map, Graphics g) {
for(int x = 0; x < map.length; x++) {
for(int y = 0; y < map[0].length; y++) {
Color color = new Color(); // how to get the color here?
}
}
}
This is the current code I've got.
Here is the link to OpenSimplexNoise for anyone who needs it:
https://gist.github.com/KdotJPG/b1270127455a94ac5d19

There's actually only 3 public methods - one for each for 2D, 3D & 4D noise.
Since you're filling a 2D array for your map , use the 2D noise eval method,
something like this:
for(int x=0; x<width; x++){
for(int y=0<y<height; y++){
map[x][y] = simplex.eval(x, y);
}
}
Later on, you can generate a color from the map values as follows:
Color color = Color.color(map[x][y], ma[x][y], map[x][y]);
The author also provides example usage code in OpenSimplexNoiseTest; he's using the 3D eval method, but always holding the z coord at zero. My guess is the example code was written before he added the 2D & 4D implementations. At any rate, it still works, but it might be a little slower than directly using 2D.

Related

Gradients with loadPixels() in Processing

Hi everyone – i am trying to draw a radial gradient in the background of my sketch – and I am trying to achieve this by manipulating the pixels like in an example by daniel shiffman – so far so good – it works as it should! BUT – now I want the radial gradient to be red – and the outer parts of the sketch to be black… So just as in the code example below, but inverted!
I tried many things – experimented with the RGB values – inverted the values of the dist(); function – thought of map(); – tried to change the calculations for the pixels – nothing worked out – what am I missing or can somebody explain it to me? I know what the code does – but cant get it inverted… does someone have an idea and can it explain it to me? I am really stuck…
void setup() {
size(1080, 1080);
}
void draw() {
loadPixels();
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
float d = dist(width/2, height/2, x, y);
pixels[x+y*width] = color(255,d,255);
}
}
updatePixels();
}
Thank you for any kind of help!
Here you go:
void setup() {
size(1080, 1080);
}
void draw() {
loadPixels();
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
float d = dist(width/2, height/2, x, y);
pixels[x+y*width] = color(255-d, 0, 0);
}
}
updatePixels();
}
Here's the trick:
RGB means Red-Green-Blue. They are the three colors which, mixed together, will make up the other colors. The number is how light the color is, so [255, 0, 0] would be a bright red. 255 everywhere would be white, and 0 everywhere would be black.
Your were close by trying to invert the dist, but the easy answer here was to invert it at the color's level by letting it range from 255 instead of to 255. That's why I wrote it 255 - d. Then, the further from the center, the closer to zero.
Have fun!

tile disappearing from rubiks cube with rotation

I'm working on a 2x2 rubik cube, and was having trouble getting one side rotate with my program. The cube is a 2d array of squares. I'm just triying to do a 90 degree counter clockwise turn.
This is what happens
https://imgur.com/a/tlskNKY
I changed the colour so I could see the specific squares and how they changed. I tried changing the order, moving specific pieces at a time to see if the problem was just overlapping pieces (no such luck).
//square class
public class square implements Comparable {
int c;
private Rectangle r;
int xpos, ypos, width, height;
public square(int a, int x, int y) {
c = a;
xpos = x;
ypos = y;
r = new Rectangle(xpos, ypos, 50, 50);
}
//some unused methods
}
//inside the cube class
public class cube{
square[] temp = new square[4]
square[][] sq= new square[6][4]
//two for loops make squares and fills the sq 2d array
//the result is in the imgur link
public void turnVc(){
temp= sq[2];
sq[2][0]=temp[1];
sq[2][1]=temp[3];
sq[2][2]=temp[2];
sq[2][3]=temp[0];
}
}
I expect the output to be the original image turned counter clockwise.
tmp is a pointer that points to the same object that sq[2] pointers. That's why when you change sq[2] content, you change tmp's as well.
i think instead of assign "temp= sq[2];" you should do the following:
temp = new square[4];
for (int i = 0; i < 4; i++) {
temp[i] = sq[2][i];
}
Edit:
i think a little improvement you could do is that you don;t need to save all the sq[2] array, you could only save the fist item. i would do like this (tmp is now a square, not an array):
tmp = sq[2][0];
sq[2][0] = sq[2][1];
sq[2][1] = sq[2][3];
sq[2][3] = sq[2][2];
sq[2][2] = tmp;
If your square class implements Cloneable, you should use clone() method possible, it is also similar to answer of #Nguyen Tan Bao, but shorter
I guess you 're C++ dev, reference in Java is like pointer in C++, you can research more Have fun !

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.

Reflecting an image

This is part of a project for my computer science class. One of the tasks is to take an image and reflect it. I've already initialized a picture called image. When I run this method, instead of reflecting the picture it mirrors it.
public void reflect()
{
//Creating a for loop to get all of the x values for the image object
for(int x = 0; x < image.getWidth(); x++)
{
//Creating a nested for loop to get all of the y values for each x value
for(int y = 0; y < image.getHeight(); y++)
{
//Getting a pixel object for the given x and y value
Pixel pixelObj = image.getPixel(x, y);
//I'm pretty sure this next line is where I'm screwing up.
//It's probably really simple, but I can't figure it out.
Pixel newPixel = image.getPixel(image.getWidth()-x-1, y);
//This sets the color values of the new pixel to the ones of the old pixel
newPixel.setRed(pixel0bj.getRed());
newPixel.setGreen(pixel0bj.getGreen());
newPixel.setBlue(pixel0bj.getBlue());
}
}
image.show();
}
You have to swap the corresponding pixel values. Currently, you are overwriting the right half of the image before saving their pixel values in a reference for putting them to the left half.
Below I've illustrated what I mean by "swapping" value instead of just assigning them uni-directionally:
//Getting a pixel object for the given x and y value
Pixel pixelObj = image.getPixel(x, y);
Pixel oppositePixel = image.getPixel(image.getWidth()-x-1, y);
//Store the RGB values of the opposite pixel temporarily
int redValue = oppositePixel.getRed();
int greenValue = oppositePixel.getGreen();
int blueValue = oppositePixel.getBlue();
//This swaps the color values of the new pixel to the ones of the old pixel
oppositePixel.setRed(pixel0bj.getRed());
oppositePixel.setGreen(pixel0bj.getGreen());
oppositePixel.setBlue(pixel0bj.getBlue());
pixelObj.setRed(redValue);
pixelObj.setGreen(greenValue);
pixelObj.setBlue(blueValue);
If you swap pixels both ways in each round, it's sufficient to loop from 0 to image.getWidth() / 2.
Have a look how it's done in ImageJ's ImageProcessor class as a reference.
Another solution is to use a matrix transformation and scale by -1 in the x direction. See the ImageJ scale op for a more elaborate example using the ImgLib2 library for image processing in Java.

I need a row of rectangles, how can I name their variables automatically?

Maybe it's a bit vague questions, but I'm just learning java and programming(using Stanford videos) and I need to make a row of rectangles to build pyramid. But as I'm doing this in loop, all rectangles get the same variable name and they just "change" places and I only get one rectangle. So how can I name the rectangles differently in loop and add them, because it'd take so long to make them manually.
My code:
private void BuildingRow() {
int Q = BRICK_QUANTITY;
double length; // length from row beginning spot
length = RowStartSpot(Q);
for (int i = 0; i < Q; i++)
{
GRect brick = new GRect(length, height - BRICK_HEIGHT, BRICK_WIDTH, BRICK_HEIGHT);
add(brick);
}
Create an array of rectangles and populate it using your for loop. The name of your rectangle will be its place in the array. For example if your rectangle array is called myRectangles, your first rectangle is myRectangles[0] etc.
You need to add them on some sort of list, so you can access them in the future:
List<GRect> listOfBricks = new ArrayList<GRect>();
for (int i = 0; i < Q; i++){
GRect brick = new GRect(length, height - BRICK_HEIGHT, BRICK_WIDTH, BRICK_HEIGHT);
listOfBricks.add(brick);
}
And then, to access each brick:
listOfBricks.get(index);

Categories