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
Related
So I had to write an algorithm for the Simpson's double integral so I can find the answer in a much faster manner. I had a guide that showed the steps to follow to write this program. After following this guide and running it in netbeans, I found out that the values coming out of the program where not really close to the real answer. This is the code that I written in java:
//INPUT
double a = 0,b = 1; // Endpoints
int m = 8,n = 4;
double K1 = 0, K2 = 0, K3 = 0;
//OUPUT
//Step 1
double h = (b - a) / n;
double j1 = 0; //End terms
double j2 = 0; //Even terms
double j3 = 0; //Odd terms
//Step 2
for(int i = 0; i <= n; i++){
//Step 3
double x = a + (i * h);
double hX = (d(x) - c(x)) / m;
K1 = f(x, c(x)) + f(x, d(x)); // End terms
//Step 4
for (int j = 1; j < (m-1); j++){
//Step 5
double y = c(x) + (j * hX);
double q = f(x,y);
//Step 6
if (j % 2 == 0){
K2 = K2 + q;
}
else
K3 = K3 + q;
}
//Step 7
double l = (K1 + (2*K2) + (4*K3)) * (hX / 3);
//Step 8
if (i == 0 || i == n)
j1 = j1 + l;
else if (i % 2 == 0)
j2 = j2 + l;
else
j3 = j3 + l;
}
double j = h * (j1 + (2 * j2) + (4 * j3)) / 3;
System.out.println("j = " + j);
}
public static double c(double x){
return x;
}
public static double d(double x){
return 2 * x;
}
public static double f(double x, double y){
return (Math.pow(y, 2) + Math.pow(x, 3));
}
I tried debugging the program several times but I haven't yet found why I am encountering this mistake. If there's any mistake that you find in my code please let me know to see if it fixes it. For the given example, I am getting the value of 0.9069281684027777 instead of having the correct value which is 0.7838542. Thank you for your help. You can also see the guide that I followed to be able to create this program.
I did not check the math, the large error seems to indicate an error in the algorithm implemented. The for-bounds are dubious. And floating point errors exist.
Instead of multiplying a fraction by a running index (which would multiply the floating point approximation error in the fraction), better do:
Instead:
double h = (b - a) / n;
for (int i = 0; i <= n; i++) {
double x = a + (i * h);
do
for (int i = 0; i < n; i++) {
double x = a + i * (b - a) / n;
or
for (int i = 0; i <= n; i++) {
double x = a + i * (b - a) / (n + 1);
The boundary n being a bit unclear to me.
I created a program that generates a user inputted number of pairs of points. It then goes through a bruteforce and divide and conquer methods to find the closest pair of points. The bruteforce method works perfectly. The divide and conquer method on the other hand gives me an output but it is different than the brute force distance almost 90% of the time. I can't seem to figure out why it is like this in my code. NOTE: Some of the comments in the functions are from my teacher. Also, the closest_pair function along with rec_cl_pair have been given to me by my teacher where I must use them but had to adjust to my code (they were pseudo code for most part).
My code is:
import java.util.*;
import static java.lang.Math.min;
public class ClosestPair{
private Double x;
private Double y;
private static Double minDist = Double.POSITIVE_INFINITY;
private static ClosestPair closestPair1 = new ClosestPair(0.0,0.0);
private static ClosestPair closestPair2 = new ClosestPair(0.0,0.0);
public ClosestPair(Double x, Double y){
this.x = x;
this.y = y;
}
public static void main(String[] args) {
Double rangeMin = 0.0;
Double rangeMax = 1000.0;
Random r = new Random();
Scanner scan = new Scanner(System.in);
System.out.print("\nEnter the number of two dimensional arrays: ");
int dim = scan.nextInt();
ClosestPair[] pair = new ClosestPair[dim];
ClosestPair[] pairCopy = new ClosestPair[dim];
for(int i = 0; i < dim; i++){
Double xVal = rangeMin + (rangeMax - rangeMin) * r.nextDouble();
Double yVal = rangeMin + (rangeMax - rangeMin) * r.nextDouble();
pair[i] = new ClosestPair(xVal,yVal);
//System.out.print(pair[i].x + ", " + pair[i].y + "\n");
}
/*
for(int j = 0; j < pair.length; j++){
System.out.print(pair[j].x + ", " + pair[j].y + "\n");
}
*/
pairCopy = pair;
pair = mergeSort(pair);
/*
System.out.print("\n\n\n");
for(int j = 0; j < pair.length; j++){
System.out.print(pair[j].x + ", " + pair[j].y + "\n");
}
*/
//BRUTE FORCE PRINT STATEMENTS
long startTime = System.nanoTime();
bruteForce(pair);
long endTime = System.nanoTime();
long timeSpent = endTime - startTime;
System.out.print("\nMin Distance = " + minDist);
System.out.print("\n(x1,y1) = " + closestPair1.x + ", " + closestPair1.y);
System.out.print("\n(x2,y2) = " + closestPair2.x + ", " + closestPair2.y);
System.out.print("\nTime: " + timeSpent + "\n\n");
minDist = 0.0;
//CONQUER DIVIDE PRINT STATEMENTS
startTime = System.nanoTime();
minDist = closest_pair(pairCopy);
endTime = System.nanoTime();
timeSpent = endTime - startTime;
System.out.print("Min Distance = " + minDist);
System.out.print("\nTime: " + timeSpent);
scan.close();
}
private static void bruteForce(ClosestPair[] pair) {
for(int i = 1; i < pair.length - 1; i++){
for(int j = i + 1; j < pair.length; j++){
ClosestPair p = new ClosestPair(pair[i].x,pair[i].y);
//System.out.print("\np:" + pair[i].x + ", " + pair[i].y);
ClosestPair q = new ClosestPair(pair[j].x,pair[j].y);
//System.out.print("\nq: " + pair[j].x + ", " + pair[j].y);
if(getDistance(p, q) < minDist){
minDist = getDistance(p, q);
closestPair1.x = p.x;
closestPair1.y = p.y;
closestPair2.x = q.x;
closestPair2.y = q.y;
}
}
}
}
private static Double getDistance(ClosestPair p1, ClosestPair p2) {
double xdist = p2.x - p1.x;
double ydist = p2.y - p1.y;
return Math.hypot(xdist, ydist);
}
static ClosestPair[] mergeSort(ClosestPair[] a) {
if (a.length > 1) {
int q = a.length/2;
ClosestPair[] leftArray = Arrays.copyOfRange(a, 0, q);
ClosestPair[] rightArray = Arrays.copyOfRange(a,q,a.length);
mergeSort(leftArray);
mergeSort(rightArray);
a = merge(a,leftArray,rightArray);
}
return a;
}
static ClosestPair[] merge(ClosestPair[] a, ClosestPair[] l, ClosestPair[] r) {
int totElem = l.length + r.length;
//int[] a = new int[totElem];
int i,li,ri;
i = li = ri = 0;
while ( i < totElem) {
if ((li < l.length) && (ri<r.length)) {
if (l[li].x < r[ri].x) {
a[i] = l[li];
i++;
li++;
}
else {
a[i] = r[ri];
i++;
ri++;
}
}
else {
if (li >= l.length) {
while (ri < r.length) {
a[i] = r[ri];
i++;
ri++;
}
}
if (ri >= r.length) {
while (li < l.length) {
a[i] = l[li];
li++;
i++;
}
}
}
}
return a;
}
//START OF CONQUER DIVIDE SECTOIN
static double closest_pair(ClosestPair[] p){
int n = p.length - 1;
p = mergeSortDC(p, 0, n); // sort all n points by x-coordinate
return rec_cl_pair(p, 0, n);
}
static double rec_cl_pair(ClosestPair[] p, int i, int j){ // finds closest pair between points in p[i..j]
// assumes input is sorted by x-coordinate
// at termination, input is sorted by y-coordinate
// i is the left index of the subarray, j is the right index
if (j - i < 3){ // at most 3 points in p[i..j]
p = mergeSortDC (p, i, j); // sort p[i..j] by y-coordinate
double delta = getDistance(p[i], p[i+1]);
if (j - i == 1) { // two points
minDist = delta;
return delta;
}
else{
double min1 = min(getDistance(p[i+1], p[i+2]), getDistance(p[i], p[i+2]));
minDist = min(delta,min1);
return minDist;
}
}
int m = (i + j)/2;
double line = p[m].x;
double deltaL = rec_cl_pair(p, i, m); // p[i..m] is sorted by y-coordinate
double deltaR = rec_cl_pair(p, m+1, j); // p[m+1..j] is sorted by y-coordinate
double delta = min(deltaL, deltaR);
p = mergeDC(p, i, m, j); // p[i..j] is now sorted by y-coordinate
// Of points in p[i..j], find points in vertical strip of width 2*delta,
// centered at line (middle of x-values), and store in array v
int t = 0;
ClosestPair[] v = new ClosestPair[j+1];
for(int k = i; k < j; k++){
if ((p[k].x > line - delta) && (p[k].x < line + delta)){
t = t + 1;
v[t] = p[k];
}
}
// Find closest pairs among points in array v. NOTE: Cool math shows
// there are at most 8 points in the strip at distance < delta. Thus,
// in the loops below, each point is compared to at most 7 other points.
for(int k = 1;k < t-1; k++){
for(int s = k+1; k < min(t,k+7); s++){ // inner loop iterates <= 7 times
delta = min(delta, getDistance(v[k],v[s]));
minDist = delta;
return delta;
}
}
return minDist;
}
private static ClosestPair[] mergeSortDC(ClosestPair[] p, int low, int high) {
// check if low is smaller then high, if not then the array is sorted
if (low < high) {
// Get the index of the element which is in the middle
int middle = low + (high - low) / 2;
// Sort the left side of the array
mergeSortDC(p, low, middle);
// Sort the right side of the array
mergeSortDC(p, middle + 1, high);
// Combine them both
p = mergeDC(p, low, middle, high);
}
return p;
}
private static ClosestPair[] mergeDC(ClosestPair[] p, int low, int middle, int high) {
ClosestPair[] helper = new ClosestPair[p.length];
// Copy both parts into the helper array
for (int i = low; i <= high; i++) {
helper[i] = p[i];
}
int i = low;
int j = middle + 1;
int k = low;
// Copy the smallest values from either the left or the right side back
// to the original array
while (i <= middle && j <= high) {
if (helper[i].x <= helper[j].x) {
p[k] = helper[i];
i++;
} else {
p[k] = helper[j];
j++;
}
k++;
}
// Copy the rest of the left side of the array into the target array
while (i <= middle) {
p[k] = helper[i];
k++;
i++;
}
return p;
}
}
An example of output is:
Enter the number of two dimensional arrays: 50
Min Distance = 19.014027210555614
(x1,y1) = 76.99595098629398, 600.1657767818473
(x2,y2) = 87.04091889578226, 616.3098732403395
Time: 3852815
Min Distance = 29.457199999686082
Time: 414081
The first min distance is the bruteforce result. The second is the divide and conquer result
I wrote a Gauss-Seidel method to calculate the unknown x values of a matrix A. Another methods online seemed to check first if the determinant contains non-zeroes, but other algorithms, including my prof's notes, don't have the verification check.
So I just followed the algorithm that my professor gave in class for now, and I think that the first xNew is correct, because I verified it on my calculator, but my other x values are not updating, can anyone see why?
public static void gaussSeidel(double[][] A, double[] b){
int count = 0;
boolean stop = false;
do{
double[] xNew = new double[b.length]; // x2 = 0, x3 = 0,
double[] xOld = new double[b.length];
for(int i = 0; i < A.length; i++){
double sum = 0.0;
double sum1 = 0.0;
for(int j = 0; j < A.length; j++){
if( j != i)
sum += (A[i][j]*xOld[j]);
sum1 += (A[i][j]*xNew[j]);
}
xNew[i] = (b[i] - sum - sum1)*(1/A[i][i]);
System.out.println("X_" + (i+1) + ": " + xNew[i]);
System.out.println("Error is: " + Math.abs((xNew[i] - xOld[i])));
System.out.println("");
count++;
if(Math.abs(xNew[i] - xOld[i]) > EPSILON){
xNew[i] = xOld[i];
}
else{
stop = true;}
}
}while( !stop && count <= MAX_ITERATIONS);
}
My matrix:
double[][] a = {{12,-2,1,0,0,0,0,0,0,0,0},
{-2,12,2,1,0,0,0,0,0,0,0}, {1,-2,12,-2,1,0,0,0,0,0,0}, {0,1,-2,12,-2,1,0,0,0,0,0},
{0,0,1,-2,12,2,1,0,0,0,0}, {0,0,0,1,-2,12,-2,1,0,0,0},
{0,0,0,0,1,-2,12,-2,1,0,0},{0,0,0,0,0,1,-2,12,-2,1,0},
{0,0,0,0,0,0,1,-2,12,-2,0},{0,0,0,0,0,0,0,1,-2,12,0}};
My b values:
double[] b = {13.97, 5.93, -6.02, 8.32, -23.75, 28.45, -8.9, -10.5, 10.34, -38.74};
Every time you loop, you are creating the following arrays again and again:
double[] xNew = new double[b.length]; // x2 = 0, x3 = 0,
double[] xOld = new double[b.length];
Surely, you are loosing the values that you have computed in the previous loop. I would think that you would only need to create these once, so outside of your loop as follows:
public static void gaussSeidel(double[][] A, double[] b){
int count = 0;
boolean stop = false;
double[] xNew = new double[b.length]; // x2 = 0, x3 = 0,
double[] xOld = new double[b.length];
do{
for(int i = 0; i < A.length; i++){
double sum = 0.0;
double sum1 = 0.0;
for(int j = 0; j < A.length; j++){
if( j != i)
sum += (A[i][j]*xOld[j]);
sum1 += (A[i][j]*xNew[j]);
}
xNew[i] = (b[i] - sum - sum1)*(1/A[i][i]);
System.out.println("X_" + (i+1) + ": " + xNew[i]);
System.out.println("Error is: " + Math.abs((xNew[i] - xOld[i])));
System.out.println("");
count++;
if(Math.abs(xNew[i] - xOld[i]) > EPSILON){
xNew[i] = xOld[i];
}
else{
stop = true;}
}
}while( !stop && count <= MAX_ITERATIONS);
}
Ok this code was in another question but I couldn't work out how to add my updated code. I got this code working and putting out the right answers but it isn't stopping according to my while loop conditions. i'm not sure what I've done wrong there? The answer clearly converges and all values are right, just while loop is ignored.
/* Newton Raphson Method*/
import java.util.Scanner;
import static java.lang.Math.*;
public class NewtRaphEx {
// Creating Function f = x - cos(3.5x)
double f = 0.0;
double df = 0.0;
public static double function(double x) {
return (x - cos(3.5 * x));
}
public static double dfunction (double x) {
return (1 + 3.5*sin(3.5 * x));
}
public static void main (String[] args) {
//Initialising all variables
double xn = 0.06;
double xnew = 0.0;
double e_allow = 0.001;
double fn = 0.0;
double eps = 0.0;
double dfn = 0.0;
double dx = 0.0;
int n = 0;
int nMax = 10000;
do {
for (n = 0; n <= nMax; n++) {
fn = function(xn);
dfn = dfunction(xn);
dx = -(fn / dfn);
xnew = xn + dx;
xn = xnew;
eps = abs(dx / xn);
n = n + 1;
}
} while (eps <= e_allow || n < nMax);
System.out.print("N" + "\t" + "X" + "\t" + "F(x)" + "\t" + "dF(x)" + "\t");
System.out.println("delX" + "\t" + "X_new" + "\t" + "Epsilon");
System.out.format("%d\t" + "%.3f\t" + "%.3f\t" + "%.3f\t" + "%.3f\t" + "%.3f\t" + "%.3f", n, xn, fn, dfn, dx, xnew, eps);
}
}
The expression
eps <= e_allow || n < nMax
evaluates to true when you reach it, therefore the for loop will run again, setting n = 0 and thus the infinite loop.
Specifically, you would have:
eps = 0.0;
e_allow = 0.001;
n = 10002; // due to the increment inside the loop
nmax = 10000;
as as such:
eps <= e_allow || n < nMax
0.0 <= 0.001 (true) OR 10002 <= 10000 (false) -> true
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!