I just started with world generation and I've been looking for tutorials on perlin noise everywhere but sadly there are not alot to be found on Google.
The last days I followed a tutorial but I can't get my code to work.
Here is my Java method.
private static double[][] createNoise(int xn, int yn, int sps) {
int m = yn * sps;
int n = xn * sps;
double[][] u = new double[yn + 1][];
double[][] v = new double[yn + 1][];
double[][] x = new double[m][];
double[][] y = new double[m][];
double[][] z = new double[m][];
for (int i = 0; i < m; i++) {
x[i] = new double[n];
y[i] = new double[n];
z[i] = new double[n];
}
for (int i = 0; i < yn + 1; i++) {
u[i] = new double[xn + 1];
v[i] = new double[xn + 1];
}
for (int i = 0; i < xn + 1; i++) {
for (int j = 0; j < yn + 1; j++) {
u[i][j] = nextRandom();
v[i][j] = nextRandom();
}
}
double hx = xn / (n - 1);
double hy = yn / (m - 1);
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
x[i][j] = hx * j;
y[i][j] = hy * i;
}
}
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
int xc = (int)x[i][j];
int yc = (int)y[i][j];
if (x[i][j] % 1 == 0 && x[i][j] != 0 ) xc = xc - 1;
if (y[i][j] % 1 == 0 && y[i][j] != 0 ) yc = yc - 1;
double xr = x[i][j] - xc;
double yr = y[i][j] - yc;
double s11[] = {-xr, -yr};
double s21[] = {-xr, 1 - yr};
double s22[] = {1 - xr, 1 - yr};
double s12[] = {1 - xr, -yr};
double q11 = s11[0] * u[yc][xc] + s11[1] * v[yc][xc];
double q21 = s21[0] * u[yc + 1][xc] + s21[1] * v[yc + 1][xc];
double q22 = s22[0] * u[yc + 1][xc + 1] + s22[1] * v[yc + 1][xc + 1];
double q12 = s12[0] * u[yc][xc + 1] + s12[1] * v[yc][xc + 1];
z[i][j] = lerp(x[i][j], y[i][j], xc, xc + 1, yc, yc + 1, q11, q12, q21, q22);
}
}
return z;
}
The heightmap that the method returns sadly enough looks like this
As you can see, the first row/column is working, but after that the algorithm seems to fail.
I made sure that the method
nextRandom();
returns a float value between -1 & 1.
Thanks alot!
Thanks to user #gawi for pointing this out.
hx = xn / (n - 1);
will divide 2 integers, and most likely return 0.
You can fix this by casting a double to it:
double hx = (double)xn / (n - 1);
Then the map just works!
Related
I found a method to do Delaunay triangulation, but I don't quite understand what the inputs int[] x, int[] y, int[] z are.
import java.awt.Point;
import java.util.Iterator;
import java.util.TreeSet;
public class DelaunayTriangulation{
int[][] adjMatrix;
DelaunayTriangulation(int size){
this.adjMatrix = new int[size][size];
}
public int[][] getAdj(){
return this.adjMatrix;
}
// n = Number of points
// adjMatrix = what point is connected to what (double)
public TreeSet getEdges(int n, int[] x, int[] y, int[] z){
TreeSet result = new TreeSet();
if(n == 2){
this.adjMatrix[0][1] = 1;
this.adjMatrix[1][0] = 1;
result.add(new GraphEdge(new GraphPoint(x[0], y[0]), new GraphPoint(x[1], y[1])));
return result;
}
for(int i = 0; i < n - 2; i++){
for(int j = i + 1; j < n; j++){
for (int k = i + 1; k < n; k++){
if(j == k){
continue;
}
int xn = (y[j] - y[i]) * (z[k] - z[i]) - (y[k] - y[i]) * (z[j] - z[i]);
int yn = (x[k] - x[i]) * (z[j] - z[i]) - (x[j] - x[i]) * (z[k] - z[i]);
int zn = (x[j] - x[i]) * (y[k] - y[i]) - (x[k] - x[i]) * (y[j] - y[i]);
boolean flag;
if(flag = (zn < 0 ? 1 : 0) != 0){
for(int m = 0; m < n; m++){
flag = (flag) && ((x[m] - x[i]) * xn + (y[m] - y[i]) * yn + (z[m] - z[i]) * zn <= 0);
}
}
if (!flag){
continue;
}
result.add(new GraphEdge(new GraphPoint(x[i], y[i]), new GraphPoint(x[j], y[j])));
result.add(new GraphEdge(new GraphPoint(x[j], y[j]), new GraphPoint(x[k], y[k])));
result.add(new GraphEdge(new GraphPoint(x[k], y[k]), new GraphPoint(x[i], y[i])));
this.adjMatrix[i][j] = 1;
this.adjMatrix[j][i] = 1;
this.adjMatrix[k][i] = 1;
this.adjMatrix[i][k] = 1;
this.adjMatrix[j][k] = 1;
this.adjMatrix[k][j] = 1;
}
}
}
return result;
}
public TreeSet getEdges(TreeSet pointsSet){
if((pointsSet != null) && (pointsSet.size() > 0)){
int n = pointsSet.size();
int[] x = new int[n];
int[] y = new int[n];
int[] z = new int[n];
int i = 0;
Iterator iterator = pointsSet.iterator();
while (iterator.hasNext()){
Point point = (Point)iterator.next();
x[i] = (int)point.getX();
y[i] = (int)point.getY();
z[i] = (x[i] * x[i] + y[i] * y[i]);
i++;
}
return getEdges(n, x, y, z);
}
return null;
}
}
Like in your comment it transform the problem and lifts the points to a paraboloid then takes the bottom convex hull and project it back to 2d by omitting the third co-ordinate.
I'm working on this problem https://projecteuler.net/problem=49 .
This is the function to check every permutation of a number(4 digit) passed to it, and check them for primality, and if there are more than 2 (ie 3) print the numbers.
the output I'm getting is a never ending sequence of numbers. What am I doing wrong?
P.s- pretty sure it has to do with the repetition of digits, can't figure out how to work around it.
void checkperm(int a) {
int w, x, y, z = 0;
int count = 0;
w = a % 10;
x = (a % 100 - w) / 10;
y = (a % 1000 - (10 * x + w) / 100);
z = a - (y * 100 + x * 10 + w)/1000;
System.out.println(w+x+y+z); /*test*/
int[] data;
data = new int[] { w, x, y, z };
int[] num = new int[100];
for (int m = 0; m < 4; m++) {
for (int n = 0; n < 4; n++) {
for (int o = 0; o < 4; o++) {
for (int p = 0; p < 4; p++) {
if (true) {
int gnaw = 1000 * data[m] + 100 * data[n] + 10 * data[o] + data[p];
if (checkprime(gnaw)) {
num[count] = gnaw;
count++;
}
}
}
}
}
}
if (count > 2)
for (int h = 0; h < 4; h++) {
System.out.println(num[h]);
}
}
the way you're calculating w, x, y and z is wrong.
what it should be -
int temp = a;
w = temp%10;
temp = temp/10;
x = temp%10;
temp = temp/10;
y = temp%10;
temp = temp/10;
z = temp;
This is just logic correction from your code. Ideally all this should happen in a loop.
This will help assuming your rest of code is logically correct (which I haven't gone through).
I have unfinished code to find the points of intersection of all lines that are perpendicular. So far I have this:
import java.util.Scanner;
public class CountSquares {
public static void main(String args[]) {
Scanner scan = new Scanner(System.in);
int lines = scan.nextInt();
scan.nextLine();
double[][] lineMXYC = new double[4][lines]; // stores the slope, and x
// and y co-ordinates and c
// so the line can be
// represented as y = mx + c
double x1 = 0.0, x2 = 0.0, y1 = 0.0, y2 = 0.0;
double slope = 0.0;
for (int i = 0; i < lines; i++) {
String input = scan.nextLine();
String[] arrayOfInput = input.split(" ");
x1 = Integer.parseInt(arrayOfInput[0]);
y1 = Integer.parseInt(arrayOfInput[1]);
x2 = Integer.parseInt(arrayOfInput[2]);
y2 = Integer.parseInt(arrayOfInput[3]);
if (x1 == x2)
slope = Double.POSITIVE_INFINITY;
else
slope = (y2 - y1) / (x2 - x1);
lineMXYC[0][i] = slope;
lineMXYC[1][i] = x1;
lineMXYC[2][i] = y1;
lineMXYC[3][i] = y1 - (slope * x1);
}
for (int j = 0; j < lines - 1; j++) { //sorts the array by slopes
if (lineMXYC[0][j] > lineMXYC[0][j + 1]) {
double TEMP = lineMXYC[0][j + 1];
lineMXYC[0][j + 1] = lineMXYC[0][j];
lineMXYC[0][j] = TEMP;
}
}
double[] pointsOfIntersectionX = new double[(int) (lines * lines / 4) + 1]; //max number of points there can be
double[] pointsOfIntersectionY = new double[(int) (lines * lines / 4) + 1];
int count = 0;
for (int k = 0; k < lines; k++) {
for (int n = k; n < lines; n++) {
System.out.println(n + " " + k);
if (1 / lineMXYC[0][k] == -lineMXYC[0][n]) {
double m1 = lineMXYC[0][k];
double m2 = lineMXYC[0][n];
double c1 = lineMXYC[3][k];
double c2 = lineMXYC[3][n];
System.out.println("m1: "+m1);
System.out.println("m2: "+m2);
System.out.println("c1: "+c1);
System.out.println("c2: "+c2);
pointsOfIntersectionX[count] = (c1 - c2) / (m2 - m1); //determinate to find x co-ordinate
pointsOfIntersectionY[count] = (m2 * c1 - m1 * c2)
/ (m2 - m1);
System.out.println("The lines intersect at: ("
+ pointsOfIntersectionX[count] + ", "
+ pointsOfIntersectionY[count] + ")");
count++;
}
}
}
scan.close();
}
}
This will take in the number of lines, then two points on each line seperated by spaces. If I enter
2
3 -1 0 8
3 -1 0 -2
It works fine, finding the point (3, -1)
However, if I put in the same values reversed
2
3 -1 0 -2
3 -1 0 8
It gives me (-3.0, 6.999999999999999) which is wrong
What is going wrong with the code? I can't pinpoint where the problem comes from.
Sorting by slopes may mix your input data in your version.
If you want to swap the lines, swap all line data:
for (int j = 0; j < lines - 1; j++) { //sorts the array by slopes
if (lineMXYC[0][j] > lineMXYC[0][j + 1]) {
for (int i = 0; i < 4; i++) {
double TEMP = lineMXYC[i][j + 1];
lineMXYC[i][j + 1] = lineMXYC[i][j];
lineMXYC[i][j] = TEMP;
}
}
}
If I may give you an advice:
make a separate Line class for better design
implement the compare method or a line comparator
use some sorting algorithm, the one you use will not sort correctly for more lines, e.g. see Java Tutorials
I need to use comb filter/transform to detect fundamental frequency of a wav file in java.
I also needed to implement ZCR, but this was easy.
Now I have this:
int best = 0, best_step = 0;
for (int step = 3; step < 400; ++step) {
int sum = 0;
for (i = 1; i < 10 && i * step < spectrum.length; ++i) {
for (int di = 0; di < i; ++di) {
sum += spectrum[i * step + di] / i;
}
}
sum *= 100;
comb.add(sum);
}
int sum = 0;
for (i = 0; i < comb.size(); ++i) {
sum = comb.get(i); // 3 * comb[i] - comb[i-1] - comb[i+1];
System.out.println(i + " - " + sum);
if (sum > best) {
best_step = i;
best = sum;
}
}
And my problem is that this code detects the wrong frequency. ;( I have searched for an algorithm/implementation (in any language) but have not found anything.
Note, I cannot use autocorelation, etc.. It must be comb filtering.
Edit: A little more explanation of my code:
I load a wav file and put frames to array frames. Then I make fft on it and have array of Complex (named widmo) (simple structure to handle complex numbers).
Now I put abs of Complex numbers into array spectrum:
double[] spectrum = new double[widmo.length];
for (i = 0; i + 1 < widmo.length; ++i) {
spectrum[i] = widmo[i].abs();
}
ArrayList<Integer> comb = new ArrayList<Integer>();
int best = 0, best_step = 0;
for (int step = 3; step < 400; ++step) {
int sum = 0;
for (i = 1; i < 10 && i * step < spectrum.length; ++i) {
for (int di = 0; di < i; ++di) {
sum += spectrum[i * step + di] / i;
}
}
// sum /= step + 100; // ta linijka pozwala usunąć sporo
// niespodziewanych skoków częstotliwości
sum *= 100;
comb.add(sum);
}
int sum = 0;
for (i = 0; i < comb.size(); ++i) {
sum = comb.get(i); // 3 * comb[i] - comb[i-1] - comb[i+1];
// ctx.fillRect(i, canvas.height, 1, -sum);
System.out.println(i + " - " + sum);
// tmp.add(new freqTime(sum,));
if (sum > best) {
best_step = i;
best = sum;
}
}
System.out.println();
System.out.println(best_step);
System.out.println(4 * 44100);
System.out.println((frames.length / numChanels));
System.out.println(best_step * 44100
/ (frames.length / numChanels));
The last println should show me my fundamental frequency, but it doesn't,.
I got this in javascript from my friend.
I figure it out (i think:P). Last println gives basic freq :). Maybe someone will need it or even imporve it :)
ArrayList<double[]> okna = new ArrayList<>();
ArrayList<freqTime> lista = new ArrayList<freqTime>();
int po2 = (int) Math.pow(2,
Integer.parseInt((String) potega2Input.getText()));
po2 /= 2;
double[] triangles = new double[po2];
double maxWykres = 0;
int licznik = 0;
int licznik2 = 0;
int T = frames.length;
boolean wykresFlaga = false;
for (int k = 0; k < T; k += po2) {
licznik = 0;
licznik2 = 0;
double[] tmp = new double[po2];
Complex[] zespolone = new Complex[po2];
for (int i = k; i < k + po2; i++) {
if (i < T) {
tmp[licznik] = frames[i];
zespolone[licznik] = new Complex(frames[i], 0);
licznik2 = licznik;
} else {
tmp[licznik] = frames[licznik2];
zespolone[licznik] = zespolone[licznik2];
}
licznik++;
}
okna.add(tmp);
FFT fft = new FFT();
zespolone = fft.fft(zespolone);
double maxF = 0;
double maxFI = 0;
double maxH = findMaxComp(zespolone);
double[] doWykresu = new double[zespolone.length];
for (int a = 2; a < 100; a++) {
for (int i = 0; i < po2; i++) {
doWykresu[i] = zespolone[i].abs();
triangles[i] = Math.abs(i % (2 * a) - a)
* (maxH) / a;
// triangles[i] = Math.abs(i % (2 * a) - a) * (maxH)
// / a;
}
double sumT = 0;
for (int i = 0; i < po2 / 2; i++) {
sumT += triangles[i] * doWykresu[i];
}
if (sumT > maxF) {
maxF = sumT;
maxFI = a;
}
}
//
// maxFI /= 2;
//
if (wykresFlaga == false) {
maxWykres = maxH;
}
for (int i = 0; i < po2; i++) {
doWykresu[i] = zespolone[i].abs();
triangles[i] = Math.abs(i % (2 * maxFI) - maxFI)
* (maxWykres) / maxFI;
}
if (wykresFlaga == false) {
System.out.println("Max w widmie: " + maxWykres);
new Wykres(doWykresu, 1, triangles);
wykresFlaga = true;
}
// System.out.println((2 * 44100 / po2) * maxFI);
System.out.println((float) (44100 / (float) po2)
* 2*(float) maxFI + " Znalzione a: " + maxFI);
lista.add(new freqTime(
(int) ((float) (44100 / (float) po2) *2* (float) maxFI),
(double) ((double) po2 / 44100)));
/*
* System.out.println((44100 / po2) * maxFI + " " + maxFI +
* " " + maxFI / 44100 + " " + 44100 / (maxFI / po2 * 44100)
* + " " + 44100 * maxFI / T);
*/
// System.out.println(zespolone[(int) maxFI/2].abs());
}
I need to write a method using an ArrayList but I can't quite figure out how to do it.
I was able to do it with just using an array and I was wondering if there was an easy way to change it so that it does implement an ArrayList.
Here is my current code:
//public ArrayList<Integer> getPixelsInWindow(int wSize, int x, int y) {
//ArrayList<Integer> values = new ArrayList<Integer>();
public int[] getPixelsInWindow(int wSize, int x, int y) {
int [] values;
int xMin = 0;
int xMax = 0;
int yMin = 0;
int yMax = 0;
xMin = x - (wSize / 2);
if (xMin < 0)
xMin = 0;
yMin = y - (wSize / 2);
if (yMin < 0)
yMin = 0;
xMax = x + (wSize / 2);
if (xMax >= rowN)
xMax = rowN - 1;
yMax = y + (wSize / 2);
if (yMax >= columnN)
yMax = columnN - 1;
int differenceX = xMax-xMin;
int differenceY = yMax-yMin;
values = new int[(differenceX + 1) * (differenceY + 1)];
int j = 0;
for(int i = xMin;i < xMax + 1;i++){
for(int k = yMin;k < yMax + 1;k++){
values[j] = img[i][k];
if(j == 0){
}
j++;
}
}
return values;
}
This was done quickly and not tested... but the idea is there, I am sure:
...
List<Integer> values = new ArrayList<Integer>();
int j = 0;
for(int i = xMin;i < xMax + 1;i++){
for(int k = yMin;k < yMax + 1;k++){
values.add(new Integer(img[i][k]));
...
}
}