Constructor is undefined, when it is clearly defined - java

I am making a program that plots the decay of atoms. Here is my main, which also does the logic. However, I am getting a undefined constructor error, when it is clearly defined in the other class. Why is this happening?
Caution: it isn't notated. Spare me your wrath.
import java.util.Random;
import java.awt.*;
import javax.swing.*;
import javax.swing.JFrame;
public class Main {
public static void main(String args[]) {
int chance = 6;
Random r = new Random();
int num = 40;
int[] decayed;
int reps = 25;
decayed = new int[reps];
for (int j = 1; j < reps+1; j++) {
for (int i = 0; i < num; i++) {
int c = r.nextInt(chance);
if (c == chance - 1) {
decayed[j]++;
}
}
System.out.printf("\n Trial: " + j + "\n Number left: " + num
+ "\n Decayed: " + decayed[j] + "\n\n");
num = num - decayed[j];
}
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.getContentPane().add(new Graph(decayed[])); //"Constuctor is undefined for type int" When I am clearly specifying an array.
f.setSize(400,400);
f.setLocation(200,200);
f.setVisible(true);
}
}
And my Graph.class. It is copied from some forum (Credit to Crieg Wood).
import java.awt.*;
import javax.swing.*;
import java.util.*;
public class Graph extends JPanel
{
int PAD = 20;
boolean drawLine = true;
boolean drawDots = true;
int dotRadius = 3;
// the y coordinates of the points to be drawn; the x coordinates are evenly spaced
int[] data;
public Graph(int points[]){ //This is the constructor which specifies type int[].
for (int i = 0; i<points.length; i++){ //Copies points[] to data[]
data[i] = points[i];
}
}
protected void paintComponent (Graphics g)
{
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
int w = getWidth();
int h = getHeight();
g2.drawLine(PAD, PAD, PAD, h-PAD);
g2.drawLine(PAD, h-PAD, w-PAD, h-PAD);
double xScale = (w - 2*PAD) / (data.length + 1);
double maxValue = 100.0;
double yScale = (h - 2*PAD) / maxValue;
// The origin location
int x0 = PAD;
int y0 = h-PAD;
// draw connecting line
if (drawLine)
{
for (int j = 0; j < data.length-1; j++)
{
int x1 = x0 + (int)(xScale * (j+1));
int y1 = y0 - (int)(yScale * data[j]);
int x2 = x0 + (int)(xScale * (j+2));
int y2 = y0 - (int)(yScale * data[j+1]);
g2.drawLine(x1, y1, x2, y2);
}
}
// draw the points as little circles in red
if (drawDots)
{
g2.setPaint(Color.red);
for (int j = 0; j < data.length; j++)
{
int x = x0 + (int)(xScale * (j+1));
int y = y0 - (int)(yScale * data[j]);
g2.fillOval(x-dotRadius, y-dotRadius, 2*dotRadius, 2*dotRadius);
}
}
}
}

The problems here are with the usage of those [] brackets.
Try to re-write your call:
f.getContentPane().add(new Graph(decayed));
Though you were not incorrect, please consider re-writing your constructor to hold to the Java standards and conventions:
public Graph(int[] points){ // NOTE: I moved the [] to a the standard position
for (int i = 0; i<points.length; i++){
data[i] = points[i];
}
}

Your syntax is invalid, to refer to your array, simply use the variable name, without the []:
f.getContentPane().add(new Graph(decayed));

Just replace this f.getContentPane().add(new Graph(decayed[]));
with this
f.getContentPane().add(new Graph(decayed));
Just use the name of the variable that you have created without that [].
Those [] brackets are used only at the time of declaration of the method parameters for arrays and not when calling the method.

Related

while loop returns a repeating random value rather than a new random value

I am currently just messing around with some code and I keep running into an issue. I want to create ten circles and simply have them bounce around the window. I've had a couple of problems (like when I want the circles to bounce off the wall, for some reason the 400,400 window isn't actually that size. I have the circles collide on the right by checking if x + width >= 400, but it bounces outside the screen unless I change the 400 to 380?), but my main issue is that when I create the circles, I want them to be in different locations (so they aren't colliding before they can even move). I am trying to get it so that if a circle is going to be 'inside' another circle then instead create random x and y coordinates again until it isn't inside another circle. But for some reason, if I put r.nextInt() inside the while loop it keeps giving me the same values. Can anyone help?
p.s. I wouldn't mind advice on any other mistakes I have made.
package practicedots;
import java.awt.Dimension;
import java.awt.Graphics;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class PracticeDots extends JPanel {
float dots[][] = new float[10][7];
Random r = new Random();
boolean first = true;
float x = 0;
float y = 0;
float xAccel = 0;
float yAccel = 0;
int wall = 380;
int width = 50;
float radius = 0;
float centreX = 0;
float centreY = 0;
boolean collision;
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(new PracticeDots());
f.setPreferredSize(new Dimension(400, 400));
f.setResizable(true);
f.pack();
f.setVisible(true);
}
/**
*
* #return
*/
public float[][] CreateDots() {
if (first == true) {
for (int i = 0; i < 10; i++) {
while(collision == true){
x = r.nextInt(300);
y = r.nextInt(300);
xAccel = r.nextFloat() / 2;
yAccel = r.nextFloat() / 2;
radius = width/2;
centreX = x + radius;
centreY = y + radius;
dots[i][0] = x;
dots[i][1] = y;
dots[i][2] = xAccel;
dots[i][3] = yAccel;
dots[i][4] = radius;
dots[i][5] = centreX;
dots[i][6] = centreY;
bounce();
}
}
first = false;
} else if (first == false) {
for (int i = 0; i < 10; i++) {
dots[i][0] = dots[i][0] + dots[i][2];
dots[i][1] = dots[i][1] + dots[i][3];
if (dots[i][0] >= wall - width) {
dots[i][2] = -dots[i][2];
}
if (dots[i][1] >= wall - 20 - width) {
dots[i][3] = -dots[i][3];
}
if (dots[i][0] < 0) {
dots[i][2] = -dots[i][2];
}
if (dots[i][1] < 0) {
dots[i][3] = -dots[i][3];
}
bounce();
}
}
repaint();
return dots;
}
//(x2-x1)^2 + (y1-y2)^2 <= (r1+r2)^2
public void bounce() {
for (int i = 0; i < 10; i++) {
for (int a = 0; a < 10; a++) {
if (a != i) {
System.out.println((dots[i][0] - dots[a][0])*(dots[i][0] - dots[a][0]) + (dots[i][1] - dots[a][1])*(dots[i][1] - dots[a][1]) <= (dots[i][4] + dots[a][4]) * (dots[i][4] + dots[a][4]));
collision = (dots[i][0] - dots[a][0])*(dots[i][0] - dots[a][0]) + (dots[i][1] - dots[a][1])*(dots[i][1] - dots[a][1]) <= (dots[i][4] + dots[a][4]) * (dots[i][4] + dots[a][4]);
}
}
}
}
/**
*
* #param g
*/
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
for (int i = 0; i < 10; i++) {
CreateDots();
g.drawOval((int) dots[i][0], (int) dots[i][1], width, width);
g.fillOval((int) dots[i][0], (int) dots[i][1], width, width);
}
}
}
<!-- end snippet -->
There were a couple of problems:
During bounce you should return the first time you find a collision, otherwise the collision will be set to true, but then could be set back to false on the next iteration in the for-loop.
In the first == true condition, you should initialize collision to true or it will never do the while loop at all. Either that or change it to a do-while.
During paintComponent you should not call CreateDots within the for-loop since it loops over all dots itself. Just call it before.
The code seems to work with these changes (including width of 400 not 380):
import java.awt.Dimension;
import java.awt.Graphics;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class PracticeDots extends JPanel {
float dots[][] = new float[10][7];
Random r = new Random();
boolean first = true;
float x = 0;
float y = 0;
float xAccel = 0;
float yAccel = 0;
int wall = 400;
int width = 50;
float radius = 0;
float centreX = 0;
float centreY = 0;
boolean collision;
public static void main(String[] args) {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(new PracticeDots());
f.setPreferredSize(new Dimension(400, 400));
f.setResizable(true);
f.pack();
f.setVisible(true);
}
public float[][] CreateDots() {
if (first == true) {
for (int i = 0; i < 10; i++) {
do {
x = r.nextInt(300);
y = r.nextInt(300);
xAccel = r.nextFloat() / 2;
yAccel = r.nextFloat() / 2;
radius = width / 2;
centreX = x + radius;
centreY = y + radius;
dots[i][0] = x;
dots[i][1] = y;
dots[i][2] = xAccel;
dots[i][3] = yAccel;
dots[i][4] = radius;
dots[i][5] = centreX;
dots[i][6] = centreY;
bounce();
} while (collision == true);
}
first = false;
} else {
for (int i = 0; i < 10; i++) {
dots[i][0] = dots[i][0] + dots[i][2];
dots[i][1] = dots[i][1] + dots[i][3];
if (dots[i][0] >= wall - width) {
dots[i][2] = -dots[i][2];
}
if (dots[i][1] >= wall - 20 - width) {
dots[i][3] = -dots[i][3];
}
if (dots[i][0] < 0) {
dots[i][2] = -dots[i][2];
}
if (dots[i][1] < 0) {
dots[i][3] = -dots[i][3];
}
bounce();
}
}
repaint();
return dots;
}
public void bounce() {
collision = false;
for (int i = 0; i < 10; i++) {
for (int a = 0; a < 10; a++) {
if (a != i && !(dots[a][0] == 0 && dots[a][1] == 0)) {
boolean thisCollision = (dots[i][0] - dots[a][0]) * (dots[i][0] - dots[a][0]) + (dots[i][1] - dots[a][1]) * (dots[i][1] - dots[a][1]) <= (dots[i][4] + dots[a][4]) * (dots[i][4] + dots[a][4]);
// System.out.println("collision: "+collision+" i="+i+" a="+a);
if (thisCollision) {
collision = true;
return;
}
}
}
}
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
CreateDots();
for (int i = 0; i < 10; i++) {
g.drawOval((int) dots[i][0], (int) dots[i][1], width, width);
g.fillOval((int) dots[i][0], (int) dots[i][1], width, width);
}
}
}

I'm trying to draw a new dot every 250 milliseconds but it only draws a dot once

//I'm trying to draw a new dot every 250 milliseconds but it only draws the dot a single time. I have tried fixing it many times, but it still will only paint a single dot, rather than one after 250 milliseconds. Is this a problem with the timer or the paint method? Here is the code:
import javax.swing.JPanel;
import javax.swing.Timer;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Window extends JPanel{
private int size;
private static double maxValue;
private double elevation;
private double vertV;
public double horizV;
public double gravity;
public double range;
public double time;
public double t = 0;
public Window(int s, double v, double e, double v2, double g,double h,double r,double t){
size = s;
maxValue = v;
elevation = e;
vertV = v2;
gravity = g;
horizV = h;
range = r;
time = t;
setPreferredSize(new Dimension(size, size));
}
public void paintComponent(Graphics g){
g.drawLine(size/25, 0,size/25, size);
g.drawLine(0, size - (size/25), size, size - (size/25));
double[] lines = getLine();
int x = size/5 + (size/25), y = size - (size/25);
int x2 = x;
for(int i = 0; i < 4; i++){
g.drawLine(x, y+5, x, y-5);
g.drawString(lines[i]+"",x-size/50,y+size/30);
x+=x2;
}
int yx = size/25, yy = size - (size/5 + (size/25));
int y2 = size/5 + (size/25);
for(int i=0;i<4;i++){
g.drawLine(yx-5, yy, yx+5, yy);
g.drawString(lines[i]+"",yx-size/25,yy+size/30);
yy -= y2;
}
drawDots(g);
}
//this is the place where i make the dots but it only makes one.
//used to be a for loop but i altered it to an if statement so i could paint one dot at a time
public void drawDots(Graphics g)
{
double ratio = (size-((size/25)*2))/maxValue;
double fx;
double xvalue;
// This for loop is where dots are drawn, each iteration draws one dot. It starts at zero, and counts up to the time variable t.
if(t<=time)
{
t+=0.025;
t = Math.round(t*1000.0)/1000.0;
fx = function(t);
xvalue = xfunction(t);
if(fx >= 0){
System.out.print("Time: " + t + " " + "Range: " + xvalue + " " + "Height: ");
System.out.println(fx);
g.drawLine((int)(size/25+(ratio*xvalue)), (int)((size-(size/25))-(ratio*fx)),
(int)(size/25+(ratio*xvalue)), (int)((size-(size/25))-(ratio*fx)));
}
}
}
//where i make the timer
//250 mill
public void dostuff()
{
int delay = 250;
ActionListener taskPerformer = new ActionListener()
{
public void actionPerformed(ActionEvent arg0)
{
repaint();
}
};
new Timer(delay, taskPerformer).start();
}
public double xfunction(double t){
double x = 0.0;
x = Math.round(horizV * t * 1000.0)/1000.0;
return x;
}
public double function(double t){
double fx = 0.0;
fx = Math.round((vertV*t + .5*(-(gravity))*(t*t) + elevation)*1000.0)/1000.0;
return fx;
}
private static double[] getLine(){
double increment = maxValue / 4;
double currentLine = 0;
double[] lines = new double[4];
for(int i = 0; i < 4; i++){
currentLine+=increment;
lines[i] = Math.round(currentLine * 10.0)/10.0;
}
return lines;
}
}
This is the original version of the code that displays the projectile's motion, but it does not wait 250 milliseconds between drawing each point:
import javax.swing.JPanel;
import java.awt.*;
public class Window extends JPanel{
private int size;
private static double maxValue;
private double elevation;
private double vertV;
public double horizV;
public double gravity;
public double range;
public double time;
public Window(int s, double v, double e, double v2, double g,double h,double r,double t){
size = s;
maxValue = v;
elevation = e;
vertV = v2;
gravity = g;
horizV = h;
range = r;
time = t;
setPreferredSize(new Dimension(size, size));
}
public void paintComponent(Graphics g){
g.drawLine(size/25, 0,size/25, size);
g.drawLine(0, size - (size/25), size, size - (size/25));
double[] lines = getLine();
int x = size/5 + (size/25), y = size - (size/25);
int x2 = x;
for(int i = 0; i < 4; i++){
g.drawLine(x, y+5, x, y-5);
g.drawString(lines[i]+"",x-size/50,y+size/30);
x+=x2;
}
int yx = size/25, yy = size - (size/5 + (size/25));
int y2 = size/5 + (size/25);
for(int i=0;i<4;i++){
g.drawLine(yx-5, yy, yx+5, yy);
g.drawString(lines[i]+"",yx-size/25,yy+size/30);
yy -= y2;
}
drawDots(g);
}
public void drawDots(Graphics g){
double ratio = (size-((size/25)*2))/maxValue;
double fx;
double xvalue;
// This for loop is where dots are drawn, each iteration draws one dot. It starts at zero, and counts up to the time variable t.
for(double t=0;t<=time; t+=0.025){
t = Math.round(t*1000.0)/1000.0;
fx = function(t);
xvalue = xfunction(t);
if(fx >= 0){
System.out.print("Time: " + t + " " + "Range: " + xvalue + " " + "Height: ");
System.out.println(fx);
g.drawLine((int)(size/25+(ratio*xvalue)), (int)((size-(size/25))-(ratio*fx)),
(int)(size/25+(ratio*xvalue)), (int)((size-(size/25))-(ratio*fx)));
}
}
}
public double xfunction(double t){
double x = 0.0;
x = Math.round(horizV * t * 1000.0)/1000.0;
return x;
}
public double function(double t){
double fx = 0.0;
fx = Math.round((vertV*t + .5*(-(gravity))*(t*t) + elevation)*1000.0)/1000.0;
return fx;
}
private static double[] getLine(){
double increment = maxValue / 4;
double currentLine = 0;
double[] lines = new double[4];
for(int i = 0; i < 4; i++){
currentLine+=increment;
lines[i] = Math.round(currentLine * 10.0)/10.0;
}
return lines;
}
}

B spline basis function seems to produce incorrect values

i wanted to implement B-splines in an Java Swing application. And since 4. May i tried nearly everything and spend every minute of my free time, but i don't get them right - i have headach since yesterday :/
To implement the B spline i used the specification from wikipedia
And i made (relating to MCVE) an demo version which can be found here: gist.github.com/soraphis/b-spline
the code shows the problem, its made to be called in an swing JPanel drawcomponent method. But you can comment this line and uncomment 71.
Some additional informations:
a and b in my basis function returns values < 0 or >1 which should not be (see wikipedia)
i want to implement the b splines myself - i dont want to use a library
referencinc to the wikipedia artikel:
basisFunc is B(x)
DeBoor is S(x)
i rly need help with the basis function, and i would like to know how to build up the knot vector "correctly"
Im thankful for every kind of reply
and thx for reading this
I can't imagine an appropriate answer that does not consist of a piece of code that you just can compile and run (without having to insert a main method and the surrounding GUI ... * wink *), regardless of how different it is from your code.
However, the weights that you have assigned to your T-array seemed odd, and the indices of the basis function seemed to be off +/-1. I tried to fix this, but it's still not entirely correct, maybe you or someone else likes to continue debugging this.
import java.awt.Color;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.util.Arrays;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class BSplineTest
{
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
#Override
public void run()
{
createAndShowGUI();
}
});
}
private static void createAndShowGUI()
{
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(new GridLayout(1, 1));
BSplineTestPanel bSplineTestPanel = new BSplineTestPanel();
frame.getContentPane().add(bSplineTestPanel);
frame.setSize(500,500);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
class BSplineTestPanel extends JPanel
{
#Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
Bspline bspline = new Bspline();
bspline.calculatePath(g);
}
}
class Bspline
{
double[][] P;
double[] T;
int _k = 3;
public Bspline()
{
P = new double[4][2];
P[0][0] = 100;
P[0][1] = 100;
P[1][0] = 50;
P[1][1] = 50;
P[2][0] = 100;
P[2][1] = 200;
P[3][0] = 50;
P[3][1] = 200;
update();
}
private void update()
{
if (P.length < 2)
return;
T = new double[_k + P.length + 1];
double d = 1.0 / (T.length-1);
for (int i = 0; i<T.length; i++)
{
T[i] = i * d;
}
System.out.println(Arrays.toString(T));
}
private double basisFunc(int i, int k, double t)
{
if (k == 0)
{
if (T[i] <= t && t < T[i + 1])
return 1;
return 0;
}
double a = (t - T[i]) / (T[i + k] - T[i]);
double b = (T[i + k + 1] - t) / (T[i + k + 1] - T[i + 1]);
return a * basisFunc(i, k - 1, t) + b * basisFunc(i + 1, k - 1, t);
}
private double[] DeBoor(double t)
{
double[] V = new double[2];
for (int i = 0; i < P.length; i++)
{
double scale = basisFunc(i, _k, t);
V[0] += P[i][0] * scale;
V[1] += P[i][1] * scale;
}
return V;
}
public void calculatePath(Graphics g)
{
if (P.length < 2)
{
return; // zu wenige punkte um ein pfad zu zeichnen
}
double[] v = null;
double delta = 1 / 32.0;
for (double t = T[2]; t < T[5]; t += delta)
{
double[] p = DeBoor(t);
if (v != null)
{
g.setColor(new Color((int)(t*255), 0, 0));
g.drawLine((int) v[0], (int) v[1], (int) p[0], (int) p[1]);
}
v = p;
}
for (int i = 0; i < P.length; i++)
{
int x = (int)P[i][0];
int y = (int)P[i][1];
g.setColor(Color.RED);
g.fillOval(x-2, y-2, 4, 4);
g.drawString(String.valueOf(i), x, y+15);
}
}
}
(Compare to http://www.ibiblio.org/e-notes/Splines/basis.html, "Quadratic B-spline (n = 3, k = 3)")
Apart from that I wonder how such an overly complicated **** like deBoors algorithm could become so "famous". Use De-Casteljau and you'll be done in a few minutes, without a single debugging run.
EDIT A port of the code from http://chi3x10.wordpress.com/2009/10/18/de-boor-algorithm-in-c/
// From http://chi3x10.wordpress.com/2009/10/18/de-boor-algorithm-in-c/
double[] deBoor(int k,int degree, int i, double x, double knots[], double ctrlPoints[][])
{
if( k == 0)
{
i = Math.max(0, Math.min(ctrlPoints.length-1, i));
return ctrlPoints[i];
}
else
{
double alpha = (x-knots[i])/(knots[i+degree+1-k]-knots[i]);
double p0[] = deBoor(k-1,degree, i-1, x, knots, ctrlPoints);
double p1[] = deBoor(k-1,degree, i, x, knots, ctrlPoints);
double p[] = new double[2];
p[0] = p0[0] *(1-alpha ) + p1[0]*alpha;
p[1] = p0[1] *(1-alpha ) + p1[1]*alpha;
return p;
}
}
int WhichInterval(double x, double knot[], int ti)
{
int index = -1;
for(int i = 1; i <= ti - 1; i++)
{
if(x < knot[i]) {
index = i - 1;
break;
}
}
if(x == knot[ti - 1]) {
index = ti - 1;
}
return index;
}
private double[] DeBoor(double t)
{
int i = WhichInterval(t, T, T.length);
return deBoor(_k, 3, i, t, T, P);
}

Java perlin noise

I need to make perlin noise like in AS3.0:
bitmapData.perlinNoise(baseX, baseY, numOctaves,
randomSeed, stitch, fractalNoise, grayScale, offsets);
It's seamless noise:
I found a lot of material about it, but I can't make it like in my as3.0 image. Java code:
import java.awt.Color;
import java.awt.Graphics;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
#SuppressWarnings("serial")
public class Noise extends JPanel{
public static int octaves = 4;
public static int size = 128;
public static float[][][] noise = new float[size][size][octaves];
public static float[][] perlinnoise = new float[size][size];
public static float p = (float) 1/4;
public static Random gen = new Random();
public static float GenerateNoise() {
return gen.nextFloat();
}
public static float SmoothNoise(int x, int y, int z) {
try{
float corners = (noise[x - 1][y - 1][z] + noise[x + 1][y - 1][z] + noise[x - 1][y + 1][z] + noise[x + 1][y + 1][z]) / 16;
float sides = (noise[x - 1][y][z] + noise[x + 1][y][z] + noise[x][y - 1][z] + noise[x][y + 1][z]) / 8;
float center = noise[x][y][z] / 4;
return corners + sides + center;
}catch(Exception e) {
return 0;
}
}
public static float InterpolatedNoise(float x, float y, int pX, int pY, int pZ) {
int intX = (int) x;
int intY = (int) y;
float fracX = x - intX;
float fracY = y - intY;
float v1 = SmoothNoise(pX, pY, pZ);
float v2 = SmoothNoise(pX + 1, pY, pZ);
float v3 = SmoothNoise(pX, pY + 1, pZ);
float v4 = SmoothNoise(pX + 1, pY + 1, pZ);
float i1 = Interpolate(v1, v2, fracX);
float i2 = Interpolate(v3, v4, fracX);
return Interpolate(i1, i2, fracY);
}
public static float Interpolate(float a, float b, float x) {
float ft = (float) (x * 3.1415927);
float f = (float) ((1 - Math.cos(ft)) * 0.5);
return (float) (a * (1 - f) + b * f);
}
public static float Perlin2D(float x, float y, int posX, int posY, int posZ) {
float total = 0;
for(int i = 0; i < octaves; i++) {
double f = Math.pow(2, i);
double a = Math.pow(p, i);
total = (float) (total + InterpolatedNoise((float)(x * f), (float)(y * f), posX, posY, posZ) * a);
}
return total;
}
public static void main(String [] args) {
for(int z = 0; z < octaves; z++) {
for(int y = 0; y < size; y++) {
for(int x = 0; x < size; x++) {
noise[x][y][z] = GenerateNoise();
}
}
}
for(int z = 0; z < octaves; z++) {
for(int y = 0; y < size; y++) {
for(int x = 0; x < size; x++) {
perlinnoise[x][y] = Perlin2D(x / (size - 1), y / (size - 1), x, y, z) / octaves;
}
}
}
JFrame f = new JFrame("Perlin Noise");
f.setSize(400, 400);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(new Noise());
f.setVisible(true);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
for(int y = 0; y < size; y++) {
for(int x = 0; x < size; x++) {
g.setColor(new Color(perlinnoise[x][y], perlinnoise[x][y], perlinnoise[x][y]));
g.fillRect(x * 2, y * 2, 2, 2);
}
}
repaint();
}
}
Help please!
The trick is, the Perlin noise does not use pseudo-random generator, it uses a function that takes an argument and returns predefined value for that argument, but when argument shifts by 1, the value jumps almost randomly. Check the sources for the permutation formulae, the init() method makes a permutation that then is used to make the entire noise.

Java Perlin Noise Implementation Problems

Hey stackoverflow community! I have been reading about perlin noise for the past 2 weeks and tried implementing it on my own in the most basic way. Even so, my program does not work. It outputs near similar looking results all the time and the persistence does not seem to change anything. Here is my code:
import java.awt.Color;
import java.awt.Graphics;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
#SuppressWarnings("serial")
public class Noise extends JPanel{
public static int octaves = 4;
public static int size = 128;
public static float[][][] noise = new float[size][size][octaves];
public static float[][] perlinnoise = new float[size][size];
public static float p = (float) 1/4;
public static Random gen = new Random();
public static float GenerateNoise() {
return gen.nextFloat();
}
public static float SmoothNoise(int x, int y, int z) {
try{
float corners = (noise[x - 1][y - 1][z] + noise[x + 1][y - 1][z] + noise[x - 1][y + 1][z] + noise[x + 1][y + 1][z]) / 16;
float sides = (noise[x - 1][y][z] + noise[x + 1][y][z] + noise[x][y - 1][z] + noise[x][y + 1][z]) / 8;
float center = noise[x][y][z] / 4;
return corners + sides + center;
}catch(Exception e) {
return 0;
}
}
public static float InterpolatedNoise(float x, float y, int pX, int pY, int pZ) {
int intX = (int) x;
int intY = (int) y;
float fracX = x - intX;
float fracY = y - intY;
float v1 = SmoothNoise(pX, pY, pZ);
float v2 = SmoothNoise(pX + 1, pY, pZ);
float v3 = SmoothNoise(pX, pY + 1, pZ);
float v4 = SmoothNoise(pX + 1, pY + 1, pZ);
float i1 = Interpolate(v1, v2, fracX);
float i2 = Interpolate(v3, v4, fracX);
return Interpolate(i1, i2, fracY);
}
public static float Interpolate(float a, float b, float x) {
float ft = (float) (x * 3.1415927);
float f = (float) ((1 - Math.cos(ft)) * 0.5);
return (float) (a * (1 - f) + b * f);
}
public static float Perlin2D(float x, float y, int posX, int posY, int posZ) {
float total = 0;
for(int i = 0; i < octaves; i++) {
double f = Math.pow(2, i);
double a = Math.pow(p, i);
total = (float) (total + InterpolatedNoise((float)(x * f), (float)(y * f), posX, posY, posZ) * a);
}
return total;
}
public static void main(String [] args) {
for(int z = 0; z < octaves; z++) {
for(int y = 0; y < size; y++) {
for(int x = 0; x < size; x++) {
noise[x][y][z] = GenerateNoise();
}
}
}
for(int z = 0; z < octaves; z++) {
for(int y = 0; y < size; y++) {
for(int x = 0; x < size; x++) {
perlinnoise[x][y] = Perlin2D(x / (size - 1), y / (size - 1), x, y, z) / octaves;
}
}
}
JFrame f = new JFrame("Perlin Noise");
f.setSize(400, 400);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(new Noise());
f.setVisible(true);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
for(int y = 0; y < size; y++) {
for(int x = 0; x < size; x++) {
g.setColor(new Color(perlinnoise[x][y], perlinnoise[x][y], perlinnoise[x][y]));
g.fillRect(x * 2, y * 2, 2, 2);
}
}
repaint();
}
}
I do not understand why it is not working because it is exactly as the pseudo code in this article said to do it. Can anyone assist me in figuring this out? Thanks.
EDIT: Ok please can someone just explain the process required to do this PLEASE I am going crazy trying to figure this out. I have been trying to figure it out for the past 2 weeks and no one is giving me any help with it. Please if you know how to do this, please just explain it to me I would greatly appreciate it. Thanks.

Categories

Resources