package automenta.vivisect.face;
/**
*
* @author me
*/
import java.util.Random;
public final class ImprovMath
{
private ImprovMath()
{
}
public static double angleBetween(double d, double d1, double d2, double d3,
double d4, double d5)
{
double d6 = d2 - d;
double d7 = d3 - d1;
double d8 = d4 - d;
double d9 = d5 - d1;
return (Math.acos(dot(d6, d7, d8, d9) / (magnitude(d6, d7) * magnitude(d8, d9))) / 3.1415926535897931D) * 180D;
}
public static double bias(double d, double d1)
{
if(d < 0.001D)
return 0.0D;
if(d > 0.999D)
return 1.0D;
if(d1 < 0.001D)
return 0.0D;
if(d1 > 0.999D)
return 1.0D;
else
return Math.pow(d, Math.log(d1) / LOG_HALF);
}
public static double[] cross(double ad[], double ad1[])
{
double ad2[] = new double[3];
ad2[0] = ad[1] * ad1[2] - ad[2] * ad1[1];
ad2[1] = ad[2] * ad1[0] - ad[0] * ad1[2];
ad2[2] = ad[0] * ad1[1] - ad[1] * ad1[0];
return ad2;
}
public static double dot(double d, double d1)
{
return d * d1;
}
public static double dot(double d, double d1, double d2, double d3)
{
return d * d2 + d1 * d3;
}
public static double dot(double d, double d1, double d2, double d3,
double d4, double d5)
{
return d * d3 + d1 * d4 + d2 * d5;
}
public static double dot(double ad[], double ad1[])
{
double d = 0.0D;
int i;
if(ad.length <= ad1.length)
i = ad.length;
else
i = ad1.length;
for(int j = 0; j < i; j++)
d += ad[j] * ad1[j];
return d;
}
public static String doubleToString(double d, int i)
{
double d1 = d - (double)(long)d;
if(d1 == 0.0D)
return String.valueOf((long)d);
boolean flag = false;
if(d < 0.0D)
{
flag = true;
d = -d;
}
double d2 = Math.pow(10D, i);
d *= d2;
if(d - (double)(long)d >= 0.49998999999999999D)
d++;
d /= d2;
String s = String.valueOf(d);
int j = s.indexOf('.');
if(j != -1)
{
int k = j + i + 1;
if(k < s.length())
s = s.substring(0, k);
}
int l = s.length() - 1;
boolean flag1 = false;
for(; l > 0 && s.charAt(l) == '0' && s.charAt(l - 1) != '.'; l--)
flag1 = true;
if(flag1)
s = s.substring(0, l);
return (flag ? "-" : "") + s;
}
public static double gain(double d, double d1)
{
if(d < 0.001D)
return 0.0D;
if(d > 0.999D)
return 1.0D;
d1 = d1 >= 0.001D ? d1 <= 0.999D ? d1 : 0.999D : 0.0001D;
double d2 = Math.log(1.0D - d1) / LOG_HALF;
if(d < 0.5D)
return Math.pow(2D * d, d2) / 2D;
else
return 1.0D - Math.pow(2D * (1.0D - d), d2) / 2D;
}
public static double[] getEulers(double ad[], int i)
{
double ad1[] = new double[3];
double ad2[] = new double[4];
double ad3[][] = new double[3][3];
byte byte0 = 0;
byte byte1 = 1;
byte byte2 = 2;
switch(i)
{
case 0: // '\0'
byte0 = 0;
byte1 = 1;
byte2 = 2;
break;
case 1: // '\001'
byte0 = 0;
byte1 = 2;
byte2 = 1;
break;
case 2: // '\002'
byte0 = 1;
byte1 = 0;
byte2 = 2;
break;
case 3: // '\003'
byte0 = 1;
byte1 = 2;
byte2 = 0;
break;
case 4: // '\004'
byte0 = 2;
byte1 = 0;
byte2 = 1;
break;
case 5: // '\005'
byte0 = 2;
byte1 = 1;
byte2 = 0;
break;
}
ad2[0] = ad[0];
ad2[1] = ad[1];
ad2[2] = ad[2];
ad2[3] = ad[3];
if(ad2[0] == 0.0D && ad2[1] == 0.0D && ad2[2] == 0.0D)
return ad1;
double d1 = ad2[0] * ad2[0] + ad2[1] * ad2[1] + ad2[2] * ad2[2];
if(d1 < 0.0001D)
{
return ad1;
} else
{
double d3 = 1.0D / Math.sqrt(d1);
ad2[0] *= d3;
ad2[1] *= d3;
ad2[2] *= d3;
double d = Math.sin(ad2[3] * 0.5D);
ad2[0] *= d;
ad2[1] *= d;
ad2[2] *= d;
ad2[3] = Math.cos(ad2[3] * 0.5D);
double d2 = ad2[0] * ad2[0] + ad2[1] * ad2[1] + ad2[2] * ad2[2] + ad2[3] * ad2[3];
double d4 = 2D / d2;
double d5 = ad2[0] * d4;
double d6 = ad2[1] * d4;
double d7 = ad2[2] * d4;
double d8 = ad2[3] * d5;
double d9 = ad2[3] * d6;
double d10 = ad2[3] * d7;
double d11 = ad2[0] * d5;
double d12 = ad2[0] * d6;
double d13 = ad2[0] * d7;
double d14 = ad2[1] * d6;
double d15 = ad2[1] * d7;
double d16 = ad2[2] * d7;
ad3[0][0] = 1.0D - d14 - d16;
ad3[0][1] = d12 - d10;
ad3[0][2] = d13 + d9;
ad3[1][0] = d12 + d10;
ad3[1][1] = 1.0D - d11 - d16;
ad3[1][2] = d15 - d8;
ad3[2][0] = d13 - d9;
ad3[2][1] = d15 + d8;
ad3[2][2] = 1.0D - d11 - d14;
int j = byte1 % 3 <= byte0 % 3 ? -1 : 1;
double d17;
double d18;
ad1[byte0] = Math.atan2(d18 = ad3[byte1][byte2] * (double)(-j), d17 = ad3[byte2][byte2]);
ad1[byte1] = Math.atan2(ad3[byte0][byte2] * (double)j, Math.sqrt(d17 * d17 + d18 * d18));
ad1[byte2] = Math.atan2(ad3[byte0][byte1] * (double)(-j), ad3[byte0][byte0]);
ad1[0] /= 0.017453292519943295D;
ad1[1] /= 0.017453292519943295D;
ad1[2] /= 0.017453292519943295D;
return ad1;
}
}
public static double[] getEulers(float af[], int i)
{
double ad[] = {
(double)af[0], (double)af[1], (double)af[2], (double)af[3]
};
return getEulers(ad, i);
}
public static float[] getQuaternion(double ad[])
{
return getQuaternion(ad, 0);
}
public static float[] getQuaternion(double ad[], int i)
{
double ad1[][] = new double[4][4];
float af[] = new float[4];
return getQuaternion(ad, i, ad1, af);
}
public static float[] getQuaternion(double ad[], int i, double ad1[][], float af[])
{
double ad2[][] = ad1;
double ad3[] = ad2[0];
double ad4[] = ad2[1];
double ad5[] = ad2[2];
double ad6[] = ad2[3];
ad3[0] = 1.0D;
ad3[1] = 0.0D;
ad3[2] = 0.0D;
ad3[3] = ad[0] * 0.017453292519943295D;
ad4[0] = 0.0D;
ad4[1] = 1.0D;
ad4[2] = 0.0D;
ad4[3] = ad[1] * 0.017453292519943295D;
ad5[0] = 0.0D;
ad5[1] = 0.0D;
ad5[2] = 1.0D;
ad5[3] = ad[2] * 0.017453292519943295D;
byte byte0;
byte byte1;
byte byte2;
switch(i)
{
case 1: // '\001'
byte0 = 0;
byte1 = 2;
byte2 = 1;
break;
case 2: // '\002'
byte0 = 1;
byte1 = 0;
byte2 = 2;
break;
case 3: // '\003'
byte0 = 1;
byte1 = 2;
byte2 = 0;
break;
case 4: // '\004'
byte0 = 2;
byte1 = 0;
byte2 = 1;
break;
case 5: // '\005'
byte0 = 2;
byte1 = 1;
byte2 = 0;
break;
default:
byte0 = 0;
byte1 = 1;
byte2 = 2;
break;
}
ad2[byte0] = ad3;
ad2[byte1] = ad4;
ad2[byte2] = ad5;
prepAngles(ad2[0]);
prepAngles(ad2[1]);
prepAngles(ad2[2]);
mult(ad2[2], ad2[1], ad6);
mult(ad6, ad2[0], ad2[2]);
double ad7[] = ad2[2];
double d = ad7[0];
double d1 = ad7[1];
double d2 = ad7[2];
double d3 = ad7[3];
double d4 = Math.sqrt(d * d + d1 * d1 + d2 * d2);
if(d4 > 0.0D)
{
af[0] = (float)(d * (1.0D / d4));
af[1] = (float)(d1 * (1.0D / d4));
af[2] = (float)(d2 * (1.0D / d4));
af[3] = 2.0F * (float)Math.acos(d3);
} else
{
af[0] = 0.0F;
af[1] = 1.0F;
af[2] = 0.0F;
af[3] = 0.0F;
}
return af;
}
private static void init()
{
Random random1 = new Random();
int i;
for(i = 0; i < 256; i++)
{
p[i] = i;
double d = (double)(random1.nextLong() & 255L) / 256D;
g1[i] = 2D * d - 1.0D;
for(int k = 0; k < 2; k++)
g2[i][k] = (double)(random1.nextLong() % 512L - 256L) / 256D;
normalize2(g2[i]);
for(int l = 0; l < 3; l++)
g3[i][l] = (double)(random1.nextLong() % 512L - 256L) / 256D;
normalize3(g3[i]);
}
while(--i > 0)
{
int l1 = p[i];
int i1 = (int)(random1.nextLong() & 255L);
p[i] = p[i1];
p[i1] = l1;
}
for(int j = 0; j < 258; j++)
{
p[256 + j] = p[j];
g1[256 + j] = g1[j];
System.arraycopy(g2[j], 0, g2[256 + j], 0, 2);
System.arraycopy(g3[j], 0, g3[256 + j], 0, 3);
}
}
public static double lerp(double d, double d1, double d2)
{
return d1 + d * (d2 - d1);
}
public static double magnitude(double d, double d1)
{
return Math.sqrt(dot(d, d1, d, d1));
}
public static double magnitude(double ad[])
{
return Math.sqrt(dot(ad, ad));
}
private static void mult(double ad[], double ad1[], double ad2[])
{
double d = ad[0];
double d1 = ad[1];
double d2 = ad[2];
double d3 = ad[3];
double d4 = ad1[0];
double d5 = ad1[1];
double d6 = ad1[2];
double d7 = ad1[3];
double d8 = (d7 * d + d4 * d3 + d5 * d2) - d6 * d1;
double d9 = (d7 * d1 + d5 * d3 + d6 * d) - d4 * d2;
double d10 = (d7 * d2 + d6 * d3 + d4 * d1) - d5 * d;
double d11 = d7 * d3 - d4 * d - d5 * d1 - d6 * d2;
d8 *= 1.0D / Math.sqrt(d8 * d8 + d9 * d9 + d10 * d10 + d11 * d11);
d9 *= 1.0D / Math.sqrt(d8 * d8 + d9 * d9 + d10 * d10 + d11 * d11);
d10 *= 1.0D / Math.sqrt(d8 * d8 + d9 * d9 + d10 * d10 + d11 * d11);
d11 *= 1.0D / Math.sqrt(d8 * d8 + d9 * d9 + d10 * d10 + d11 * d11);
ad2[0] = d8;
ad2[1] = d9;
ad2[2] = d10;
ad2[3] = d11;
}
private static double[] multBy(double ad[], double d)
{
double ad1[] = ad;
ad1[0] *= d;
ad1[1] *= d;
ad1[2] *= d;
return ad1;
}
public static double noise(double d)
{
double d7 = d;
if(start == 1)
{
start = 0;
init();
}
double d4 = d7 + 4096D;
int i = (int)d4 & 0xff;
int j = i + 1 & 0xff;
double d1 = d4 - (double)(int)d4;
double d2 = d1 - 1.0D;
double d3 = s_curve(d1);
double d5 = d1 * g1[p[i]];
double d6 = d2 * g1[p[j]];
return lerp(d3, d5, d6);
}
private static double[] norm(double ad[])
{
double ad1[] = new double[4];
ad1[0] = ad[0];
ad1[1] = ad[1];
ad1[2] = ad[2];
ad1[3] = ad[3];
double d = Math.sqrt(ad1[0] * ad1[0] + ad1[1] * ad1[1] + ad1[2] * ad1[2]);
if(d != 0.0D)
{
ad1[0] *= d;
ad1[1] *= d;
ad1[2] *= d;
} else
{
ad1[0] = 0.0D;
ad1[1] = 0.0D;
ad1[2] = 0.0D;
}
return ad1;
}
private static void normalize2(double ad[])
{
double d = Math.sqrt(ad[0] * ad[0] + ad[1] * ad[1]);
ad[0] /= d;
ad[1] /= d;
}
private static void normalize3(double ad[])
{
double d = Math.sqrt(ad[0] * ad[0] + ad[1] * ad[1] + ad[2] * ad[2]);
ad[0] /= d;
ad[1] /= d;
ad[2] /= d;
}
private static void prepAngles(double ad[])
{
norm(ad);
multBy(ad, Math.sin(ad[3] / 2D));
ad[3] = Math.cos(ad[3] / 2D);
}
public static double random(double d, double d1)
{
return Math.min(d, d1) + Math.random() * Math.abs(d1 - d);
}
private static double s_curve(double d)
{
return d * d * (3D - 2D * d);
}
private static int p[] = new int[514];
private static double g3[][] = new double[514][3];
private static double g2[][] = new double[514][2];
private static double g1[] = new double[514];
private static int start = 1;
private static final double LOG_HALF = Math.log(0.5D);
public static final int XYZ = 0;
public static final int XZY = 1;
public static final int YXZ = 2;
public static final int YZX = 3;
public static final int ZXY = 4;
public static final int ZYX = 5;
static
{
init();
}
}