I'm having some trouble when trying to plot some coordinates from a CSV file. I'm taking latitude and longitude, then I convert them using Web Mercator (https://en.wikipedia.org/wiki/Web_Mercator#Formulas), after which I'm taking the min and max values and by using the map() function in order to map them to values between 0 and 500. However, I get the following error:
total number of rows: 6606
maxLat = 198987.05; minLat = 198986.94 ; maxLong = 110837.664; minLong = 110836.695
lat & long before mapping: 198986.27 ; 110840.68
lat & long after map(): -6142.857 ; 4112.9033
lat & long after norm(): -6.142857 ; 4.112903
map(NaN, 198986.94, 198987.05, 0, 500) called, which returns NaN (not a number)
map(NaN, 110836.695, 110837.664, 0, 500) called, which returns NaN (not a number)
I'd appreciate any suggestions how to fix the error or improvements on the code.
Thank you in advance.
The code itself:
import java.util.Collections;
Table csvFile;
ArrayList<Float>times = new ArrayList<Float>();
ArrayList<Float>latitude = new ArrayList<Float>();
ArrayList<Float>longitude = new ArrayList<Float>();
ArrayList<Float>lap = new ArrayList<Float>();
ArrayList<Float>latitudeCal = new ArrayList<Float>();
ArrayList<Float>longitudeCal = new ArrayList<Float>();
float maxLat = 0;
float maxLong = 0;
float minLat = 0;
float minLong = 0;
void setup() {
size(600, 800);
csvFile = loadTable("RRData.csv", "header");
int totalRows = csvFile.getRowCount();
println("total number of rows: " + totalRows);
for (TableRow row : csvFile.rows()) {
times.add(row.getFloat("Time"));
latitude.add(normLat(row.getFloat("Latitude")));
longitude.add(normLon(row.getFloat("Longitude")));
}
maxLat = latitude.get(0);
maxLong = longitude.get(0);
maxLat = latitude.get(0);
maxLong = longitude.get(0);
// Finding Max Values
for (int i = 1; i < latitude.size() - 1; i++) {
maxLat = max(maxLat, latitude.get(i));
maxLong = max(maxLong, longitude.get(i));
minLat = min(minLat, latitude.get(i));
minLong = min(minLong, longitude.get(i));
}
println("maxLat = " + maxLat + "; minLat = " + minLat + " ; maxLong = " + maxLong + "; minLong = " + minLong);
println("lat & long before mapping: " + latitude.get(0) + " ; " + longitude.get(0));
println("lat & long after map(): " + map(latitude.get(0), minLat, maxLat, 0, 1000) + " ; " + map(longitude.get(0), minLong, maxLong, 0, 1000)); // map() doesn't worked as intended
//Try Normalising
println("lat & long after norm(): " + norm(latitude.get(0), minLat, maxLat) + " ; " + norm(longitude.get(0), minLong, maxLong));
// Mapping
for (int i = 0; i < latitude.size() - 1; i++) {
float num = latitude.get(i);
float num2 = longitude.get(i);
//println(num);
//println(num2);
latitudeCal.add(map(num, minLat, maxLat, 0, 500));
longitudeCal.add(map(num2, minLong, maxLong, 0, 500));
}
}
float normLon(float lon) {
lon = radians(lon);
float a = (256 / PI) * pow(2, 10);
float b = lon + PI;
return a * b;
}
float normLat(float lat) {
lat = radians(lat);
float a = (256 / PI) * pow(2, 10);
float b = tan(PI / 4 + lat / 2);
float c = PI - log(b);
return a * c;
}
void draw() {
background(51);
for (int i = 0; i < times.size() - 1; i++) {
noFill();
ellipse(latitude.get(i), longitude.get(i), 20, 20);
}
}
Related
can anyone tell me what i'm doing wrong? i'm trying to get the circles to bounce off each other but they don't seem to be working.i keep making changes to fix the issue but that only makes more issues, whilst the main issue isn't resolved. have i used the wrong math's algorithm to check for collisions? or is it right and i have just made an error i cant seem to find? any help would be appreciated.
public float[][] CreateDots() {
if (first == true) {
for (int i = 0; i < dotNumber; i++) {
do{
dotX = r.nextInt(300);
dotY = r.nextInt(300);
dotWidth = r.nextFloat() * 50;
dotRadius = dotWidth / 2;
dotMass = r.nextFloat() / 10;
dotCentreX = dotX + dotRadius;
dotCentreY = dotY + dotRadius;
dotVelocityX = r.nextFloat();
dotVelocityY = r.nextFloat();
dots[i][0] = dotX;
dots[i][1] = dotY;
dots[i][2] = dotVelocityX;
dots[i][3] = dotVelocityY;
dots[i][4] = dotRadius;
dots[i][5] = dotCentreX;
dots[i][6] = dotCentreY;
dots[i][7] = dotMass;
dots[i][8] = dotWidth;
}while(collision == true);
}
first = false;
} else {
for (int i = 0; i < dotNumber; i++) {
dots[i][0] = dots[i][0] + dots[i][2];
dots[i][1] = dots[i][1] + dots[i][3];
if (dots[i][0] + dots[i][8] >= wallX) {
dots[i][2] = -dots[i][2];
}
if (dots[i][1] + dots[i][8] >= wallY) {
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];
}
}
}
repaint();
return dots;
}
public void bounce() {
collisionDot = false;
for (int i = 0; i < dotNumber; i++) {
for (int a = i + 1; a < dotNumber; a++) {
// difference between the x and y velocity of two dots
float xVelDiff = dots[i][2] - dots[a][2];
float yVelDiff = dots[i][3] - dots[a][3];
//difference between the centre x and y of two dots
float xDist = dots[i][5] - dots[a][5];
float yDist = dots[i][6] - dots[a][6];
System.out.println(xVelDiff + " * " + xDist + " + " + yVelDiff + " * " + yDist + " = "+ (xVelDiff * xDist + yVelDiff * yDist));
//not quite sure yet
if (xVelDiff * xDist + yVelDiff * yDist <= 0) {
angleCollision = (float) -Math.atan2(dots[a][0] - dots[i][0], dots[a][1] - dots[i][1]);
float mass = (dots[i][7] + dots[a][7]);
float mass2 = (dots[i][7] - dots[a][7]);
// x and y velocity and angle of collision for the two dots
float[] u1 = rotate(dots[i][2], dots[i][3], (float) angleCollision);
float[] u2 = rotate(dots[a][2], dots[a][3], (float) angleCollision);
//Velocity of dot 1
float[] v1 = new float[2];
v1[0] = u1[0] * mass2 / mass + u2[0] * 2 * dots[a][7] / (mass);
v1[1] = u1[1];
// velocity of dot 2
float[] v2 = new float[2];
v2[0] = u2[0] * mass2 / mass + u1[0] * 2 * dots[a][7] / (mass);
v2[1] = u2[1];
// final velocity of two colliding dots is:
float[] vFinal1 = rotate(v1[0], v1[1], (float) -angleCollision);;
float[] vFinal2 = rotate(v2[0], v2[1], (float) -angleCollision);;
if (a != i && !(dots[a][0] == 0 && dots[a][1] == 0)) {
// if the x and y distance between the two dots centres is less than their radii combined then the dots have collided
boolean thisCollision = Math.pow(xDist, 2) + Math.pow(yDist, 2) <= Math.pow((dots[a][4] + dots[i][4]), 2);
//if the dots collided, create new final velocity's from the angle of collision and the x and y velocitys at collision
if (thisCollision) {
collisionDot = true;
dots[i][2] = vFinal1[0];
dots[i][3] = vFinal1[1];
dots[a][2] = vFinal2[0];
dots[a][3] = vFinal2[1];
return;
}
}
}
}
}
}
public float[] rotate(float velocityX, float velocityY, float angle) {
float x1 = (float) (velocityX * Math.cos(angle) - velocityY * Math.sin(angle));
float y1 = (float) (velocityX * Math.sin(angle) - velocityY * Math.cos(angle));
float vel[] = new float[2];
vel[0] = x1;
vel[1] = y1;
return vel;
}
I'm working on a program that calculates pi based on randomly generated float numbers that represent x,y co-ordinates on a graph. Each x, y co-ordinate is raised by the power of 2 and stored in two separate arrays. The co-ordinates are distributed uniformly on a graph of interval of 0,1.
The program adds the x, y co-ordinates and if they are less than 1 then the points are located within a circle of diameter 1, illustrated in the diagram below.
I then used the formula,
π ≈ 4 w / n
to work out pi. Where, w is the count of the points within the circle and n is the number of x or y co-ordinates within the arrays.
When I set n up to 10,000,000 (the size of the array) it generates the most accurate calculation of pi of 15-16 decimal places. However after dedicating 4GB of RAM to the run config and setting n to 100,000,000 pi ends up being 0.6710...
I was wondering why this may be happening? Sorry if this is a stupid question.. code is below.
import java.text.DecimalFormat;
import java.util.Random;
public class random_pi {
public random_pi() {
float x2_store[] = new float[10000000];
float y2_store[] = new float[10000000];
float w = 0;
Random rand = new Random();
DecimalFormat df2 = new DecimalFormat("#,###,###");
for (int i = 0; i < x2_store.length; i++) {
float x2 = (float) Math.pow(rand.nextFloat(), 2);
x2_store[i] = x2;
float y2 = (float) Math.pow(rand.nextFloat(), 2);
y2_store[i] = y2;
}
for (int i = 0; i < x2_store.length; i++) {
if (x2_store[i] + y2_store[i] < 1) {
w++;
}
}
System.out.println("w: "+w);
float numerator = (4*w);
System.out.printf("4*w: " + (numerator));
System.out.println("\nn: " + df2.format(x2_store.length));
float pi = numerator / x2_store.length;
String fmt = String.format("%.20f", pi);
System.out.println(fmt);
String pi_string = Double.toString(Math.abs(pi));
int intP = pi_string.indexOf('.');
int decP = pi_string.length() - intP - 1;
System.out.println("decimal places: " + decP);
}
public static void main(String[] args) {
new random_pi();
}
}
The problem is here:
float w = 0;
float numerator = (4*w);
float precision is not enough, change it to int or double:
Like this working sample code:
import java.text.DecimalFormat;
import java.util.Random;
public class random_pi {
public random_pi() {
float x2_store[] = new float[100000000];
float y2_store[] = new float[100000000];
int w = 0;
Random rand = new Random();
DecimalFormat df2 = new DecimalFormat("#,###,###");
for (int i = 0; i < x2_store.length; i++) {
float x2 = (float) Math.pow(rand.nextFloat(), 2);
x2_store[i] = x2;
float y2 = (float) Math.pow(rand.nextFloat(), 2);
y2_store[i] = y2;
}
for (int i = 0; i < x2_store.length; i++) {
if (x2_store[i] + y2_store[i] < 1) {
w++;
}
}
System.out.println("w: "+w);
int numerator = (4*w);
System.out.printf("4*w: " + (numerator));
System.out.println("\nn: " + df2.format(x2_store.length));
float pi = ((float)numerator) / x2_store.length;
String fmt = String.format("%.20f", pi);
System.out.println(fmt);
String pi_string = Double.toString(Math.abs(pi));
int intP = pi_string.indexOf('.');
int decP = pi_string.length() - intP - 1;
System.out.println("decimal places: " + decP);
}
public static void main(String[] args) {
new random_pi();
}
}
output:
w: 78544041
4*w: 314176164
n: 100,000,000
3.14176154136657700000
decimal places: 15
And you don't need to store the results, like this working sample code:
import java.text.DecimalFormat;
import java.util.Random;
public class pi {
public pi() {
double n=100000000;
double w = 0;
Random rand = new Random();
DecimalFormat df2 = new DecimalFormat("#,###,###");
for (int i = 0; i < n; i++) {
double x = rand.nextFloat();
double y = rand.nextFloat();
if ((x*x + y*y) < 1.0) w++;
}
System.out.println("w: "+w);//w: 7852372.0
double numerator = (4*w);
System.out.printf("4*w: " + (numerator));//4*w: 3.1409488E7
System.out.println("\nn: " + df2.format(n));//n: 10,000,000
double pi = numerator / n;
final String fmt = String.format("%.20f", pi);
System.out.println(fmt);//3.14094877243042000000
String pi_string = Double.toString(Math.abs(pi));
int intP = pi_string.indexOf('.');
int decP = pi_string.length() - intP - 1;
System.out.println("decimal places: " + decP);//decimal places: 14
}
public static void main(String[] args) {
new random_pi();
}
}
output:
w: 78539606
4*w: 314158424
n: 100,000,000
3.14158439636230470000
decimal places: 16
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
Alongside with my main class, i want to output the table with the points of the airfoil to the command line, but right now some of the system print functions aren't working. here is my calc class:
package airfoil;
import java.text.DecimalFormat;
import java.text.NumberFormat;
public class airfoil
{
private static final int numOfCoord = 250;
double dx = 1.0 / numOfCoord;
private double m; // maximum camber in % of chord
private double p; // chordwise position of max ord., 10th of chord
private double t; // thickness in % of the cord
private String nacaNum; // NACA number - 4 digits
private double[][] coordinates; // Coordinates of the upper half
// or lower half of the airfoil
private double[][] meanLine; // mean line coordinates
public airfoil(String number) {
nacaNum = number;
m = Double.parseDouble(nacaNum.substring(0,1)) / 100.0;
p = Double.parseDouble(nacaNum.substring(1,2)) / 10.0;
t = Double.parseDouble(nacaNum.substring(2,4)) / 100.0;
meanLine = new double[2][numOfCoord]; // x values row 0, y values row 1
// x upper = row 0,
// y upper = row 1,
// x lower = row 2,
// y lower = row 3
coordinates = new double [4][numOfCoord];
System.out.println("NACA: " + nacaNum);
System.out.println("Number of coordinates: " + numOfCoord);
calcMeanLine();
calcAirfoil();
}
/*
* Calculates the values for the mean line forward of the maximum
* ordinate and aft of the maximum ordinate.
*/
private void calcMeanLine() {
double x = dx;
int j = 0;
// fwd of max ordinate
while (x <= p) {
meanLine[0][j] = x;
meanLine[1][j] = (m / (p * p))*(2*p*x - (x*x));
x += dx;
j++;
}
// aft of max ordinate
while (x <= 1.0 + dx) {
meanLine[0][j] = x;
meanLine[1][j] = (m / ((1 - p) * (1 - p))) *
((1 - 2*p) + 2*p*x - x * x);
x += dx;
j++;
}
} // end calcMeanLine
/*
* Calculate the upper and lower coordinates of the airfoil surface.
*/
private void calcAirfoil() {
double theta; // arctan(dy_dx)
double dy; // derivative of mean line equation
double yt, ml; // thickness and meanline values, respectively
double x = dx; // x-value w.r.t. chord
int j = 0; // counter for array
// calculate upper/lower surface coordinates fwd of max ordinate
while (x <= p) {
dy = (m / (p*p)) * (2*p - 2*x);
theta = Math.atan(dy);
yt = thicknessEQ(x);
ml = meanLine[1][j];
// upper surface coordinates;
coordinates[0][j] = x - yt * Math.sin(theta);
coordinates[1][j] = ml + yt * Math.cos(theta);
// lower surface coordinates
coordinates[2][j] = x + yt*Math.sin(theta);
coordinates[3][j] = ml - yt * Math.cos(theta);
x += dx;
j++;
}
// calculate the coordinates aft of max ordinate
while (x <= 1.0 + dx) {
dy = (m / ((1 - p) * (1 - p))) * ((2 * p) - (2 * x));
theta = Math.atan(dy);
yt = thicknessEQ(x);
ml = meanLine[1][j];
// upper surface coordinates;
coordinates[0][j] = x - yt * Math.sin(theta);
coordinates[1][j] = ml + yt * Math.cos(theta);
// lower surface coordinates
coordinates[2][j] = x + yt * Math.sin(theta);
coordinates[3][j] = ml - yt * Math.cos(theta);
x += dx;
j++;
}
System.out.println("j = " + j);
} // end calcAirfoil
/*
* Thickness equation
*/
private double thicknessEQ(double x) {
return ((t / 0.2) * (0.2969 * Math.sqrt(x) - (0.126 * x) -
(0.3526 * x * x) + (0.28430 * x * x * x) -
(0.1015 * x * x * x * x)));
}
public String toString() {
String str = "";
NumberFormat df = new DecimalFormat("0.0000");
System.out.println("Xu\tYu\tXl\tYl");
for (int j = 0; j < numOfCoord; j++) {
str += df.format(coordinates[0][j]) + "\t" +
df.format(coordinates[1][j]) + "\t" +
df.format(coordinates[2][j]) + "\t" +
df.format(coordinates[3][j]) + "\n";
}
return str;
}
/*
* Return the coordinates array
*/
public double[][] getCoordinates() { return coordinates; }
public int getSize() { return numOfCoord; }
} // end Airfoil class
This part of the class is supposed to print a table, but it isnt doing anything:
public String toString() {
String str = "";
NumberFormat df = new DecimalFormat("0.0000");
System.out.println("Xu\tYu\tXl\tYl");
for (int j = 0; j < numOfCoord; j++) {
str += df.format(coordinates[0][j]) + "\t" +
df.format(coordinates[1][j]) + "\t" +
df.format(coordinates[2][j]) + "\t" +
df.format(coordinates[3][j]) + "\n";
}
return str;
}
So what can I do to make these things print correctly?
Your System.out.println("Xu\tYu\tXl\tYl"); code prints the following: Xu Yu Xl Yl because you did not add any variables to it. You could change it to:
public String toString() {
String str = "";
NumberFormat df = new DecimalFormat("0.0000");
for (int j = 0; j < numOfCoord; j++) {
str += df.format(coordinates[0][j]) + "\t" +
df.format(coordinates[1][j]) + "\t" +
df.format(coordinates[2][j]) + "\t" +
df.format(coordinates[3][j]) + "\n";
}
System.out.println(str);
return str;
}
Anyway, don't print in toString() function. toString() shouldn't print anything, it should just return the String so that you can print it or do whatever you want with it.
Airfoil airfoil = new Airfoil(); // Yes, first letter uppercase recommended
// do stuff
System.out.println(airfoil.toString());
EDIT: It works for me (I think). I used the input 1000 (by the way, you should use try/catch for numbers with 3 characters or less or it will crash), and this is the output I got (only the beginning and ending), as it's long.
NACA: 1000
Number of coordinates: 250
j = 250
0.0040 0.0100 0.0040 0.0100
0.0080 0.0100 0.0080 0.0100
0.0120 0.0100 0.0120 0.0100
[...]
0.9920 0.0002 0.9920 0.0002
0.9960 0.0001 0.9960 0.0001
1.0000 -0.0000 1.0000 -0.0000
This is the toString() code used to make it work:
public String toString() {
String str = "";
NumberFormat df = new DecimalFormat("0.0000");
// System.out.println("Xu\tYu\tXl\tYl");
for (int j = 0; j < numOfCoord; j++) {
str += df.format(coordinates[0][j]) + "\t" +
df.format(coordinates[1][j]) + "\t" +
df.format(coordinates[2][j]) + "\t" +
df.format(coordinates[3][j]) + "\n";
}
return str;
}
And the main I used:
public static void main (String args[]){
Airfoil air = new Airfoil("1000");
System.out.println(air.toString());
}
I've been trying to implement a perlin noise generator in java, based on this article. Homever, my generator produces noise that is not continuous but instead "blocky", forming visible lines between every even numbered -coordinate. Below is my current code:
private static final Point[] grads = {
new Point(1, 0), new Point(-1, 0), new Point(0, 1), new Point(0, -1),
new Point(1, 1), new Point(1, -1), new Point(-1, 1), new Point(-1, -1)
};
private int permutations[] = new int[512];
private int frequency;
private int seed;
private double[][] heightMap;
private double amplitude;
public PerlinNoise(int frequency, int seed, double[][] heightMap, double amplitude) {
this.frequency = frequency;
this.seed = seed; //Seed for randomizing the permutation table
this.heightMap = heightMap; //The Heightmap where the finalt result will be stored
this.amplitude = amplitude;
}
private void seedPermutationTables() {
LinkedList<PermutationValue> l = new LinkedList<PermutationValue>();
Random rand = new Random(this.seed);
for (int i = 0; i < 256; i++) {
l.add(new PermutationValue(i, rand));
}
Collections.sort(l);
for (int i = 0; i < 512; i++) {
permutations[i] = l.get(i & 255).getValue();
}
}
public void generateNoise() {
this.seedPermutationTables();
int sWidth = this.heightMap.length / frequency;
int sHeight = this.heightMap[0].length / frequency;
for (int i = 0; i < this.heightMap.length; i++) {
for (int j = 0; j < this.heightMap[i].length; j++) {
double x = (double)i / sWidth;
double y = (double)j / sHeight;
this.heightMap[i][j] = this.noise(x, y);
}
}
}
private double noise(double x, double y) {
int xi = (int)x & 255;
int yi = (int)y & 255;
double xf = x - (int)x;
double yf = y - (int)y;
double u = this.fade(xf);
double v = this.fade(yf);
int aa = permutations[permutations[xi] + yi];
int ab = permutations[permutations[xi] + yi + 1];
int ba = permutations[permutations[xi + 1] + yi];
int bb = permutations[permutations[xi + 1] + yi + 1];
double x1 = this.lerp(this.grad(aa, xf, yf), this.grad(ab, xf - 1, yf), u);
double x2 = this.lerp(this.grad(ba, xf, yf - 1), this.grad(bb, xf - 1, yf - 1), u);
double noise = this.lerp(x1, x2, v);
return (1D + noise) / 2 * this.amplitude; //The noise returns values between -1 and 1
//So we change the range to 0-amplitude
}
private double grad(int hash, double x, double y) {
hash = hash & 7;
Point p = grads[hash];
return p.x * x + p.y * y;
}
private double lerp(double a, double b, double x) {
return a + x * (b - a);
}
private double fade(double x) {
return x * x * x * (x * (x * 6 - 15) + 10);
}
private class PermutationValue implements Comparable<PermutationValue> {
private int value;
private double sortValue;
public PermutationValue(int value, Random rand) {
this.setValue(value);
this.sortValue = rand.nextDouble();
}
#Override
public int compareTo(PermutationValue pv) {
if (pv.sortValue > this.sortValue) {
return -1;
}
return 1;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
}
The heightmap array simply stores the height value for every pixel. Any suggestions or ideas what might be causing these formations?
hash tables can be replaced with 1-2 multiplications as in rndng fct:
blocky can come from lack of cubic interpolation or digital noise from the hash table.
in your case it sounds like it's not lerping between two values of the hash table. lerp just takes any 2 values and smooths between them. so if that's not running ok, it's blocky.
function rndng ( n: float ): float //total noise pseudo
{//random proportion -1, 1
var e = ( n *321.9)%1;
return (e*e*111.0)%2-1;
}
function lerps(o:float, v:float, alpha:float):float
{
o += ( v - o ) * alpha;
return o;
}
function lnz ( vtx: Vector3 ): float//3d noise
{
vtx= Vector3 ( Mathf.Abs(vtx.x) , Mathf.Abs(vtx.y) , Mathf.Abs(vtx.z) ) ;
var I = Vector3 (Mathf.Floor(vtx.x),Mathf.Floor(vtx.y),Mathf.Floor(vtx.z));
var D = Vector3(vtx.x%1,vtx.y%1,vtx.z%1);
D = Vector3(D.x*D.x*(3.0-2.0*D.x),D.y*D.y*(3.0-2.0*D.y),D.z*D.z*(3.0-2.0*D.z));
var W = I.x + I.y*71.0 + 125.0*I.z;
return lerps(
lerps( lerps(rndng(W+0.0),rndng(W+1.0),D.x) , lerps(rndng(W+71.0),rndng(W+72.0),D.x) , D.y)
,
lerps( lerps(rndng(W+125.0),rndng(W+126.0),D.x) , lerps(rndng(W+153.0),rndng(W+154.0),D.x) , D.y)
,
D.z
);
}
function lnzo ( vtx: Vector3 ): float
{
var total = 0.0;
for (var i:int = 1; i < 5; i ++)
{
total+= lnz2(Vector3 (vtx.x*(i*i),0.0,vtx.z*(i*i)))/(i*i);
}
return total*5;
}
function lnzh ( vtx: Vector3 ): float//3 axis 3d noise
{
vtx= Vector3 ( Mathf.Abs(vtx.z) , Mathf.Abs(vtx.z*.5-vtx.x*.866) , Mathf.Abs(vtx.z*.5+vtx.x*.866) ) ;
var I = Vector3 (Mathf.Floor(vtx.x),Mathf.Floor(vtx.y),Mathf.Floor(vtx.z));
var D = Vector3(vtx.x%1,vtx.y%1,vtx.z%1);
//D = Vector3(D.x*D.x*(3.0-2.0*D.x),D.y*D.y*(3.0-2.0*D.y),D.z*D.z*(3.0-2.0*D.z));
var W = I.x + I.y*71.0 + 125.0*I.z;
return lerps(
lerps( lerps(rndng(W+0.0),rndng(W+1.0),D.x) , lerps(rndng(W+71.0),rndng(W+72.0),D.x) , D.y)
,
lerps( lerps(rndng(W+125.0),rndng(W+126.0),D.x) , lerps(rndng(W+153.0),rndng(W+154.0),D.x) , D.y)
,
D.z
);
}
function lnz2 ( vtx: Vector3 ): float//2d noise
{
vtx= Vector3 ( Mathf.Abs(vtx.x) , Mathf.Abs(vtx.y) , Mathf.Abs(vtx.z) ) ;
var I = Vector3 (Mathf.Floor(vtx.x),Mathf.Floor(vtx.y),Mathf.Floor(vtx.z));
var D = Vector3(vtx.x%1,vtx.y%1,vtx.z%1);
D = Vector3(D.x*D.x*(3.0-2.0*D.x),D.y*D.y*(3.0-2.0*D.y),D.z*D.z*(3.0-2.0*D.z));
var W = I.x + I.y*71.0 + 125.0*I.z;
return lerps(
lerps( lerps(rndng(W+0.0),rndng(W+1.0),D.x) , lerps(rndng(W+71.0),rndng(W+72.0),D.x) , D.z)
,
lerps( rndng(W+125.0), rndng(W+126.0),D.x)
,
D.z
);
}
As the title suggests, I'm working on a homework assignment where we are limited to using multi-dimensional arrays in order to create a program that finds two points nearest to each other in a three dimensional space. So far my code looks like this (hybridized from examples in my textbook and my own code):
package exercise7_7;
public class Exercise7_7 {
public static void main(String[] args) {
java.util.Scanner input = new java.util.Scanner(System.in);
System.out.println("Enter the number of points:");
int numberOfPoints = input.nextInt();
double[][] points = new double[numberOfPoints][3];
System.out.println("Enter " + numberOfPoints + " points:");
for (int i = 0; i < points.length; i++) {
points[i][0] = input.nextDouble();
points[i][1] = input.nextDouble();
points[i][2] = input.nextDouble();
}
int p1 = 0, p2 = 1, p3 = 2;
double shortestDistance = distance(points[p1][0] , points[p1][1] , points[p1][2] ,
points[p2][0] , points[p2][1] , points[p2][2]);
for (int i = 0; i < points.length; i++) {
for (int j = i + 1; j < points.length; j++) {
double distance = distance(points[i][0] , points[j][0] , points[j][1] , points[j][2] , points[i][2] , points[j][2]);
if (shortestDistance > distance) {
p1 = i;
p2 = j;
shortestDistance = distance;
}
}
}
System.out.println("The closest two points are " + "(" + points[p1][0] + "," + points[p1][1] +
and (" + points[p2][0] + "," );
}
public static double distance(
double x1, double y1, double z1, double x2, double y2, double z2) {
return Math.sqrt(((x2 - x1) * (x2 - x1)) + ((y2 - y1) * (y2 - y1)) + ((z2 - z1) * (z2 - z1)));
}
}
What I mostly need help with is figuring out just how to get these points compared. I don't think the way I tackled this problem was the best way to do it.
Thanks for the help guys. I'm running on 2 hours of sleep for 2 days now so please excuse any stupid questions or sloppy code.
******
I think I've got it:
package exercise7_7;
public class Exercise7_7 {
public static void main(String[] args) {
java.util.Scanner input = new java.util.Scanner(System.in);
System.out.println("Enter the number of points:");
int numberOfPoints = input.nextInt();
double[][] points = new double[numberOfPoints][3];
System.out.println("Enter " + numberOfPoints + " points:");
for (int i = 0; i < points.length; i++) {
points[i][0] = input.nextDouble();
points[i][1] = input.nextDouble();
points[i][2] = input.nextDouble();
}
int p1 = 0, p2 = 1;
double shortestDistance = distance(points[p1][0] , points[p1][1] , points[p1][2] ,
points[p2][0] , points[p2][1] , points[p2][2]);
for (int i = 0; i < points.length; i++) {
for (int j = i + 1; j < points.length; j++) {
double distance = distance(points[i][0] , points[j][0] , points[j][1] , points[j][2] , points[i][2] , points[j][2]);
if (shortestDistance > distance) {
p1 = i;
p2 = j;
shortestDistance = distance;
}
}
}
System.out.println("The closest two points are " + "(" + points[p1][0] + "," + points[p1][1] + "," + points[p1][2] +
") and (" + points[p2][0] + "," + points[p2][1] + "," + points[p2][2] + ")");
}
public static double distance(
double x1, double y1, double z1, double x2, double y2, double z2) {
return Math.sqrt(((x2 - x1) * (x2 - x1)) + ((y2 - y1) * (y2 - y1)) + ((z2 - z1) * (z2 - z1)));
}
}
Input is taken in, processed, and then outputs the two closest points. Just as a reference, when:
(-1,0,3),(-1,-1,-1),(4,1,1),(2,0.5,9),(3.5,1.5,3),(-1.5,4,2),(5.5,4,-0.5) are inputted, the outcome
seems to be (-1,0,3) and (4,1,1). Could someone confirm that for me.
If this isn't the way to follow up on my own question, I apologize. First day on these slopes and I'm still
learning the ropes.
Use a class to represent your points. This way to you have a distanceTo method that calculates and returns distance. Also you can have a toString method that prints out the point for display to the user. Taking your code rearranging yields this class:
public class ThreeDPoint {
final double x;
final double y;
final double z;
public ThreeDPoint(final double x, final double y, final double z) {
this.x = x;
this.y = y;
this.z = z;
}
public double distanceto(final ThreeDPoint other) {
final double dx = other.x - x;
final double dy = other.y - y;
final double dz = other.z - z;
return Math.sqrt(dx * dx + dy * dy + dz * dz);
}
#Override
public String toString() {
return "{X=" + x + ",Y=" + y + ",Z=" + z + "}";
}
}
Now putting that together gives this, which is much more readable. I have removed the bit where you read points and used random numbers:
public static void main(String args[]) {
final ThreeDPoint[] points = new ThreeDPoint[5];
final Random random = new Random();
for (int i = 0; i < points.length; ++i) {
points[i] = new ThreeDPoint(random.nextInt(100), random.nextInt(100), random.nextInt(100));
}
//store min
double min = Double.POSITIVE_INFINITY;
int first = -1;
int last = -1;
for (int i = 0; i < points.length; ++i) {
for (int j = i + 1; j < points.length; ++j) {
final double d = points[i].distanceto(points[j]);
if (d < min) {
min = d;
first = i;
last = j;
}
}
}
System.out.println("The minimum distance is between point " + first + " and " + last + "(" + points[first] + " and " + points[last] + "). This distance is " + min + ".");
}
private static final class ThreeDPoint {
final double x;
final double y;
final double z;
public ThreeDPoint(final double x, final double y, final double z) {
this.x = x;
this.y = y;
this.z = z;
}
public double distanceto(final ThreeDPoint other) {
final double dx = other.x - x;
final double dy = other.y - y;
final double dz = other.z - z;
return Math.sqrt(dx * dx + dy * dy + dz * dz);
}
#Override
public String toString() {
return "{X=" + x + ",Y=" + y + ",Z=" + z + "}";
}
}