Related
I know the theory of glFrustumf and glOrthof but I'm quite
puzzled by the fact that there is another parameter in android
method that sets projection which is mOffset which does not exist in normal OpenGL implementation.``
public static void orthoM(float[] m, int mOffset, <---- mOffset
float left, float right, float bottom, float top,
float near, float far)
In the implementation it seems that this mOffset parameter shifts matrix index by the value that is setted:
m[mOffset + 0] = x;
m[mOffset + 5] = y;
m[mOffset +10] = z;
m[mOffset +12] = tx;
m[mOffset +13] = ty;
m[mOffset +14] = tz;
m[mOffset +15] = 1.0f;
m[mOffset + 1] = 0.0f;
m[mOffset + 2] = 0.0f;
m[mOffset + 3] = 0.0f;
m[mOffset + 4] = 0.0f;
m[mOffset + 6] = 0.0f;
m[mOffset + 7] = 0.0f;
m[mOffset + 8] = 0.0f;
m[mOffset + 9] = 0.0f;
m[mOffset + 11] = 0.0f;
Can anyone please explain why would you ever need to offset matrix index for the projection? What is a purpouse of mOffset?
I've tried to port these 2 functions from Lua to Java (bspline2D and bspline3D), but they doen't work. The output is completely different, and I can't figure out why.
I've already tried messing with the array numbers, the subdivision value, the for loops, and everything that came up my head.
The test provided should give numbers that are totally different one another, but they're not.
These are the Java results:
bspline2D
0.0, 0.0, 0.0
-1.0, 0.0, 0.0
-1.0, 0.0, 0.0
-1.0, 0.0, 0.0
-1.0, 0.0, 0.0
0.0, 0.0, 0.0
0.0, 0.0, 0.0
0.0, 0.0, 0.0
0.0, 0.0, 0.0
bspline3D
-2.0, 0.0, 0.0
-1.0, 0.0, 0.0
-1.0, 0.0, 0.0
0.0, 0.0, 0.0
0.0, 0.0, 0.0
...which are clearly wrong.
These are the outputs from the Lua version, the correct ones.
bspline2D
0, 0
-0.75, 0
-0.5, 0
-0.25, 0
0, 0
0.24739583, 0.0026041667
0.47916666, 0.020833334
0.6796875, 0.0703125
0.8333333, 0.16666667
0.9270833, 0.31770834
0.9583333, 0.5
0.9270833, 0.6822917
0.8333333, 0.8333333
0.6796875, 0.9296875
0.47916666, 0.9791667
0.24739583, 0.9973958
0, 1
bspline3D
0, 0, 0
0.24739583, 0.0026041667, 0
0.47916666, 0.020833334, 0
0.6796875, 0.0703125, 0
0.8333333, 0.16666667, 0
0.9270833, 0.31770834, 0
0.9583333, 0.5, 0
0.9270833, 0.6822917, 0
0.8333333, 0.8333333, 0
0.6796875, 0.9296875, 0
0.47916666, 0.9791667, 0
0.24739583, 0.9973958, 0
0, 1, 0
-0.25, 1, 0
-0.5, 1, 0
-0.75, 1, 0
-1, 1, 0
-1.25, 1, 0
-1.5, 1, 0
-1.75, 1, 0
-2, 1, 0
I've been scratching my head for days on this, and I have just no ideas, so I thought maybe someone here at StackOverflow would.
Here's the Java version that needs to be fixed:
public static List<Vector3> bspline2D(Vector3[] pointz, int subdivision) {
ArrayList spline = new ArrayList();
int pointsNumber = pointz.length;
Vector3[] points = new Vector3[pointsNumber + 4];
System.arraycopy(pointz, 0, points, 2, pointsNumber);
points[1] = points[2].add(points[2].minus(points[3]));
points[0] = points[1].add(points[1].minus(points[2]));
points[pointsNumber + 2] = points[pointsNumber - 3].add(points[pointsNumber - 3].minus(points[pointsNumber - 4]));
points[pointsNumber + 3] = points[pointsNumber].add(points[pointsNumber].minus(points[pointsNumber - 3]));
spline.add(pointz[0]);
for(int i = 1; i < pointsNumber - 1; ++i) {
double[] a = new double[4];
double[] b = new double[4];
a[0] = (-points[i - 1].x + 3.0D * points[i].x - 3.0D * points[i + 1].x + points[i + 2].x) / 6.0D;
a[1] = (3.0D * points[i - 1].x - 6.0D * points[i].x + 3.0D * points[i + 1].x) / 6.0D;
a[2] = (-3.0D * points[i - 1].x + 3.0D * points[i + 1].x) / 6.0D;
a[3] = (points[i - 1].x + 4.0D * points[i].x + points[i + 1].x) / 6.0D;
b[0] = (-points[i - 1].y + 3.0D * points[i].y - 3.0D * points[i + 1].y + points[i + 2].y) / 6.0D;
b[1] = (3.0D * points[i - 1].y - 6.0D * points[i].y + 3.0D * points[i + 1].y) / 6.0D;
b[2] = (-3.0D * points[i - 1].y + 3.0D * points[i + 1].y) / 6.0D;
b[3] = (points[i - 1].y + 4.0D * points[i].y + points[i + 1].y) / 6.0D;
for(int j = 0; j < subdivision; ++j) {
double t = j / subdivision;
spline.add(new Vector3((a[2] + t * (a[1] + t * a[0])) * t + a[3], (b[2] + t * (b[1] + t * b[0])) * t + b[3]));
}
}
return spline;
}
public static List<Vector3> bspline3D(Vector3[] pointz, int subdivision) {
ArrayList spline = new ArrayList();
int pointsNumber = pointz.length;
Vector3[] points = new Vector3[pointsNumber + 4];
System.arraycopy(pointz, 0, points, 2, pointsNumber);
points[1] = points[2].add(points[2].minus(points[3]));
points[0] = points[1].add(points[1].minus(points[2]));
points[pointsNumber + 2] = pointz[pointsNumber - 1].add(pointz[pointsNumber - 1].minus(pointz[pointsNumber - 2]));
points[pointsNumber + 3] = points[pointsNumber].add(points[pointsNumber].minus(pointz[pointsNumber - 1]));
spline.add(points[0]);
for(int i = 1; i < pointsNumber - 1; ++i) {
double[] a = new double[4];
double[] b = new double[4];
double[] c = new double[4];
a[0] = (-points[i - 1].x + 3.0D * points[i].x - 3.0D * points[i + 1].x + points[i + 2].x) / 6.0D;
a[1] = (3.0D * points[i - 1].x - 6.0D * points[i].x + 3.0D * points[i + 1].x) / 6.0D;
a[2] = (-3.0D * points[i - 1].x + 3.0D * points[i + 1].x) / 6.0D;
a[3] = (points[i - 1].x + 4.0D * points[i].x + points[i + 1].x) / 6.0D;
b[0] = (-points[i - 1].y + 3.0D * points[i].y - 3.0D * points[i + 1].y + points[i + 2].y) / 6.0D;
b[1] = (3.0D * points[i - 1].y - 6.0D * points[i].y + 3.0D * points[i + 1].y) / 6.0D;
b[2] = (-3.0D * points[i - 1].y + 3.0D * points[i + 1].y) / 6.0D;
b[3] = (points[i - 1].y + 4.0D * points[i].y + points[i + 1].y) / 6.0D;
c[0] = (-points[i - 1].z + 3.0D * points[i].z - 3.0D * points[i + 1].z + points[i + 2].z) / 6.0D;
c[1] = (3.0D * points[i - 1].z - 6.0D * points[i].z + 3.0D * points[i + 1].z) / 6.0D;
c[2] = (-3.0D * points[i - 1].z + 3.0D * points[i + 1].z) / 6.0D;
c[3] = (points[i - 1].z + 4.0D * points[i].z + points[i + 1].z) / 6.0D;
for(int j = 1; j < subdivision; ++j) {
double t = j / subdivision;
Vector3 sp = new Vector3();
sp.x = (a[2] + t * (a[1] + t * a[0])) * t + a[3];
sp.y = (b[2] + t * (b[1] + t * b[0])) * t + b[3];
sp.z = (c[2] + t * (c[1] + t * c[0])) * t + c[3];
spline.add(sp);
}
}
return spline;
}
public static void main(String[] args) {
Vector3[] v = new Vector3[] {new Vector3(0, 0, 0), new Vector3(1, 0, 0), new Vector3(1, 1, 0), new Vector3(0, 1, 0)};
System.out.println("\nbspline2D");
for(Vector3 v3 : bspline2D(v, 4)) {
System.out.println(v3.x + ", " + v3.y + ", " + v3.z);
}
System.out.println("\nbspline3D");
for(Vector3 v3 : bspline3D(v, 4)) {
System.out.println(v3.x + ", " + v3.y + ", " + v3.z);
}
}
And here's the Lua version:
function M.bspline2D(points, subdivision)
local spline = {}
local wbvector2 = dofile('wbvector3.lua')
local pointsNumber = #points
-- extend the points array
points[0] = wbvector2.add(points[1], wbvector2.minus(points[1], points[2]))
points[-1] = wbvector2.add(points[0], wbvector2.minus(points[0], points[1]))
points[pointsNumber + 1] = wbvector2.add(points[pointsNumber], wbvector2.minus(points[pointsNumber], points[pointsNumber - 1]))
points[pointsNumber + 2] = wbvector2.add(points[pointsNumber + 1], wbvector2.minus(points[pointsNumber + 1], points[pointsNumber]))
-- Interpolation
local index = 1
spline[index] = points[1] -- first point
for i = 0, pointsNumber - 1 do
local a = {} -- compute the third order coefficients for x
local b = {} -- compute the third order coefficients for y
a[1] = (-points[i-1].x + 3 * points[i].x - 3 * points[i+1].x + points[i+2].x) / 6.0;
a[2] = (3 * points[i-1].x - 6 * points[i].x + 3 * points[i+1].x) / 6.0;
a[3] = (-3 * points[i-1].x + 3 * points[i+1].x) / 6.0;
a[4] = (points[i-1].x + 4 * points[i].x + points[i+1].x) / 6.0;
b[1] = (-points[i-1].y + 3 * points[i].y - 3 * points[i+1].y + points[i+2].y) / 6.0;
b[2] = (3 * points[i-1].y - 6 * points[i].y + 3 * points[i+1].y) / 6.0;
b[3] = (-3 * points[i-1].y + 3 * points[i+1].y) / 6.0;
b[4] = (points[i-1].y + 4 * points[i].y + points[i+1].y) / 6.0;
for j = 1, subdivision do
index = index + 1
spline[index] = {}
local t = j / subdivision
spline[index].x = (a[3] + t * (a[2] + t * a[1])) * t + a[4]
spline[index].y = (b[3] + t * (b[2] + t * b[1])) * t + b[4]
end
end
return spline
end
function M.bspline3D(points, subdivision)
local spline = {}
local wbcore = require('wbcore')
local wbvector3 = require('wbvector3')
local pointsNumber = wbcore.tablelength(points)
-- extend the points array
points[0] = wbvector3.add(points[1], wbvector3.minus(points[1], points[2]))
points[-1] = wbvector3.add(points[0], wbvector3.minus(points[0], points[1]))
points[pointsNumber + 1] = wbvector3.add(points[pointsNumber], wbvector3.minus(points[pointsNumber], points[pointsNumber - 1]))
points[pointsNumber + 2] = wbvector3.add(points[pointsNumber + 1], wbvector3.minus(points[pointsNumber + 1], points[pointsNumber]))
-- Interpolation
local index = 1
spline[index] = points[1] -- first point
for i = 1, pointsNumber - 1 do
local a = {} -- compute the third order coefficients for x
local b = {} -- compute the third order coefficients for y
local c = {} -- compute the third order coefficients for z
a[1] = (-points[i-1].x + 3 * points[i].x - 3 * points[i+1].x + points[i+2].x) / 6.0;
a[2] = (3 * points[i-1].x - 6 * points[i].x + 3 * points[i+1].x) / 6.0;
a[3] = (-3 * points[i-1].x + 3 * points[i+1].x) / 6.0;
a[4] = (points[i-1].x + 4 * points[i].x + points[i+1].x) / 6.0;
b[1] = (-points[i-1].y + 3 * points[i].y - 3 * points[i+1].y + points[i+2].y) / 6.0;
b[2] = (3 * points[i-1].y - 6 * points[i].y + 3 * points[i+1].y) / 6.0;
b[3] = (-3 * points[i-1].y + 3 * points[i+1].y) / 6.0;
b[4] = (points[i-1].y + 4 * points[i].y + points[i+1].y) / 6.0;
c[1] = (-points[i-1].z + 3 * points[i].z - 3 * points[i+1].z + points[i+2].z) / 6.0;
c[2] = (3 * points[i-1].z - 6 * points[i].z + 3 * points[i+1].z) / 6.0;
c[3] = (-3 * points[i-1].z + 3 * points[i+1].z) / 6.0;
c[4] = (points[i-1].z + 4 * points[i].z + points[i+1].z) / 6.0;
for j = 1, subdivision do
index = index + 1
spline[index] = {}
local t = j / subdivision
spline[index].x = (a[3] + t * (a[2] + t * a[1])) * t + a[4]
spline[index].y = (b[3] + t * (b[2] + t * b[1])) * t + b[4]
spline[index].z = (c[3] + t * (c[2] + t * c[1])) * t + c[4]
end
end
return spline
end
local v = {{x = 0, y = 0, z = 0}, {x = 1, y = 0, z = 0}, {x = 1, y = 1, z = 0}, {x = 0, y = 1, z = 0}}
print()
print("bspline2D");
for _, v3 in ipairs(M.bspline2D(v, 4)) do
print(v3.x .. ", " .. v3.y .. ", " .. v3.z)
end
print()
print("bspline3D");
for _, v3 in ipairs(M.bspline3D(v, 4)) do
print(v3.x .. ", " .. v3.y .. ", " .. v3.z)
end
My friend and I was having a lot of trouble trying to implement the perceptron algorithm, but then I found this tutorial, it goes through a java implementation and then has some example code. I substituted my own data structures for there ones in the tutorial, and it works! :)
HOWEVER
I made this substitution in the most simplistic possible way, manually enumerating my data structures. This works as a proof of concept, for my experimental "toy" data, but most certainly is not able to tackle the real data I want to consider. It's far too rigid.
Perhaps someone more proficient in abstract thinking and loops would be able to show me how I can improve this code.
The important data structure to consider is Map<File, int[] >, it looks like this:
/data/test/sports/t.s_1.txt, [0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0]
/data/test/politics/t.p_0.txt, [0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0]
/data/test/atheism/t.a_0.txt, [0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
/data/test/science/t.s_0.txt, [1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0]
The code that needs to be generalized proceeds this sentence, you can also find the full programme on this github page.
Thank you for your consideration & happy Japanese/Chinese new year!
public static void perceptron( Set<String> GLOBO_DICT, Map<File, int[] > training_perceptron_input, Map<File, int[] > test_perceptron_input)
{
//number of features, number of x, y, z
int size_of_globo_dict = GLOBO_DICT.size();
//number of instances
int NUM_INSTANCES = training_perceptron_input.size();
//three variables (features) they enumerate by
//features, xyz, i also do that
double[] a00 = new double [NUM_INSTANCES];
double[] a01 = new double [NUM_INSTANCES];
double[] a02 = new double [NUM_INSTANCES];
double[] a03 = new double [NUM_INSTANCES];
double[] a04 = new double [NUM_INSTANCES];
double[] a05 = new double [NUM_INSTANCES];
double[] a06 = new double [NUM_INSTANCES];
double[] a07 = new double [NUM_INSTANCES];
double[] a08 = new double [NUM_INSTANCES];
double[] a09 = new double [NUM_INSTANCES];
double[] a10 = new double [NUM_INSTANCES];
double[] a11 = new double [NUM_INSTANCES];
double[] a12 = new double [NUM_INSTANCES];
double[] a13 = new double [NUM_INSTANCES];
double[] a14 = new double [NUM_INSTANCES];
double[] a15 = new double [NUM_INSTANCES];
double[] a16 = new double [NUM_INSTANCES];
double[] a17 = new double [NUM_INSTANCES];
double[] a18 = new double [NUM_INSTANCES];
double[] a19 = new double [NUM_INSTANCES];
double[] a20 = new double [NUM_INSTANCES];
double[] a21 = new double [NUM_INSTANCES];
double[] a22 = new double [NUM_INSTANCES];
double[] a23 = new double [NUM_INSTANCES];
double[] a24 = new double [NUM_INSTANCES];
double[] a25 = new double [NUM_INSTANCES];
double[] a26 = new double [NUM_INSTANCES];
double[] a27 = new double [NUM_INSTANCES];
double[] a28 = new double [NUM_INSTANCES];
double[] a29 = new double [NUM_INSTANCES];
double[] a30 = new double [NUM_INSTANCES];
//2d array for features
int x = 0;
int[][] feature_matrix = new int[ training_perceptron_input.size() ][ GLOBO_DICT.size() ];
String[][] output_label = new String[ training_perceptron_input.size() ][ 2 ];
for(Entry<File, int[]> entry : training_perceptron_input.entrySet())
{
int[] container =entry.getValue();
for(int j = 0; j < 4; j++)
{
feature_matrix[x][j] = container[j];
output_label[x][1] = entry.getKey().toString();
}
x++;
}
int[] outputs = new int [NUM_INSTANCES];
for(int g = 0; g < NUM_INSTANCES; g++)
{
a00[g] = feature_matrix[g][ 0];
a01[g] = feature_matrix[g][ 1];
a02[g] = feature_matrix[g][ 2];
a03[g] = feature_matrix[g][ 3];
a04[g] = feature_matrix[g][ 4];
a05[g] = feature_matrix[g][ 5];
a06[g] = feature_matrix[g][ 6];
a07[g] = feature_matrix[g][ 7];
a08[g] = feature_matrix[g][ 8];
a09[g] = feature_matrix[g][ 9];
a10[g] = feature_matrix[g][10];
a11[g] = feature_matrix[g][11];
a12[g] = feature_matrix[g][12];
a13[g] = feature_matrix[g][13];
a14[g] = feature_matrix[g][14];
a15[g] = feature_matrix[g][15];
a16[g] = feature_matrix[g][16];
a17[g] = feature_matrix[g][17];
a18[g] = feature_matrix[g][18];
a19[g] = feature_matrix[g][19];
a20[g] = feature_matrix[g][20];
a21[g] = feature_matrix[g][21];
a22[g] = feature_matrix[g][22];
a23[g] = feature_matrix[g][23];
a24[g] = feature_matrix[g][24];
a25[g] = feature_matrix[g][25];
a26[g] = feature_matrix[g][26];
a27[g] = feature_matrix[g][27];
a28[g] = feature_matrix[g][28];
a29[g] = feature_matrix[g][29];
a30[g] = feature_matrix[g][30];
if(output_label[g][1].equals( "/home/yamada/Workbench/SUTD/ISTD_50.570/assignments/practice_data/data/train/atheism/a_0.txt" ) )
{
outputs[g] = 1;
}
else
{
outputs[g] = 0;
}
}
double[] weights = new double[ GLOBO_DICT.size() + 1];// 32 for input variables and one for bias
double localError, globalError;
int i, p, iteration, output;
weights[ 0] = randomNumber(0,1);// w1
weights[ 1] = randomNumber(0,1);// w2
weights[ 2] = randomNumber(0,1);// w3
weights[ 3] = randomNumber(0,1);// w4
weights[ 4] = randomNumber(0,1);// w5
weights[ 5] = randomNumber(0,1);// w6
weights[ 6] = randomNumber(0,1);// w7
weights[ 7] = randomNumber(0,1);// w8
weights[ 8] = randomNumber(0,1);// w9
weights[ 9] = randomNumber(0,1);// w10
weights[10] = randomNumber(0,1);// w11
weights[11] = randomNumber(0,1);// w12
weights[12] = randomNumber(0,1);// w13
weights[13] = randomNumber(0,1);// w14
weights[14] = randomNumber(0,1);// w15
weights[15] = randomNumber(0,1);// w16
weights[16] = randomNumber(0,1);// w17
weights[17] = randomNumber(0,1);// w18
weights[18] = randomNumber(0,1);// w19
weights[19] = randomNumber(0,1);// w20
weights[20] = randomNumber(0,1);// w21
weights[21] = randomNumber(0,1);// w22
weights[22] = randomNumber(0,1);// w23
weights[23] = randomNumber(0,1);// w24
weights[24] = randomNumber(0,1);// w25
weights[25] = randomNumber(0,1);// w26
weights[26] = randomNumber(0,1);// w27
weights[27] = randomNumber(0,1);// w28
weights[28] = randomNumber(0,1);// w29
weights[29] = randomNumber(0,1);// w30
weights[30] = randomNumber(0,1);// w31
weights[31] = randomNumber(0,1);// this is the bias
iteration = 0;
do {
iteration++;
globalError = 0;
//loop through all instances (complete one epoch)
for (p = 0; p < NUM_INSTANCES; p++)
{
// calculate predicted class
output = calculateOutput(theta,
weights,
a00[p],
a01[p],
a02[p],
a03[p],
a04[p],
a05[p],
a06[p],
a07[p],
a08[p],
a09[p],
a10[p],
a11[p],
a12[p],
a13[p],
a14[p],
a15[p],
a16[p],
a17[p],
a18[p],
a19[p],
a20[p],
a21[p],
a22[p],
a23[p],
a24[p],
a25[p],
a26[p],
a27[p],
a28[p],
a29[p],
a30[p]);
// difference between predicted and actual class values
localError = outputs[p] - output;
//update weights and bias
weights[ 0] += LEARNING_RATE * localError * a00[p];
weights[ 1] += LEARNING_RATE * localError * a01[p];
weights[ 2] += LEARNING_RATE * localError * a02[p];
weights[ 3] += LEARNING_RATE * localError * a03[p];
weights[ 4] += LEARNING_RATE * localError * a04[p];
weights[ 5] += LEARNING_RATE * localError * a05[p];
weights[ 6] += LEARNING_RATE * localError * a06[p];
weights[ 7] += LEARNING_RATE * localError * a07[p];
weights[ 8] += LEARNING_RATE * localError * a08[p];
weights[ 9] += LEARNING_RATE * localError * a09[p];
weights[10] += LEARNING_RATE * localError * a10[p];
weights[11] += LEARNING_RATE * localError * a11[p];
weights[12] += LEARNING_RATE * localError * a12[p];
weights[13] += LEARNING_RATE * localError * a13[p];
weights[14] += LEARNING_RATE * localError * a14[p];
weights[15] += LEARNING_RATE * localError * a15[p];
weights[16] += LEARNING_RATE * localError * a16[p];
weights[17] += LEARNING_RATE * localError * a17[p];
weights[18] += LEARNING_RATE * localError * a18[p];
weights[19] += LEARNING_RATE * localError * a19[p];
weights[20] += LEARNING_RATE * localError * a20[p];
weights[21] += LEARNING_RATE * localError * a21[p];
weights[22] += LEARNING_RATE * localError * a22[p];
weights[23] += LEARNING_RATE * localError * a23[p];
weights[24] += LEARNING_RATE * localError * a24[p];
weights[25] += LEARNING_RATE * localError * a25[p];
weights[26] += LEARNING_RATE * localError * a26[p];
weights[27] += LEARNING_RATE * localError * a27[p];
weights[28] += LEARNING_RATE * localError * a28[p];
weights[29] += LEARNING_RATE * localError * a29[p];
weights[30] += LEARNING_RATE * localError * a30[p];
weights[31] += LEARNING_RATE * localError;
//summation of squared error (error value for all instances)
globalError += (localError*localError);
}
/* Root Mean Squared Error */
System.out.println("Iteration "+iteration+" : RMSE = "+Math.sqrt(globalError/NUM_INSTANCES));
}
while (globalError != 0 && iteration <= MAX_ITER);
System.out.println("\n=======\nDecision boundary equation:");
System.out.println(
" a00 *" +
weights[ 0] +
" a01 *" +
weights[ 1] +
" a02 *" +
weights[ 2] +
" a03 *" +
weights[ 3] +
" a04 *" +
weights[ 4] +
" a05 *" +
weights[ 5] +
" a06 *" +
weights[ 6] +
" a07 *" +
weights[ 7] +
" a08 *" +
weights[ 8] +
" a09 *" +
weights[ 9] +
" a10 *" +
weights[10] +
" a11 *" +
weights[11] +
" a12 *" +
weights[12] +
" a13 *" +
weights[13] +
" a14 *" +
weights[14] +
" a15 *" +
weights[15] +
" a16 *" +
weights[16] +
" a17 *" +
weights[17] +
" a18 *" +
weights[18] +
" a19 *" +
weights[19] +
" a20 *" +
weights[20] +
" a21 *" +
weights[21] +
" a22 *" +
weights[22] +
" a23 *" +
weights[23] +
" a24 *" +
weights[24] +
" a25 *" +
weights[25] +
" a26 *" +
weights[26] +
" a27 *" +
weights[27] +
" a28 *" +
weights[28] +
" a29 *" +
weights[29] +
" a30 *" +
weights[30] +
" bias: " +
weights[31]);
//2d array for features
int x_TEST = 0;
int[][] feature_matrix_TEST = new int[ test_perceptron_input.size() ][ GLOBO_DICT.size() ];
for(Entry<File, int[]> entry : test_perceptron_input.entrySet())
{
int[] container =entry.getValue();
for(int jj = 0; jj < 4; jj++)
{
feature_matrix_TEST[x_TEST][jj] = container[jj];
}
x_TEST++;
}
//three variables (features) they enumerate by
//features, xyz, i also do that
double[] z00 = new double [NUM_INSTANCES];
double[] z01 = new double [NUM_INSTANCES];
double[] z02 = new double [NUM_INSTANCES];
double[] z03 = new double [NUM_INSTANCES];
double[] z04 = new double [NUM_INSTANCES];
double[] z05 = new double [NUM_INSTANCES];
double[] z06 = new double [NUM_INSTANCES];
double[] z07 = new double [NUM_INSTANCES];
double[] z08 = new double [NUM_INSTANCES];
double[] z09 = new double [NUM_INSTANCES];
double[] z10 = new double [NUM_INSTANCES];
double[] z11 = new double [NUM_INSTANCES];
double[] z12 = new double [NUM_INSTANCES];
double[] z13 = new double [NUM_INSTANCES];
double[] z14 = new double [NUM_INSTANCES];
double[] z15 = new double [NUM_INSTANCES];
double[] z16 = new double [NUM_INSTANCES];
double[] z17 = new double [NUM_INSTANCES];
double[] z18 = new double [NUM_INSTANCES];
double[] z19 = new double [NUM_INSTANCES];
double[] z20 = new double [NUM_INSTANCES];
double[] z21 = new double [NUM_INSTANCES];
double[] z22 = new double [NUM_INSTANCES];
double[] z23 = new double [NUM_INSTANCES];
double[] z24 = new double [NUM_INSTANCES];
double[] z25 = new double [NUM_INSTANCES];
double[] z26 = new double [NUM_INSTANCES];
double[] z27 = new double [NUM_INSTANCES];
double[] z28 = new double [NUM_INSTANCES];
double[] z29 = new double [NUM_INSTANCES];
double[] z30 = new double [NUM_INSTANCES];
for(int g = 0; g < NUM_INSTANCES; g++)
{
z00[g] = feature_matrix_TEST[g][ 0];
z01[g] = feature_matrix_TEST[g][ 1];
z02[g] = feature_matrix_TEST[g][ 2];
z03[g] = feature_matrix_TEST[g][ 3];
z04[g] = feature_matrix_TEST[g][ 4];
z05[g] = feature_matrix_TEST[g][ 5];
z06[g] = feature_matrix_TEST[g][ 6];
z07[g] = feature_matrix_TEST[g][ 7];
z08[g] = feature_matrix_TEST[g][ 8];
z09[g] = feature_matrix_TEST[g][ 9];
z10[g] = feature_matrix_TEST[g][10];
z11[g] = feature_matrix_TEST[g][11];
z12[g] = feature_matrix_TEST[g][12];
z13[g] = feature_matrix_TEST[g][13];
z14[g] = feature_matrix_TEST[g][14];
z15[g] = feature_matrix_TEST[g][15];
z16[g] = feature_matrix_TEST[g][16];
z17[g] = feature_matrix_TEST[g][17];
z18[g] = feature_matrix_TEST[g][18];
z19[g] = feature_matrix_TEST[g][19];
z20[g] = feature_matrix_TEST[g][20];
z21[g] = feature_matrix_TEST[g][21];
z22[g] = feature_matrix_TEST[g][22];
z23[g] = feature_matrix_TEST[g][23];
z24[g] = feature_matrix_TEST[g][24];
z25[g] = feature_matrix_TEST[g][25];
z26[g] = feature_matrix_TEST[g][26];
z27[g] = feature_matrix_TEST[g][27];
z28[g] = feature_matrix_TEST[g][28];
z29[g] = feature_matrix_TEST[g][29];
z30[g] = feature_matrix_TEST[g][30];
}
int output_TEST;
// calculate predicted class TEST
output_TEST = calculateOutput(theta,
weights,
z00[2],
z01[2],
z02[2],
z03[2],
z04[2],
z05[2],
z06[2],
z07[2],
z08[2],
z09[2],
z10[2],
z11[2],
z12[2],
z13[2],
z14[2],
z15[2],
z16[2],
z17[2],
z18[2],
z19[2],
z20[2],
z21[2],
z22[2],
z23[2],
z24[2],
z25[2],
z26[2],
z27[2],
z28[2],
z29[2],
z30[2]);
System.out.println("\n=======\nTEST Point:");
System.out.println(
"z00[0]:" + z00[0] +
"z01[0]:" + z01[0] +
"z02[0]:" + z02[0] +
"z03[0]:" + z03[0] +
"z04[0]:" + z04[0] +
"z05[0]:" + z05[0] +
"z06[0]:" + z06[0] +
"z07[0]:" + z07[0] +
"z08[0]:" + z08[0] +
"z09[0]:" + z09[0] +
"z10[0]:" + z10[0] +
"z11[0]:" + z11[0] +
"z12[0]:" + z12[0] +
"z13[0]:" + z13[0] +
"z14[0]:" + z14[0] +
"z15[0]:" + z15[0] +
"z16[0]:" + z16[0] +
"z17[0]:" + z17[0] +
"z18[0]:" + z18[0] +
"z19[0]:" + z19[0] +
"z20[0]:" + z20[0] +
"z21[0]:" + z21[0] +
"z22[0]:" + z22[0] +
"z23[0]:" + z23[0] +
"z24[0]:" + z24[0] +
"z25[0]:" + z25[0] +
"z26[0]:" + z26[0] +
"z27[0]:" + z27[0] +
"z28[0]:" + z28[0] +
"z29[0]:" + z29[0] +
"z30[0]:" + z30[0]
);
System.out.println("class = "+output_TEST);
}
//end main
/**
* returns a random double value within a given range
* #param min the minimum value of the required range (int)
* #param max the maximum value of the required range (int)
* #return a random double value between min and max
*/
public static double randomNumber(int min , int max) {
DecimalFormat df = new DecimalFormat("#.####");
double d = min + Math.random() * (max - min);
String s = df.format(d);
double x = Double.parseDouble(s);
return x;
}
/**
* returns either 1 or 0 using a threshold function
* theta is 0range
* #param theta an integer value for the threshold
* #param weights[] the array of weights
* #param x the x input value
* #param y the y input value
* #param z the z input value
* #return 1 or 0
*/
static int calculateOutput(int theta,
double weights[],
double a00,
double a01,
double a02,
double a03,
double a04,
double a05,
double a06,
double a07,
double a08,
double a09,
double a10,
double a11,
double a12,
double a13,
double a14,
double a15,
double a16,
double a17,
double a18,
double a19,
double a20,
double a21,
double a22,
double a23,
double a24,
double a25,
double a26,
double a27,
double a28,
double a29,
double a30)
{
double sum = a00 *
weights[ 0] +
a01 *
weights[ 1] +
a02 *
weights[ 2] +
a03 *
weights[ 3] +
a04 *
weights[ 4] +
a05 *
weights[ 5] +
a06 *
weights[ 6] +
a07 *
weights[ 7] +
a08 *
weights[ 8] +
a09 *
weights[ 9] +
a10 *
weights[10] +
a11 *
weights[11] +
a12 *
weights[12] +
a13 *
weights[13] +
a14 *
weights[14] +
a15 *
weights[15] +
a16 *
weights[16] +
a17 *
weights[17] +
a18 *
weights[18] +
a19 *
weights[19] +
a20 *
weights[20] +
a21 *
weights[21] +
a22 *
weights[22] +
a23 *
weights[23] +
a24 *
weights[24] +
a25 *
weights[25] +
a26 *
weights[26] +
a27 *
weights[27] +
a28 *
weights[28] +
a29 *
weights[29] +
a30 *
weights[30] +
weights[31];
return (sum >= theta) ? 1 : 0;
}
}
Here is a more generalized version your Perceptron class, simplified to reduce code duplication. Though untested, this is mechanically equivalent to the code you presented in your question.
class Perceptron {
static final int MAX_ITER = 100;
static final double LEARNING_RATE = 0.1;
static final int THETA = 0;
static final String FILEPATH =
"/home/yamada/Workbench/SUTD/ISTD_50.570/assignments/practice_data/data/train/atheism/a_0.txt";
public static void perceptron(Set<String> globoDict,
Map<File, int[]> trainingPerceptronInput,
Map<File, int[]> testPerceptronInput)
{
final int globoDictSize = globoDict.size(); // number of features (x, y, z)
// weights total 32 (31 for input variables and one for bias)
double[] weights = new double[globoDictSize + 1];
for (int i = 0; i < weights.length; i++) {
weights[i] = Math.floor(Math.random() * 10000) / 10000;
}
int inputSize = trainingPerceptronInput.size();
int[] outputs = new int[inputSize];
final double[][] a =
initializeOutput(trainingPerceptronInput, globoDictSize, outputs);
double globalError;
int iteration = 0;
do {
iteration++;
globalError = 0;
// loop through all instances (complete one epoch)
for (int p = 0; p < inputSize; p++) {
// calculate predicted class
int output = calculateOutput(THETA, weights, a, p);
// difference between predicted and actual class values
double localError = outputs[p] - output;
int i;
for (i = 0; i < a.length; i++) {
weights[i] += LEARNING_RATE * localError * a[i][p];
}
weights[i] += LEARNING_RATE * localError;
// summation of squared error (error value for all instances)
globalError += localError * localError;
}
/* Root Mean Squared Error */
System.out.println("Iteration "
+ iteration + " : RMSE = " + Math.sqrt(globalError
/ inputSize));
} while (globalError != 0 && iteration <= MAX_ITER);
System.out.println("\n=======\nDecision boundary equation:");
int i;
for (i = 0; i < a.length; i++) {
System.out.print(" a");
if (i < 10) System.out.print(0);
System.out.print(i + " *" + weights[i]);
}
System.out.println(" bias: " + weights[i]);
inputSize = testPerceptronInput.size();
outputs = new int[inputSize];
double[][] z = initializeOutput(testPerceptronInput, globoDictSize, outputs);
// calculate predicted class TEST
int output = calculateOutput(THETA, weights, z, 2);
System.out.println("\n=======\nTEST Point:");
for (i = 0; i < z.length; i++) {
System.out.print(" z");
if (i < 10) System.out.print(0);
System.out.print(i + "[0]" + z[i][0]);
}
System.out.println();
System.out.println("class = " + output);
}
static double[][] initializeOutput(
Map<File, int[]> perceptronInput, int size, int[] outputs)
{
final int inputSize = perceptronInput.size();
final double[][] a = new double[size][inputSize];
// 2d array for features
int[][] feature_matrix = new int[inputSize][size];
String[] output_label = new String[inputSize];
int x = 0;
for (Entry<File, int[]> entry : perceptronInput.entrySet()) {
int[] container = entry.getValue();
for (int j = 0; j < container.length; j++) {
feature_matrix[x][j] = container[j];
output_label[x] = String.valueOf(entry.getKey());
}
x++;
}
for (x = 0; x < inputSize; x++) {
for (int i = 0; i < a.length; i++) {
a[i][x] = feature_matrix[x][i];
}
outputs[x] = output_label[x].equals(FILEPATH) ? 1 : 0;
}
return a;
}
/**
* returns either 1 or 0 using a threshold function
* theta is 0range
* #param theta an integer value for the threshold
* #param weights the array of weights
* #param a the array of inputs
* #return 1 or 0
*/
static int calculateOutput(int theta, double[] weights, double[][] a, int index)
{
double sum = 0;
int i;
for (i = 0; i < a.length; i++) {
sum += weights[i] * a[i][index];
}
sum += weights[i];
return (sum >= theta) ? 1 : 0;
}
}
I hope this is instructional for you.
I have an algorithm in JavaScript which I want to transform into Java.
Here is the JavaScript code:
function downScaleCanvas(cv, scale) {
if (!(scale < 1) || !(scale > 0)) throw ('scale must be a positive number <1 ');
var sqScale = scale * scale; // square scale = area of source pixel within target
var sw = cv.width; // source image width
var sh = cv.height; // source image height
var tw = Math.ceil(sw * scale); // target image width
var th = Math.ceil(sh * scale); // target image height
var sx = 0, sy = 0, sIndex = 0; // source x,y, index within source array
var tx = 0, ty = 0, yIndex = 0, tIndex = 0; // target x,y, x,y index within target array
var tX = 0, tY = 0; // rounded tx, ty
var w = 0, nw = 0, wx = 0, nwx = 0, wy = 0, nwy = 0; // weight / next weight x / y
// weight is weight of current source point within target.
// next weight is weight of current source point within next target's point.
var crossX = false; // does scaled px cross its current px right border ?
var crossY = false; // does scaled px cross its current px bottom border ?
var sBuffer = cv.getContext('2d').getImageData(0, 0, sw, sh).data; // source buffer 8 bit rgba
var tBuffer = new Float32Array(4 * sw * sh); // target buffer Float32 rgb
var sR = 0, sG = 0, sB = 0; // source's current point r,g,b
// untested !
var sA = 0; //source alpha
for (sy = 0; sy < sh; sy++) {
ty = sy * scale; // y src position within target
tY = 0 | ty; // rounded : target pixel's y
yIndex = 4 * tY * tw; // line index within target array
crossY = (tY != (0 | ty + scale));
if (crossY) { // if pixel is crossing botton target pixel
wy = (tY + 1 - ty); // weight of point within target pixel
nwy = (ty + scale - tY - 1); // ... within y+1 target pixel
}
for (sx = 0; sx < sw; sx++, sIndex += 4) {
tx = sx * scale; // x src position within target
tX = 0 | tx; // rounded : target pixel's x
tIndex = yIndex + tX * 4; // target pixel index within target array
crossX = (tX != (0 | tx + scale));
if (crossX) { // if pixel is crossing target pixel's right
wx = (tX + 1 - tx); // weight of point within target pixel
nwx = (tx + scale - tX - 1); // ... within x+1 target pixel
}
sR = sBuffer[sIndex ]; // retrieving r,g,b for curr src px.
sG = sBuffer[sIndex + 1];
sB = sBuffer[sIndex + 2];
sA = sBuffer[sIndex + 3];
if (!crossX && !crossY) { // pixel does not cross
// just add components weighted by squared scale.
tBuffer[tIndex ] += sR * sqScale;
tBuffer[tIndex + 1] += sG * sqScale;
tBuffer[tIndex + 2] += sB * sqScale;
tBuffer[tIndex + 3] += sA * sqScale;
} else if (crossX && !crossY) { // cross on X only
w = wx * scale;
// add weighted component for current px
tBuffer[tIndex ] += sR * w;
tBuffer[tIndex + 1] += sG * w;
tBuffer[tIndex + 2] += sB * w;
tBuffer[tIndex + 3] += sA * w;
// add weighted component for next (tX+1) px
nw = nwx * scale;
tBuffer[tIndex + 4] += sR * nw; // not 3
tBuffer[tIndex + 5] += sG * nw; // not 4
tBuffer[tIndex + 6] += sB * nw; // not 5
tBuffer[tIndex + 7] += sA * nw; // not 6
} else if (crossY && !crossX) { // cross on Y only
w = wy * scale;
// add weighted component for current px
tBuffer[tIndex ] += sR * w;
tBuffer[tIndex + 1] += sG * w;
tBuffer[tIndex + 2] += sB * w;
tBuffer[tIndex + 3] += sA * w;
// add weighted component for next (tY+1) px
nw = nwy * scale;
tBuffer[tIndex + 4 * tw ] += sR * nw; // *4, not 3
tBuffer[tIndex + 4 * tw + 1] += sG * nw; // *4, not 3
tBuffer[tIndex + 4 * tw + 2] += sB * nw; // *4, not 3
tBuffer[tIndex + 4 * tw + 3] += sA * nw; // *4, not 3
} else { // crosses both x and y : four target points involved
// add weighted component for current px
w = wx * wy;
tBuffer[tIndex ] += sR * w;
tBuffer[tIndex + 1] += sG * w;
tBuffer[tIndex + 2] += sB * w;
tBuffer[tIndex + 3] += sA * w;
// for tX + 1; tY px
nw = nwx * wy;
tBuffer[tIndex + 4] += sR * nw; // same for x
tBuffer[tIndex + 5] += sG * nw;
tBuffer[tIndex + 6] += sB * nw;
tBuffer[tIndex + 7] += sA * nw;
// for tX ; tY + 1 px
nw = wx * nwy;
tBuffer[tIndex + 4 * tw ] += sR * nw; // same for mul
tBuffer[tIndex + 4 * tw + 1] += sG * nw;
tBuffer[tIndex + 4 * tw + 2] += sB * nw;
tBuffer[tIndex + 4 * tw + 3] += sA * nw;
// for tX + 1 ; tY +1 px
nw = nwx * nwy;
tBuffer[tIndex + 4 * tw + 4] += sR * nw; // same for both x and y
tBuffer[tIndex + 4 * tw + 5] += sG * nw;
tBuffer[tIndex + 4 * tw + 6] += sB * nw;
tBuffer[tIndex + 4 * tw + 7] += sA * nw;
}
} // end for sx
} // end for sy
// create result canvas
var resCV = document.createElement('canvas');
resCV.width = tw;
resCV.height = th;
var resCtx = resCV.getContext('2d');
var imgRes = resCtx.getImageData(0, 0, tw, th);
var tByteBuffer = imgRes.data;
// convert float32 array into a UInt8Clamped Array
var pxIndex = 0; //
for (sIndex = 0, tIndex = 0; pxIndex < tw * th; sIndex += 4, tIndex += 4, pxIndex++) {
tByteBuffer[tIndex] = Math.ceil(tBuffer[sIndex]);
tByteBuffer[tIndex + 1] = Math.ceil(tBuffer[sIndex + 1]);
tByteBuffer[tIndex + 2] = Math.ceil(tBuffer[sIndex + 2]);
tByteBuffer[tIndex + 3] = Math.ceil(tBuffer[sIndex + 3]);
}
// writing result to canvas.
resCtx.putImageData(imgRes, 0, 0);
return resCV;
}
Here is what I did so far in Java:
public static final CanvasElement scaleCanvas(CanvasElement cv, double scale) {
if (!(scale < 1) || !(scale > 0)) {
// throw new Exception("scale must be a positive number <1 ");
}
double sqScale = scale * scale; // square scale = area of source pixel within target
int sw = cv.getWidth(); // source image width
int sh = cv.getHeight(); // source image height
double tw = Math.ceil(sw * scale); // target image width
double th = Math.ceil(sh * scale); // target image height
int sx = 0, sy = 0, sIndex = 0; // source x,y, index within source array
double tx = 0, ty = 0;
int yIndex = 0, tIndex = 0; // target x,y, x,y index within target array
double tX = 0, tY = 0; // rounded tx, ty
double w = 0, nw = 0, wx = 0, nwx = 0, wy = 0, nwy = 0; // weight / next weight x / y
// weight is weight of current source point within target.
// next weight is weight of current source point within next target's point.
boolean crossX = false; // does scaled px cross its current px right border ?
boolean crossY = false; // does scaled px cross its current px bottom border ?
CanvasPixelArray sBuffer = cv.getContext2d().getImageData(0, 0, sw, sh).getData(); // source buffer 8 bit rgba
Float32Array tBuffer = TypedArrays.createFloat32Array(4 * sw * sh);
double sR = 0, sG = 0, sB = 0; // source's current point r,g,b
// untested !
double sA = 0; //source alpha
for (sy = 0; sy < sh; sy++) {
GWT.log("sy: "+sy+" sh: "+sh);
ty = sy * scale; // y src position within target
tY = (long)ty; // rounded : target pixel's y // ?????
yIndex = (int)Math.floor(4 * tY * tw); // line index within target array
crossY = (tY != ( (long)(ty + scale) )); // ?????
if (crossY) { // if pixel is crossing botton target pixel
wy = (tY + 1 - ty); // weight of point within target pixel
nwy = (ty + scale - tY - 1); // ... within y+1 target pixel
}
for (sx = 0; sx < sw; sx++, sIndex += 4) {
tx = sx * scale; // x src position within target
tX = (long)tx; // rounded : target pixel's x // ?????
tIndex = (int)Math.floor(yIndex + tX * 4); // target pixel index within target array // ?????
crossX = (tX != ((int)Math.floor(tx + scale)));
if (crossX) { // if pixel is crossing target pixel's right
wx = (tX + 1 - tx); // weight of point within target pixel
nwx = (tx + scale - tX - 1); // ... within x+1 target pixel
}
sR = sBuffer.get(sIndex); // retrieving r,g,b for curr src px.
sG = sBuffer.get(sIndex + 1);
sB = sBuffer.get(sIndex + 2);
sA = sBuffer.get(sIndex + 3);
if (!crossX && !crossY) { // pixel does not cross
// just add components weighted by squared scale.
tBuffer.set(tIndex , (float)(tBuffer.get(tIndex) + sR * sqScale));
tBuffer.set(tIndex + 1, (float)(tBuffer.get(tIndex + 1) + sG * sqScale));
tBuffer.set(tIndex + 2, (float)(tBuffer.get(tIndex + 2) + sB * sqScale));
tBuffer.set(tIndex + 3, (float)(tBuffer.get(tIndex + 3) + sA * sqScale));
} else if (crossX && !crossY) { // cross on X only
w = wx * scale;
// add weighted component for current px
tBuffer.set(tIndex , (float)(tBuffer.get(tIndex) + sR * w));
tBuffer.set(tIndex + 1, (float)(tBuffer.get(tIndex + 1) + sG * w));
tBuffer.set(tIndex + 2, (float)(tBuffer.get(tIndex + 2) + sB * w));
tBuffer.set(tIndex + 3, (float)(tBuffer.get(tIndex + 3) + sA * w));
// add weighted component for next (tX+1) px
nw = nwx * scale;
tBuffer.set(tIndex + 4, (float)(tBuffer.get(tIndex + 4) + sR * nw)); // not 3
tBuffer.set(tIndex + 5, (float)(tBuffer.get(tIndex + 5) + sG * nw)); // not 4
tBuffer.set(tIndex + 6, (float)(tBuffer.get(tIndex + 6) + sB * nw)); // not 5
tBuffer.set(tIndex + 7, (float)(tBuffer.get(tIndex + 7) + sA * nw)); // not 6
} else if (crossY && !crossX) { // cross on Y only
w = wy * scale;
// add weighted component for current px
tBuffer.set(tIndex , (float)(tBuffer.get(tIndex) + sR * w));
tBuffer.set(tIndex + 1, (float)(tBuffer.get(tIndex + 1) + sG * w));
tBuffer.set(tIndex + 2, (float)(tBuffer.get(tIndex + 2) + sB * w));
tBuffer.set(tIndex + 3, (float)(tBuffer.get(tIndex + 3) + sA * w));
// add weighted component for next (tY+1) px
nw = nwy * scale;
tBuffer.set((int)Math.floor(tIndex + 4 * tw) , (float)(tBuffer.get((int)Math.floor(tIndex + 4 * tw)) + sR * nw)); // *4, not 3
tBuffer.set((int)Math.floor(tIndex + 4 * tw + 1), (float)(tBuffer.get((int)Math.floor(tIndex + 4 * tw + 1)) + sG * nw)); // *4, not 3
tBuffer.set((int)Math.floor(tIndex + 4 * tw + 2), (float)(tBuffer.get((int)Math.floor(tIndex + 4 * tw + 2)) + sB * nw)); // *4, not 3
tBuffer.set((int)Math.floor(tIndex + 4 * tw + 3), (float)(tBuffer.get((int)Math.floor(tIndex + 4 * tw + 3)) + sA * nw)); // *4, not 3
} else { // crosses both x and y : four target points involved
// add weighted component for current px
w = wx * wy;
tBuffer.set(tIndex , (float)(tBuffer.get(tIndex) + sR * w));
tBuffer.set(tIndex + 1, (float)(tBuffer.get(tIndex + 1) + sG * w));
tBuffer.set(tIndex + 2, (float)(tBuffer.get(tIndex + 2) + sB * w));
tBuffer.set(tIndex + 3, (float)(tBuffer.get(tIndex + 3) + sA * w));
// for tX + 1; tY px
nw = nwx * wy;
tBuffer.set(tIndex + 4, (float)(tBuffer.get(tIndex + 4) + sR * nw)); // same for x
tBuffer.set(tIndex + 5, (float)(tBuffer.get(tIndex + 5) + sG * nw));
tBuffer.set(tIndex + 6, (float)(tBuffer.get(tIndex + 6) + sB * nw));
tBuffer.set(tIndex + 7, (float)(tBuffer.get(tIndex + 7) + sA * nw));
// for tX ; tY + 1 px
nw = wx * nwy;
tBuffer.set((int)Math.floor(tIndex + 4 * tw) , (float)(tBuffer.get((int)Math.floor(tIndex + 4 * tw)) + sR * nw)); // same for mul
tBuffer.set((int)Math.floor(tIndex + 4 * tw + 1), (float)(tBuffer.get((int)Math.floor(tIndex + 4 * tw + 1)) + sG * nw));
tBuffer.set((int)Math.floor(tIndex + 4 * tw + 2), (float)(tBuffer.get((int)Math.floor(tIndex + 4 * tw + 2)) + sB * nw));
tBuffer.set((int)Math.floor(tIndex + 4 * tw + 3), (float)(tBuffer.get((int)Math.floor(tIndex + 4 * tw + 3)) + sA * nw));
// for tX + 1 ; tY +1 px
nw = nwx * nwy;
tBuffer.set((int)Math.floor(tIndex + 4 * tw + 4), (float)(tBuffer.get((int)Math.floor(tIndex + 4 * tw + 4)) + sR * nw)); // same for both x and y
tBuffer.set((int)Math.floor(tIndex + 4 * tw + 5), (float)(tBuffer.get((int)Math.floor(tIndex + 4 * tw + 5)) + sG * nw));
tBuffer.set((int)Math.floor(tIndex + 4 * tw + 6), (float)(tBuffer.get((int)Math.floor(tIndex + 4 * tw + 6)) + sB * nw));
tBuffer.set((int)Math.floor(tIndex + 4 * tw + 7), (float)(tBuffer.get((int)Math.floor(tIndex + 4 * tw + 7)) + sA * nw));
}
} // end for sx
} // end for sy
// create result canvas
Canvas resCV = Canvas.createIfSupported();
resCV.getCanvasElement().setWidth((int)Math.floor(tw));
resCV.getCanvasElement().setHeight((int)Math.floor(th));
Context2d resCtx = resCV.getContext2d();
ImageData imgRes = resCtx.getImageData(0, 0, tw, th);
CanvasPixelArray tByteBuffer = imgRes.getData();
// convert float32 array into a UInt8Clamped Array
int pxIndex = 0;
for (sIndex = 0, tIndex = 0; pxIndex < tw * th; sIndex += 4, tIndex += 4, pxIndex++) {
tByteBuffer.set(tIndex, (int)Math.ceil(tBuffer.get(sIndex)));
tByteBuffer.set(tIndex + 1, (int)Math.ceil(tBuffer.get(sIndex + 1)));
tByteBuffer.set(tIndex + 2, (int)Math.ceil(tBuffer.get(sIndex + 2)));
tByteBuffer.set(tIndex + 3, (int)Math.ceil(tBuffer.get(sIndex + 3)));
}
// writing result to canvas.
resCtx.putImageData(imgRes, 0, 0);
return resCV.getCanvasElement();
}
I am not sure how to write an expression like thit tY = 0 | ty in Java. I am also not sure if canvas.width(value); transforms into canvas.setCoordinateSpaceWidth(value);
Edit:
Is (0 | ty + scale) in JS is ((long)ty + scale) in Java?
What is the translation of
var sBuffer = cv.getContext('2d').getImageData(0, 0, sw, sh).data
is it CanvasPixelArray
CanvasPixelArray sBuffer = cv.getContext2d().getImageData(0, 0, sw, sh).getData()
Can someone help me with the translation?
Edit: It turns out that my Java code is very slow. I cannot run it in dev mode. In prod mode it is event slower than the JavaScript code. Why is this code slower?
0 | tY is rounding a JS Number (equivalent to a Java double) to an integer value; equivalent to Math.floor(tY) or (long) tY (int is too small for all integer values that can be expressed in a double, but might be OK in this specific case).
canvas.width maps to Canvas#getCoordinateSpaceWidth, as you can see in GWT sources.
Finally, new Float32Array(n) maps to TypedArrays.createFloat32Array.
I am doing a javafx visualisation application for 3d points. As I am new to javafx, I started from the tutorial provided in the oracle website:
http://docs.oracle.com/javase/8/javafx/graphics-tutorial/javafx-3d-graphics.htm#JFXGR256
The example above runs perfect on my Mac, But after adding more points, the mouse drag, which causes the camera to rotate and thus people can view the objects from different angle, became very slow and simply not applicable any more.
I currently have a data for a rabbit with about 40000 points:
The code I used to rotate camera:
cameraXform.ry.setAngle(cameraXform.ry.getAngle() - mouseDeltaX * MOUSE_SPEED * modifier * ROTATION_SPEED);
cameraXform.rx.setAngle(cameraXform.rx.getAngle() + mouseDeltaY * MOUSE_SPEED * modifier * ROTATION_SPEED);
which is the same as in the oracle example.
What I have tried:
set JVM flag -Djavafx.animation.fullspeed=true, this helped a bit, but not significant.
set JVM flag -Djavafx.autoproxy.disable=true, this did not help.
set Cache to true and CacheHint to Cache.SPEED, this did not make much difference.
create another thread to do the rotation, and sync back after calculation, this did not help neither.
Any help is appreciated.Thanks in advance!
Here is how I made a point cloud using tetrahedrons in a triangle mesh. seems to run faster than using spheres or squares. this code helped me scalafx google code
import java.util.ArrayList;
import javafx.scene.shape.TriangleMesh;
public class TetrahedronMesh extends TriangleMesh {
private ArrayList<Point3i> vertices;
private int[] facesLink;
public TetrahedronMesh(double length, ArrayList<Point3i> v) {
this.vertices = v;
if (length > 0.0) {
float[] points = new float[vertices.size() * 12];
int[] faces = new int[vertices.size() * 24];
facesLink = new int[vertices.size() * 4];
float[] texCoords = new float[vertices.size() * 12];
int vertexCounter = 0;
int primitiveCounter = 0;
int pointCounter = 0;
int facesCounter = 0;
int texCounter = 0;
for (Point3i vertex : vertices) {
vertex.scale(100);
points[primitiveCounter] = vertex.x;
points[primitiveCounter + 1] = (float) (vertex.y - (length
* Math.sqrt(3.0) / 3.0));
points[primitiveCounter + 2] = -vertex.z;
points[primitiveCounter + 3] = (float) (vertex.x + (length / 2.0));
points[primitiveCounter + 4] = (float) (vertex.y + (length
* Math.sqrt(3.0) / 6.0));
points[primitiveCounter + 5] = -vertex.z;
points[primitiveCounter + 6] = (float) (vertex.x - (length / 2.0));
points[primitiveCounter + 7] = (float) (vertex.y + (length
* Math.sqrt(3.0) / 6.0));
points[primitiveCounter + 8] = -vertex.z;
points[primitiveCounter + 9] = vertex.x;
points[primitiveCounter + 10] = vertex.y;
points[primitiveCounter + 11] = (float) -(vertex.z - (length * Math
.sqrt(2.0 / 3.0)));
faces[facesCounter] = pointCounter + 0;
faces[facesCounter + 1] = pointCounter + 0;
faces[facesCounter + 2] = pointCounter + 1;
faces[facesCounter + 3] = pointCounter + 1;
faces[facesCounter + 4] = pointCounter + 2;
faces[facesCounter + 5] = pointCounter + 2;
faces[facesCounter + 6] = pointCounter + 1;
faces[facesCounter + 7] = pointCounter + 1;
faces[facesCounter + 8] = pointCounter + 0;
faces[facesCounter + 9] = pointCounter + 0;
faces[facesCounter + 10] = pointCounter + 3;
faces[facesCounter + 11] = pointCounter + 3;
faces[facesCounter + 12] = pointCounter + 2;
faces[facesCounter + 13] = pointCounter + 2;
faces[facesCounter + 14] = pointCounter + 1;
faces[facesCounter + 15] = pointCounter + 1;
faces[facesCounter + 16] = pointCounter + 3;
faces[facesCounter + 17] = pointCounter + 4;
faces[facesCounter + 18] = pointCounter + 0;
faces[facesCounter + 19] = pointCounter + 0;
faces[facesCounter + 20] = pointCounter + 2;
faces[facesCounter + 21] = pointCounter + 2;
faces[facesCounter + 22] = pointCounter + 3;
faces[facesCounter + 23] = pointCounter + 5;
facesLink[pointCounter] = vertexCounter;
facesLink[pointCounter + 1] = vertexCounter;
facesLink[pointCounter + 2] = vertexCounter;
facesLink[pointCounter + 3] = vertexCounter;
texCoords[texCounter] = 0.5f;
texCoords[texCounter + 1] = 1.0f;
texCoords[texCounter + 2] = 0.75f;
texCoords[texCounter + 3] = (float) (1.0 - Math.sqrt(3.0) / 4.0);
texCoords[texCounter + 4] = 0.25f;
texCoords[texCounter + 5] = (float) (1.0 - Math.sqrt(3.0) / 4.0);
texCoords[texCounter + 6] = 1.0f;
texCoords[texCounter + 7] = 1.0f;
texCoords[texCounter + 8] = 0.5f;
texCoords[texCounter + 9] = (float) (1.0 - Math.sqrt(3.0) / 2.0);
texCoords[texCounter + 10] = 0.0f;
texCoords[texCounter + 11] = 1.0f;
vertexCounter++;
primitiveCounter += 12;
pointCounter += 4;
facesCounter += 24;
texCounter += 12;
}
getPoints().setAll(points);
getFaces().setAll(faces);
getTexCoords().setAll(texCoords);
// getFaceSmoothingGroups().setAll(0, 1, 2, 3);
}
}
public Point3i getPointFromFace(int faceId) {
return vertices.get(facesLink[faceId]);
}
}
Point3i code as follows
public class Point3i {
public int x;
public int y;
public int z;
public Point3i() {
x = 0;
y = 0;
z = 0;
}
}
Picking the point using the scene
scene.setOnMousePressed(new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent me) {
PickResult pr = me.getPickResult();
int faceId = pr.getIntersectedFace();
if (faceId != -1) {
Point3i p = tetrahedronMesh.getPointFromFace(faceId);
}
}
});
I know this is old, But for others ..
Instead of creating a new shape all together, each of the predefined shapes
Sphere, Box, Cylinder, allow you to set the number of divisions in the constructor.
Sphere for example defaults to 64 divisions, 32 for longitude, 32 for latitude.
you can easily do ... = new Sphere(radius, divisions); (4 is the minimum I believe for Sphere).
Something that helps a lot is to set the mouse transparent on the root with:
root3D.setMouseTransparent(true);
This obviously disables clicking or hovering on objects of the view (i.e PickResult is null). The solution for that is to temporarily enable it when there is a click for example and simulate another identical click with impl_processMouseEvent.
#Override
public void handle(MouseEvent event) {
try {
if (event.getEventType() == MouseEvent.MOUSE_CLICKED
&& event.isStillSincePress()
&& (event.getTarget() == scene3d || event.getTarget() instanceof Shape3D)) {
Parent root3D = scene3d.getRoot();
// if the 3D scene has been set to mouse transparent,
// then we send another event and we disable the transparency temporarily
if (root3D.isMouseTransparent()) {
root3D.setMouseTransparent(false);
try {
scene3d.impl_processMouseEvent(event);
}
finally {
root3D.setMouseTransparent(true);
}
}
else {
// here you get the pick result you need :)
}
}
}
catch (Exception e) {
e.printStackTrace();
}
}