How would I Have Each TextView display something depending on another variable? - java

I am making an application for teachers that you put in the max number of points and it tells you the percent of each amount wrong. I then would like to use that percentage to make each of the textviews display the grade with the corresponding percentage. So the first column is the amount right out of the max, the second column is the percentage, and the third column is the letter grade. I then have eight rows, but would like to expand that in the future. I know that I would have to an if to say if the percent is between two numbers, settext to a letter grade, but would I have to do the same for every textview, or what other way would there be to do this?
This is the code for what I basically have to far:
MaxInt = Integer.parseInt(number);
minus1 = MaxInt - 1;
minus2 = MaxInt - 2;
minus3 = MaxInt - 3;
minus4 = MaxInt - 4;
minus5 = MaxInt - 5;
minus6 = MaxInt - 6;
minus7 = MaxInt - 7;
minus8 = MaxInt - 8;
float PD1 = (minus1 * 100.0f) / MaxInt;
float PD2 = (minus2 * 100.0f) / MaxInt;
float PD3 = (minus3 * 100.0f) / MaxInt;
float PD4 = (minus4 * 100.0f) / MaxInt;
float PD5 = (minus5 * 100.0f) / MaxInt;
float PD6 = (minus6 * 100.0f) / MaxInt;
float PD7 = (minus7 * 100.0f) / MaxInt;
float PD8 = (minus8 * 100.0f) / MaxInt;
int D1 = (int) PD1;
int D2 = (int) PD2;
int D3 = (int) PD3;
int D4 = (int) PD4;
int D5 = (int) PD5;
int D6 = (int) PD6;
int D7 = (int) PD7;
int D8 = (int) PD8;
P1 = String.valueOf(D1);
P2 = String.valueOf(D2);
P3 = String.valueOf(D3);
P4 = String.valueOf(D4);
P5 = String.valueOf(D5);
P6 = String.valueOf(D6);
P7 = String.valueOf(D7);
P8 = String.valueOf(D8);
TV1.setText(Integer.toString(minus1));
TV2.setText(Integer.toString(minus2));
TV3.setText(Integer.toString(minus3));
TV4.setText(Integer.toString(minus4));
TV5.setText(Integer.toString(minus5));
TV6.setText(Integer.toString(minus6));
TV7.setText(Integer.toString(minus7));
TV8.setText(Integer.toString(minus8));
TV9.setText(P1 + "%");
TV10.setText(P2 + "%");
TV11.setText(P3 + "%");
TV12.setText(P4 + "%");
TV13.setText(P5 + "%");
TV14.setText(P6 + "%");
TV15.setText(P7 + "%");
TV16.setText(P8 + "%");
I know that some of that isn't nessesary like converting the float to a integer, then string, but I will fix that when I am done. TV17 - TV24 will be the letter grades.

Related

How can I get rid of fraction? (The fraction somehow still remains.) [duplicate]

This question already has an answer here:
Java Division error
(1 answer)
Closed 7 months ago.
I'm trying to make a "Distance & Speed to Time"
But the fraction is obstructing me to calculate the minute part.
Like... the hour part still have a fractional value somewhere.
This is what I want.
In this example Distance is 130 km and speed is 40 km/hr
Answer I want is
3 Hour(s) 15 Minute(s) 0 Second(s)
But what I get is
3 Hour(s) **0 Minute(s) 0 Second(s)**
float Bx = 130;
float By = 40;
int x = (int) Bx;
int y = (int) By;
var KeepSecond = (x / y * 3600) ;
var HourX = KeepSecond/3600;
int Hour = (int) HourX;
var MinuteX = (KeepSecond-(Hour*3600))/60;
int Minute = (int) MinuteX;
var SecondX = (KeepSecond-(Hour*3600)-(Minute*60));
int Second = (int) SecondX;
String result = String.format(Hour+" Hour(s) "+Minute+" Minute(s) "+Second+" Second(s) ");
Answer.setText(result);
You're doing an int division on distance/speed : 130/40 gives 3 with int types
You need the double or float division of 130.0/40.0 which gives expected 3.25
var KeepSecond = (Bx / By * 3600);
Also use meaningfull variable name and follow Java convention which is lowerCamelCase for variable (UpperCamelCase for class name)
float distance = 130;
float speed = 40;
var keepSecond = (distance / speed * 3600);
int hourInt = (int) keepSecond / 3600;
int minuteInt = (int) (keepSecond - (hourInt * 3600)) / 60;
int secondInt = (int) (keepSecond - (hourInt * 3600) - (minuteInt * 60));
That intermediate casting to ints is the problem.
Along with removing int x = (int) Bx; int y = (int) By;, I would make that code a little clearer and [conventionally] correct as follows:
float distance = 130f;
float speed = 40f;
int secondsInMinute = 60;
int minutesInHour = 60;
int secondsInHour = minutesInHour * secondsInMinute;
int timeInSeconds = (int) (distance / speed * secondsInHour); // formula: t = d/s
int hours = timeInSeconds / secondsInHour;
int minutes = (timeInSeconds - (hours * secondsInHour)) / secondsInMinute;
int seconds = timeInSeconds - ((hours * secondsInHour) + (minutes * secondsInMinute));
String result = String.format("%d Hour(s) %d Minute(s) %d Second(s)", hours, minutes, seconds);
Answer.setText(result);

JzAzBz java implementation precision

I made a java implementation of the new perceptualy uniform color space JzAzBz. OSA publication is : https://www.osapublishing.org/oe/fulltext.cfm?uri=oe-25-13-15131&id=368272.
My java code is :
private double b = 1.15;
private double g = 0.66;
private double c1 = 3424 / Math.pow(2, 12);
private double c2 = 2413 / Math.pow(2, 7);
private double c3 = 2392 / Math.pow(2, 7);
private double n = 2610 / Math.pow(2, 14);
private double p = 1.7 * 2523 / Math.pow(2, 5);
private double d = -0.56;
private double d0 = 1.6295499532821566 * Math.pow(10, -11);
public void XYZToJab(double[] xyz, double[] jab) {
double[] XYZp = new double[3];
XYZp[0] = b * xyz[0] - ((b - 1) * xyz[2]);
XYZp[1] = g * xyz[1] - ((g - 1) * xyz[0]);
XYZp[2] = xyz[2];
double[] LMS = new double[3];
LMS[0] = 0.41478972 * XYZp[0] + 0.579999 * XYZp[1] + 0.0146480 * XYZp[2];
LMS[1] = -0.2015100 * XYZp[0] + 1.120649 * XYZp[1] + 0.0531008 * XYZp[2];
LMS[2] = -0.0166008 * XYZp[0] + 0.264800 * XYZp[1] + 0.6684799 * XYZp[2];
double[] LMSp = new double[3];
for (int i = 0; i < 3; i++) {
LMSp[i] = Math.pow((c1 + c2 * Math.pow((LMS[i] / 10000.0), n)) / (1 + c3 * Math.pow((LMS[i] / 10000.0), n)), p);
}
double[] Iab = new double[3];
Iab[0] = 0.5 * LMSp[0] + 0.5 * LMSp[1];
Iab[1] = 3.524000 * LMSp[0] - 4.066708 * LMSp[1] + 0.542708 * LMSp[2];
Iab[2] = 0.199076 * LMSp[0] + 1.096799 * LMSp[1] - 1.295875 * LMSp[2];
jab[0] = (((1 + d) * Iab[0]) / (1 + d * Iab[0])) - d0;
jab[1] = Iab[1];
jab[2] = Iab[2];
}
public void JabToXYZ(double[] jab, double[] xyz) {
double[] Iab = new double[3];
Iab[0] = (jab[0] + d0) / (1 + d - d * (jab[0] + d0));
Iab[1] = jab[1];
Iab[2] = jab[2];
double[] LMSp = new double[3];
LMSp[0] = 1.0 * Iab[0] + 0.13860504 * Iab[1] + 0.05804732 * Iab[2];
LMSp[1] = 1.0 * Iab[0] - 0.13860504 * Iab[1] - 0.05804732 * Iab[2];
LMSp[2] = 1.0 * Iab[0] - 0.09601924 * Iab[1] - 0.81189190 * Iab[2];
double[] LMS = new double[3];
for (int i = 0; i < 3; i++) {
LMS[i] = 10000 * Math.pow((c1 - Math.pow(LMSp[i], 1 / p)) / ((c3 * Math.pow(LMSp[i], 1 / p)) - c2), 1 / n);
}
double[] XYZp = new double[3];
XYZp[0] = 1.92422644 * LMS[0] - 1.00479231 * LMS[1] + 0.03765140 * LMS[2];
XYZp[1] = 0.35031676 * LMS[0] + 0.72648119 * LMS[1] - 0.06538442 * LMS[2];
XYZp[2] = -0.09098281 * LMS[0] - 0.31272829 * LMS[1] + 1.52276656 * LMS[2];
xyz[0] = (XYZp[0] + (b - 1) * XYZp[2]) / b;
xyz[1] = (XYZp[1] + (g - 1) * XYZp[0]) / g;
xyz[2] = XYZp[2];
}
When I test it running XYZToJab and then JabToXYZ I get a good precision for X and Z (delta order is E-9) but for Y I get a bad precision (delta order is 1-5%).
Is there anyone who can help me ?
The implementation is almost correct: The error lies in JabToXYZ where the prior to last line should be changed from
(XYZp[1] + (g - 1) * XYZp[0]) / g;
to
(XYZp[1] + (g - 1) * xyz[0]) / g;
However the fact that you are using rounded invert matrices to 6 decimal places in the JabToXYZ function will prevent you to get a clean inversion. You should try to compute the inverse at full double precision:
>>> import numpy as np
>>> np.set_printoptions(formatter={'float': '{:0.15f}'.format})
>>> import colour.models.jzazbz
>>> colour.models.jzazbz.JZAZBZ_IZAZBZ_TO_LMS_P_MATRIX
array([[1.000000000000000, 0.138605043271539, 0.058047316156119],
[1.000000000000000, -0.138605043271539, -0.058047316156119],
[1.000000000000000, -0.096019242026319, -0.811891896056039]])
>>> colour.models.jzazbz.JZAZBZ_LMS_TO_XYZ_MATRIX
array([[1.924226435787607, -1.004792312595365, 0.037651404030618],
[0.350316762094999, 0.726481193931655, -0.065384422948085],
[-0.090982810982848, -0.312728290523074, 1.522766561305260]])

Using java to solve an equation

I'm wanting to use java to help me quickly solve an equation to get x and y on a trilateration project i'm working on.
I get tot his point where the only numbers that i need to change is the ones i'be labelled (a) and (b)
120x - 15600 + 40y - 4400 = 1200(a)
y = -3x + 530
-180x + 20700 + 60y - 8100 = -2400(b)
y = 3x - 250
so i continue to solve and will get the answer
-3x + 530 = 3x - 250
780 = 6x
130 = x
y = 3(130) - 250
y = 140
x= 130, y = 140
I just need java to work out the equation and then be able to change the two values (a) and (b)
so im asking for a little bit of help as to whether or not i can do this? and could someone help me out please? im not a great programmer as its not my field
This is just general math:
Ax + By = C
Dx + Ey = F
// From first formula
x = (C - By) / A
// Applied to second formula
D * ((C - By) / A) + Ey = F
D * C / A - D * By / A + Ey = F
D * C / A + (E - D * B / A) * y = F
y = (F - D * C / A) / (E - D * B / A)
= (A * F - D * C) / (A * E - D * B)
In your case:
120x - 15600 + 40y - 4400 = 1200
-180x + 20700 + 60y - 8100 = -2400
A = 120 B = 40 C = 1200 + 15600 + 4400 = 21200
D = -180 E = 60 F = -2400 - 20700 + 8100 = -15000
y = (A * F - D * C) / (A * E - D * B)
= (120 * -15000 - -180 * 21200) / (120 * 60 - -180 * 40)
= 2016000 / 14400
= 140
x = (C - By) / A
= (21200 - 40 * 140) / 120
= 15600 / 120
= 130
Anyway, I digress, you want:
120x - 15600 + 40y - 4400 = a
-180x + 20700 + 60y - 8100 = b
// Normalized
(A= 120)x + (B=40)y = (C=a + 15600 + 4400)
(D=-180)x + (E=60)y = (F=b - 20700 + 8100)
C = a + 15600 + 4400 = a + 20000
F = b - 20700 + 8100 = b - 12600
y = (A * F - D * C) / (A * E - D * B)
= (120 * (b - 12600) - -180 * (a + 20000)) / (120 * 60 - -180 * 40)
= ((120 * b - 120 * 12600) - (-180 * a + -180 * 20000)) / 14400
= (120 * b - 1512000 + 180 * a + 3600000) / 14400
= 120 * b / 14400 + 180 * a / 14400 + (3600000 - 1512000) / 14400
= b / 120 + a / 80 + 145
x = (C - By) / A
= (a + 20000 - 40 * y) / 120
= a / 120 + 20000 / 120 - 40 * y / 120
= (a / 40 - y + 500) / 3
Verifying formulas with your numbers:
y = b / 120 + a / 80 + 145
= -2400 / 120 + 1200 / 80 + 145
= 140
x = (a / 40 - y + 500) / 3
= (1200 / 40 - 140 + 500) / 3
= 130
Or in Java code:
double a = 1200;
double b = -2400;
double y = b / 120 + a / 80 + 145;
double x = (a / 40 - y + 500) / 3;
System.out.println("x = " + x + ", y = " + y);
IDEONE
You can reorganize (a) and (b) so that the constants are all on the right side of the equation
120x + 40y = 21200(a)
-180x + 60y = -15000(b)
Let's name 120 the coefficient of x, 40 the coefficient of y and 21200 as the constant for equation a. The similar goes for equation b. And use these names as variables for the program.
One way to solve the two unknown variables in a binary quadric equation is to eliminate one unknown variables by manipulate the coefficient and constants in the two equations and combine them to get rid of one unknown variable, which you have shown in your question.
As shown by you, you eliminated x first and then solve for y. In the following program, I eliminated y first and then solve for x. But essentially, they are the same.
Note the program assumes that the coefficients and constants are integers.
public class Equation {
public static void main(String[] args) {
int coefficient_x_1, coefficient_y_1, constant_1, coefficient_x_2, coefficient_y_2, constant_2;
Scanner in = new Scanner(System.in);
// 1. get the inputs
coefficient_x_1 = in.nextInt();
coefficient_y_1 = in.nextInt();
constant_1 = in.nextInt();
coefficient_x_2 = in.nextInt();
coefficient_y_2 = in.nextInt();
constant_2 = in.nextInt();
// 2. try to eliminate x from the two equations to get the value of y
// 2.1 get the least common multiplier of the two coefficient of x in the two equations
int leastCommonMultiplier =
Math.abs(coefficient_x_1) * Math.abs(coefficient_x_2) / getMaxCommonFactor(Math.abs(coefficient_x_1), Math.abs(coefficient_x_2));
int cancellationFactor = -1;
if (coefficient_x_1 * coefficient_y_1 < 0) cancellationFactor = 1;
int multiplier_1 = leastCommonMultiplier / coefficient_x_1;
int multiplier_2 = cancellationFactor * leastCommonMultiplier / coefficient_x_2;
// 2.2 eleminate x and solve for y
int y = (constant_1 * multiplier_1 + constant_2 * multiplier_2) / (coefficient_y_1 * multiplier_1 + coefficient_y_2 * multiplier_2);
// 3. get the value of x based on the value of y
int x = (constant_1 - coefficient_y_1 * y) / coefficient_x_1;
System.out.println("x is : " + x);
System.out.println("y is : " + y);
in.close();
}
public static int getMaxCommonFactor(int a, int b) {
if (a < b) {
int temp = a;
a = b;
b = temp;
}
while (a % b != 0) {
int temp = a % b;
a = b;
b = temp;
}
return b;
}
}

Trying to calculate sunrise...ain't getting the right answer

This is my current code:
public class Sunpos {
final private double Pi = Math.PI;
final private double eul = 2.71828182845904523552 ;
final private double sonauf = 90;
final private double RAD = 0.017453292519943295769236907684886;
public double sunrisefinal (double Breitengrad, double Laengengrad, int tagzahl, int sommerzeit, int nacht) {
double lngHour = Laengengrad/15;
double t = tagzahl + ((6 - lngHour)/24);
// double ab = tagzahl + ((18 - lngHour)/24);
double M = (0.9856 * t) - 3.289;
double L = M + (1.916 * Math.sin(M)) + (0.020 * Math.sin(2 * M)) + 282.634;
if (L >= 359) { L -= 360; }
else if (L < 0) { L += 360; }
double RA = (Math.atan(0.91764 * Math.tan(Pi/180)*L));
if (RA >= 359) { RA -= 360; }
else if (RA < 0) { RA += 360; }
double Lquadrant = (Math.floor(L/90)*90);
double RAquadrant = (Math.floor(RA/90))*90;
RA = RA + (Lquadrant - RAquadrant);
RA = RA/15;
double sinDec = 0.39782 * Math.sin((Pi/180)*L);
double cosDec = (180/Pi)*(Math.cos(Math.asin(sinDec)));
double cosH = (Math.cos((Pi/180)*sonauf)-(sinDec*Math.sin((Pi/180)*Breitengrad)))/(cosDec * Math.cos((Pi/180)*Breitengrad));
double H = 360 - Math.acos(cosH);
H /= 15;
double T = H + RA -(0.06571 * t) - 6.622;
double UTC = T - lngHour;
if (UTC >= 23) { UTC -= 24; }
else if (UTC < 0) { UTC += 24; }
double locTime = UTC; // Fuer die schweiz!
System.out.println(locTime);
return(0);
}
The inputs are the following: ( 50, 10, 294, 1, 0). The last 2 can be ignored.
Now I am basing this on the following page:
http://williams.best.vwh.net/sunrise_sunset_algorithm.htm
The code should be complete according to the site, but I don't get anywhere near the supposed results. I should get around 7.5 for today but I'm getting a 9.358.
Now, that might be because something with radiants/degrees? I can't quite get my Mind into that, as I've been trying to insert those converters (Pi/180) into the code, without any usable result.
Can anyone tell me where to put them or point me in the right direction? I've spent waaaay too much time on this already, and now I'm so close.
I'll just post my implementation here in case people need it (ported from the same source as yours)
https://gist.github.com/zhong-j-yu/2232343b14a5b5ef5b9d
public class SunRiseSetAlgo
{
static double calcSunrise(int dayOfYear, double localOffset, double latitude, double longitude)
{
return calc(dayOfYear, localOffset, latitude, longitude, true);
}
static double calcSunset(int dayOfYear, double localOffset, double latitude, double longitude)
{
return calc(dayOfYear, localOffset, latitude, longitude, false);
}
// http://williams.best.vwh.net/sunrise_sunset_algorithm.htm
static double calc(int dayOfYear, double localOffset, double latitude, double longitude, boolean rise)
{
//1. first calculate the day of the year
// int N1 = floor(275 * month / 9.0);
// int N2 = floor((month + 9) / 12.0);
// int N3 = (1 + floor((year - 4 * floor(year / 4.0) + 2) / 3.0));
// int N = N1 - (N2 * N3) + day - 30;
int N = dayOfYear;
//2. convert the longitude to hour value and calculate an approximate time
double lngHour = longitude / 15;
double t = rise?
N + (( 6 - lngHour) / 24) :
N + ((18 - lngHour) / 24);
//3. calculate the Sun's mean anomaly
double M = (0.9856 * t) - 3.289;
//4. calculate the Sun's true longitude
double L = M + (1.916 * sin(M)) + (0.020 * sin(2 * M)) + 282.634;
L = mod(L, 360);
//5a. calculate the Sun's right ascension
double RA = atan(0.91764 * tan(L));
RA = mod(RA, 360);
//5b. right ascension value needs to be in the same quadrant as L
double Lquadrant = (floor( L/90)) * 90;
double RAquadrant = (floor(RA/90)) * 90;
RA = RA + (Lquadrant - RAquadrant);
//5c. right ascension value needs to be converted into hours
RA = RA / 15;
//6. calculate the Sun's declination
double sinDec = 0.39782 * sin(L);
double cosDec = cos(asin(sinDec));
//7a. calculate the Sun's local hour angle
double zenith = 90 + 50.0/60;
double cosH = (cos(zenith) - (sinDec * sin(latitude))) / (cosDec * cos(latitude));
if (cosH > 1)
throw new Error("the sun never rises on this location (on the specified date");
if (cosH < -1)
throw new Error("the sun never sets on this location (on the specified date");
//7b. finish calculating H and convert into hours
double H = rise?
360 - acos(cosH) :
acos(cosH);
H = H / 15;
//8. calculate local mean time of rising/setting
double T = H + RA - (0.06571 * t) - 6.622;
//9. adjust back to UTC
double UT = T - lngHour;
//10. convert UT value to local time zone of latitude/longitude
double localT = UT + localOffset;
localT = mod(localT, 24);
return localT;
}
static int floor(double d){ return (int)Math.floor(d); }
static double sin(double degree)
{
return Math.sin(degree*Math.PI/180);
}
static double cos(double degree)
{
return Math.cos(degree*Math.PI/180);
}
static double tan(double degree)
{
return Math.tan(degree*Math.PI/180);
}
static double atan(double x)
{
return Math.atan(x) *180/Math.PI;
}
static double asin(double x)
{
return Math.asin(x) *180/Math.PI;
}
static double acos(double x)
{
return Math.acos(x) *180/Math.PI;
}
static double mod(double x, double lim)
{
return x - lim * floor(x/lim);
}
}
Everone seems to link to this http://williams.best.vwh.net/sunrise_sunset_algorithm.htm
which doesn't exist anymore. Why not try something that gets updated once in a while like https://en.wikipedia.org/wiki/Sunrise_equation
Then if you like you could help edit it to make it better.

Perlin noise value range

I used perlin noise to generate a 2D height map. At first i tried some parameters manually and found a good combination of amplitude, persistence,... for my job.
Now that i'm developing the program, i added the feature for user to change the map parameters and make a new map for himself but now i see that for certain parameters (Mostly octaves and frequency) the values are not in the range i used to see. I thought that if a set Amplitude = 20, the values(heights) i get from it will be in e.g [0,20] or [-10,10] or [-20,20] ranges but now i see that Amplitude is not the only parameter that controls output range.
My question is: Is there an exact mathematical formula (a function of Amplitude, Octaves, Frequency and persistence) to compute the range or i should take a lot of samples (like 100,000) and check minimum and maximum values of them to guess the aproximate range?
Note: The following code is an implementation of perlin noise that one of stackoverflow guys worte it in C and i ported it to java.
PerlinNoiseParameters.java
public class PerlinNoiseParameters {
public double persistence;
public double frequency;
public double amplitude;
public int octaves;
public int randomseed;
public PerlinNoiseParameters(double persistence, double frequency, double amplitude, int octaves, int randomseed) {
this.ChangeParameters(persistence, frequency, amplitude, octaves, randomseed);
}
public void ChangeParameters(double persistence, double frequency, double amplitude, int octaves, int randomseed) {
this.persistence = persistence;
this.frequency = frequency;
this.amplitude = amplitude;
this.octaves = octaves;
this.randomseed = 2 + randomseed * randomseed;
}
}
PerlinNoiseGenerator.java
public class PerlinNoiseGenerator {
PerlinNoiseParameters parameters;
public PerlinNoiseGenerator() {
}
public PerlinNoiseGenerator(PerlinNoiseParameters parameters) {
this.parameters = parameters;
}
public void ChangeParameters(double persistence, double frequency, double amplitude, int octaves, int randomseed) {
parameters.ChangeParameters(persistence, frequency, amplitude, octaves, randomseed);
}
public void ChangeParameters(PerlinNoiseParameters newParams) {
parameters = newParams;
}
public double get(double x, double y) {
return parameters.amplitude * Total(x, y);
}
private double Total(double i, double j) {
double t = 0.0f;
double _amplitude = 1;
double freq = parameters.frequency;
for (int k = 0; k < parameters.octaves; k++) {
t += GetValue(j * freq + parameters.randomseed, i * freq + parameters.randomseed)
* _amplitude;
_amplitude *= parameters.persistence;
freq *= 2;
}
return t;
}
private double GetValue(double x, double y) {
int Xint = (int) x;
int Yint = (int) y;
double Xfrac = x - Xint;
double Yfrac = y - Yint;
double n01 = Noise(Xint - 1, Yint - 1);
double n02 = Noise(Xint + 1, Yint - 1);
double n03 = Noise(Xint - 1, Yint + 1);
double n04 = Noise(Xint + 1, Yint + 1);
double n05 = Noise(Xint - 1, Yint);
double n06 = Noise(Xint + 1, Yint);
double n07 = Noise(Xint, Yint - 1);
double n08 = Noise(Xint, Yint + 1);
double n09 = Noise(Xint, Yint);
double n12 = Noise(Xint + 2, Yint - 1);
double n14 = Noise(Xint + 2, Yint + 1);
double n16 = Noise(Xint + 2, Yint);
double n23 = Noise(Xint - 1, Yint + 2);
double n24 = Noise(Xint + 1, Yint + 2);
double n28 = Noise(Xint, Yint + 2);
double n34 = Noise(Xint + 2, Yint + 2);
double x0y0 = 0.0625 * (n01 + n02 + n03 + n04) + 0.1250
* (n05 + n06 + n07 + n08) + 0.2500 * n09;
double x1y0 = 0.0625 * (n07 + n12 + n08 + n14) + 0.1250
* (n09 + n16 + n02 + n04) + 0.2500 * n06;
double x0y1 = 0.0625 * (n05 + n06 + n23 + n24) + 0.1250
* (n03 + n04 + n09 + n28) + 0.2500 * n08;
double x1y1 = 0.0625 * (n09 + n16 + n28 + n34) + 0.1250
* (n08 + n14 + n06 + n24) + 0.2500 * n04;
double v1 = Interpolate(x0y0, x1y0, Xfrac);
double v2 = Interpolate(x0y1, x1y1, Xfrac);
double fin = Interpolate(v1, v2, Yfrac);
return fin;
}
private double Interpolate(double x, double y, double a) {
double negA = 1.0 - a;
double negASqr = negA * negA;
double fac1 = 3.0 * (negASqr) - 2.0 * (negASqr * negA);
double aSqr = a * a;
double fac2 = 3.0 * aSqr - 2.0 * (aSqr * a);
return x * fac1 + y * fac2;
}
private double Noise(int x, int y) {
int n = x + y * 57;
n = (n << 13) ^ n;
int t = (n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff;
return 1.0 - (double) t * 0.931322574615478515625e-9;
}
}
The range of a single perlin noise step is:
http://digitalfreepen.com/2017/06/20/range-perlin-noise.html
-sqrt(N/4), sqrt(N/4)
With N being the amount of dimensions. 2 in your case.
Octaves, persistence and amplitude add on top of that:
double range = 0.0;
double _amplitude = parameters.;
for (int k = 0; k < parameters.octaves; k++) {
range += sqrt(N/4) * _amplitude;
_amplitude *= parameters.persistence;
}
return range;
There might be some way to do this as a single mathematical expression. Involving pow(), but by brain fails me right now.
This is not a problem with octaves and frequency affecting amplitude, not directly at least. It is a problem with integer overflow. Because you introduce your random seed by adding it to the the x and y co-ordinates (which is unusual, I don't think this is the usual implimentation)
t += GetValue(j * freq + parameters.randomseed, i * freq + parameters.randomseed)* _amplitude;
And random seed could be huge (possibly the near full size of the int) because
this.randomseed = 2 + randomseed * randomseed;
So if you input large values for j and i you end up with the doubles that are passed through at GetValue(double x, double y) being larger than the maximum size of int, at that point when you call
int Xint = (int) x;
int Yint = (int) y;
Xint and YInt won't be anything like x and y (because x and y could be huge!) and so
double Xfrac = x - Xint;
double Yfrac = y - Yint;
could be much much larger that 1, allowing values not between -1 and 1 to be returned.
Using reasonable and small values my ranges using your code are between -1 and 1 (for amplitude 1)
As an asside, in java usually method names are methodName, not MethodName
If its useful please find annother java implimentation of perlin noise here:
http://mrl.nyu.edu/~perlin/noise/

Categories

Resources