Processing P3D sketch not working in Javascript mode - java

I Am trying to convert a project I've built in Processing [Java Mode] to be able to be viewed on the web.The project utilizes P3D rendering to display a 3D world that can be rotated and also can change 3 data sets (.tsv files) that map the location and size of earthquakes that occurred during three years. The following code works fine when ran in Java but when I run in Javascript mode I only get a blank gray screen. The HTML to embed the sketch into the canvas is correct and there are no errors so I am sure it is something within the code that that is not compatible with Javascript. Is there a way to just run the PDE as java without having to use Processing.js otherwise is there anything that is noticeably wrong with the code in regards to compatibility with processing.js?
Here is a link to the sketch that is not working if that helps .
Any suggestions as to what I should do is greatly appreciated. Thanks
float dial = 0.0;
FloatTable data;
FloatTable data2;
float dataMin, dataMax;
int rowCount;
int currentColumn = 0;
int columnCount;
int yearMin, yearMax;
int[] years;
int yearInterval = 10;
int volumeInterval = 10;
int volumeIntervalMinor=5;
PImage bg;
PImage texmap;
PFont font;
PImage img, img2;
PImage imgTitle;
int sDetail = 35; // Sphere detail setting
float rotationX = 0;
float rotationY = 0;
float velocityX = 0;
float velocityY = 0;
float globeRadius = 750;
float pushBack = 0;
float[] cx, cz, sphereX, sphereY, sphereZ;
float sinLUT[];
float cosLUT[];
float SINCOS_PRECISION = 0.5;
int SINCOS_LENGTH = int(360.0 / SINCOS_PRECISION);
void setup() {
size(1300,1000, P3D);
textSize(100);
texmap = loadImage("img/world32k.jpg");
initializeSphere(sDetail);
setupstuff("2011.tsv");
}
void draw() {
background(0);
// drawTitle();
drawMain();
renderGlobe();
drawDial();
}
void setupstuff(String filename){
data = new FloatTable(filename);
rowCount=data.getRowCount();
columnCount = data.getColumnCount();
years = int(data.getRowNames());
yearMin = years[0];
yearMax = years[years.length - 1];
font = loadFont("Univers-Bold-12.vlw");
dataMin = 0;
dataMax = ceil( data.getTableMax()/volumeInterval)*volumeInterval;
img = loadImage("img/dialface.jpg");
img2 = loadImage("img/dial.png");
imgTitle = loadImage("Title.png");
imageMode(CENTER);
}
void renderGlobe() {
pushMatrix();
translate(width * 0.33, height * 0.4, pushBack);
// pushMatrix();
noFill();
stroke(255,200);
strokeWeight(2);
smooth();
//popMatrix();
pointLight(201, 252, 276, width * 0.3, height * 0.2, 660);
pushMatrix();
rotateX( radians(-rotationX) );
rotateY( radians(180 - rotationY) );
fill(200);
noStroke();
textureMode(IMAGE);
texturedSphere(globeRadius, texmap);
popMatrix();
drawDots(0);
popMatrix();
rotationX += velocityX;
rotationY += velocityY;
velocityX *= 0.95;
velocityY *= 0.95;
// Implements mouse control (interaction will be inverse when sphere is upside down)
if(mousePressed){
velocityX += (mouseY-pmouseY) * 0.01;
velocityY -= (mouseX-pmouseX) * 0.01;
}
}
void initializeSphere(int res)
{
sinLUT = new float[SINCOS_LENGTH];
cosLUT = new float[SINCOS_LENGTH];
for (int i = 0; i < SINCOS_LENGTH; i++) {
sinLUT[i] = (float) Math.sin(i * DEG_TO_RAD * SINCOS_PRECISION);
cosLUT[i] = (float) Math.cos(i * DEG_TO_RAD * SINCOS_PRECISION);
}
float delta = (float)SINCOS_LENGTH/res;
float[] cx = new float[res];
float[] cz = new float[res];
// Calc unit circle in XZ plane
for (int i = 0; i < res; i++) {
cx[i] = -cosLUT[(int) (i*delta) % SINCOS_LENGTH];
cz[i] = sinLUT[(int) (i*delta) % SINCOS_LENGTH];
}
// Computing vertexlist vertexlist starts at south pole
int vertCount = res * (res-1) + 2;
int currVert = 0;
// Re-init arrays to store vertices
sphereX = new float[vertCount];
sphereY = new float[vertCount];
sphereZ = new float[vertCount];
float angle_step = (SINCOS_LENGTH*0.5f)/res;
float angle = angle_step;
// Step along Y axis
for (int i = 1; i < res; i++) {
float curradius = sinLUT[(int) angle % SINCOS_LENGTH];
float currY = -cosLUT[(int) angle % SINCOS_LENGTH];
for (int j = 0; j < res; j++) {
sphereX[currVert] = cx[j] * curradius;
sphereY[currVert] = currY;
sphereZ[currVert++] = cz[j] * curradius;
}
angle += angle_step;
}
sDetail = res;
}
// Draw texture sphere
void texturedSphere(float r, PImage t) {
int v1,v11,v2;
r = (r + 240 ) * 0.33;
beginShape(TRIANGLE_STRIP);
texture(t);
float iu=(float)(t.width-1)/(sDetail);
float iv=(float)(t.height-1)/(sDetail);
float u=0,v=iv;
for (int i = 0; i < sDetail; i++) {
vertex(0, -r, 0,u,0);
vertex(sphereX[i]*r, sphereY[i]*r, sphereZ[i]*r, u, v);
u+=iu;
}
vertex(0, -r, 0,u,0);
vertex(sphereX[0]*r, sphereY[0]*r, sphereZ[0]*r, u, v);
endShape();
// Middle rings
int voff = 0;
for(int i = 2; i < sDetail; i++) {
v1=v11=voff;
voff += sDetail;
v2=voff;
u=0;
beginShape(TRIANGLE_STRIP);
texture(t);
for (int j = 0; j < sDetail; j++) {
vertex(sphereX[v1]*r, sphereY[v1]*r, sphereZ[v1++]*r, u, v);
vertex(sphereX[v2]*r, sphereY[v2]*r, sphereZ[v2++]*r, u, v+iv);
u+=iu;
}
// Close each ring
v1=v11;
v2=voff;
vertex(sphereX[v1]*r, sphereY[v1]*r, sphereZ[v1]*r, u, v);
vertex(sphereX[v2]*r, sphereY[v2]*r, sphereZ[v2]*r, u, v+iv);
endShape();
v+=iv;
}
u=0;
// Add the northern cap
beginShape(TRIANGLE_STRIP);
texture(t);
for (int i = 0; i < sDetail; i++) {
v2 = voff + i;
vertex(sphereX[v2]*r, sphereY[v2]*r, sphereZ[v2]*r, u, v);
vertex(0, r, 0,u,v+iv);
u+=iu;
}
vertex(sphereX[voff]*r, sphereY[voff]*r, sphereZ[voff]*r, u, v);
endShape();
}
//draw dot
void drawDots(float r){
r = (r + 240 ) * 0.33;
blendMode(ADD);
stroke(255, 100, 0, 100);
rotateX( radians(-rotationX) );
rotateY( radians(270 - rotationY) );
for(int row = 0; row<rowCount; row++){
int col2 = 0;
int col3 = 1;
int col4 = 2;
float latY = data.getFloat(row, col2);
float longX = data.getFloat(row, col3);
float ricter = data.getFloat(row, col4);
pushMatrix();
rotateX(radians(-latY));
rotateY(radians(longX));
translate(0,0,r+250);
ellipse(0,0,ricter*ricter*ricter/20,ricter*ricter*ricter/20);
popMatrix();
println(latY);
}
rotationX += velocityX;
rotationY += velocityY;
velocityX *= 0.95;
velocityY *= 0.95;
}
void drawDial(){
translate(width-250, height-250);
image(img, -9/2, 53/2, 830/2,626/2 );
if(keyPressed){
if (key == '1') {
dial = radians( 0 );
setupstuff("2011.tsv");
}
if (key == '2') {
dial = radians( 120 );
setupstuff("2012.tsv");
}
if (key == '3') {
dial = radians( 240 );
setupstuff("2010.tsv");
}
}
rotate(dial);
image(img2, 103/2, -65/2, 314/2, 400/2);
}
void drawMain(){
image(imgTitle, width-320, 170);
}
void drawTitle(){
pushMatrix();
fill(255,255, 255);
translate(width-300, 120);
textFont(font, 32);
text("Earthquakes", 10, 50);
popMatrix();
}
class FloatTable {
int rowCount;
int columnCount;
float[][] data;
String[] rowNames;
String[] columnNames;
FloatTable(String filename) {
String[] rows = loadStrings(filename);
String[] columns = split(rows[0], TAB);
columnNames = subset(columns, 1); // upper-left corner ignored
scrubQuotes(columnNames);
columnCount = columnNames.length;
rowNames = new String[rows.length-1];
data = new float[rows.length-1][];
// start reading at row 1, because the first row was only the column headers
for (int i = 1; i < rows.length; i++) {
if (trim(rows[i]).length() == 0) {
continue; // skip empty rows
}
if (rows[i].startsWith("#")) {
continue; // skip comment lines
}
// split the row on the tabs
String[] pieces = split(rows[i], TAB);
scrubQuotes(pieces);
// copy row title
rowNames[rowCount] = pieces[0];
// copy data into the table starting at pieces[1]
data[rowCount] = parseFloat(subset(pieces, 1));
// increment the number of valid rows found so far
rowCount++;
}
// resize the 'data' array as necessary
data = (float[][]) subset(data, 0, rowCount);
}
void scrubQuotes(String[] array) {
for (int i = 0; i < array.length; i++) {
if (array[i].length() > 2) {
// remove quotes at start and end, if present
if (array[i].startsWith("\"") && array[i].endsWith("\"")) {
array[i] = array[i].substring(1, array[i].length() - 1);
}
}
// make double quotes into single quotes
array[i] = array[i].replaceAll("\"\"", "\"");
}
}
int getRowCount() {
return rowCount;
}
String getRowName(int rowIndex) {
return rowNames[rowIndex];
}
String[] getRowNames() {
return rowNames;
}
int getRowIndex(String name) {
for (int i = 0; i < rowCount; i++) {
if (rowNames[i].equals(name)) {
return i;
}
}
//println("No row named '" + name + "' was found");
return -1;
}
int getColumnCount() {
return columnCount;
}
String getColumnName(int colIndex) {
return columnNames[colIndex];
}
String[] getColumnNames() {
return columnNames;
}
float getFloat(int rowIndex, int col) {
if ((rowIndex < 0) || (rowIndex >= data.length)) {
throw new RuntimeException("There is no row " + rowIndex);
}
if ((col < 0) || (col >= data[rowIndex].length)) {
throw new RuntimeException("Row " + rowIndex + " does not have a column " + col);
}
return data[rowIndex][col];
}
boolean isValid(int row, int col) {
if (row < 0) return false;
if (row >= rowCount) return false;
//if (col >= columnCount) return false;
if (col >= data[row].length) return false;
if (col < 0) return false;
return !Float.isNaN(data[row][col]);
}
float getColumnMin(int col) {
float m = Float.MAX_VALUE;
for (int row = 0; row < rowCount; row++) {
if (isValid(row, col)) {
if (data[row][col] < m) {
m = data[row][col];
}
}
}
return m;
}
float getColumnMax(int col) {
float m = -Float.MAX_VALUE;
for (int row = 0; row < rowCount; row++) {
if (isValid(row, col)) {
if (data[row][col] > m) {
m = data[row][col];
}
}
}
return m;
}
float getRowMin(int row) {
float m = Float.MAX_VALUE;
for (int col = 0; col < columnCount; col++) {
if (isValid(row, col)) {
if (data[row][col] < m) {
m = data[row][col];
}
}
}
return m;
}
float getRowMax(int row) {
float m = -Float.MAX_VALUE;
for (int col = 0; col < columnCount; col++) {
if (isValid(row, col)) {
if (data[row][col] > m) {
m = data[row][col];
}
}
}
return m;
}
float getTableMin() {
float m = Float.MAX_VALUE;
for (int row = 0; row < rowCount; row++) {
for (int col = 0; col < columnCount; col++) {
if (isValid(row, col)) {
if (data[row][col] < m) {
m = data[row][col];
}
}
}
}
return m;
}
float getTableMax() {
float m = -Float.MAX_VALUE;
for (int row = 0; row < rowCount; row++) {
for (int col = 0; col < columnCount; col++) {
if (isValid(row, col)) {
if (data[row][col] > m) {
m = data[row][col];
}
}
}
}
return m;
}
}

UPDATE
Your error about Float might be related to this line:
return !Float.isNaN(data[row][col]);
Javascript is not going to recognize Float, that is a Java construct and not fully implemented within Processing. You need to find something else to make that comparison such as: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/NaN
Similarly all the statements like the following
float m = Float.MAX_VALUE;
are not going to work with ProcessingJS. You might want to look at: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Infinity
ProcessingJS is extremely difficult to debug so you need to make sure you avoid everything that is only Java and not fully implemented in Processing. You need to also avoid variable name clash. Read the following to get an idea about what else could go wrong: http://processingjs.org/articles/p5QuickStart.html#thingstoknowusingpjs
Also the following method does not have a closing brace:
float getTableMin() {
float m = Float.MAX_VALUE;
for (int row = 0; row < rowCount; row++) {
for (int col = 0; col < columnCount; col++) {
if (isValid(row, col)) {
if (data[row][col] < m) {
m = data[row][col];
}
}
}
}
return m;
Fix that by adding a closing brace like so:
float getTableMin() {
float m = Float.MAX_VALUE;
for (int row = 0; row < rowCount; row++) {
for (int col = 0; col < columnCount; col++) {
if (isValid(row, col)) {
if (data[row][col] < m) {
m = data[row][col];
}
}
}
}
return m;
}
This is why it helps to have properly formatted code. In your Processing IDE, select your code and then hit Ctrl-t, that should auto-format your code to something more easily readable.
By the way, your code wouldn't even run in Java mode without this fix. It will throw an unexpected token: float exception for the method in question.
UPDATE 2
To be able to get rid of your Float related code, you can change the following line
return !Float.isNaN(data[row][col]);
to
return isNaN(data[row][col]);
And you can change all instances of Float.MAX_VALUE; to Number.MAX_VALUE;.
After changing all the instances to Javascript friendly code, I too get the error you're getting. I will try to see if I can figure it out and update the answer.

Instead of using fullscreen() use this code:
size(window.innerWidth, window.innerHeight, P3D);
NOTE: Does not work in IE.
If IE:
void setup() {
if (window.innerWidth) {
wW = window.innerWidth;
wH = window.innerHeight;
} else {
var cW = document.body.offsetWidth;
var cH = document.body.offsetHeight;
window.resizeTo(500,500);
var barsW = 500 - document.body.offsetWidth;
var barsH = 500 - document.body.offsetHeight;
wW = barsW + cW;
wH = barsH + cH;
window.resizeTo(wW,wH);
}
size(wW,wH,P3D);
}

Related

Building Tic-Tac-Toe Board and am stuck on an infinite loop. Any Suggestions?

I am trying to make the board display alternating X's and O's on each square of the board and am having trouble not being able to stop the program from infinitely printing on the first space and switching markers. First I will show the class:
public class Board {
int cellsize = 4;
int cellsperrow = 3;
int rowsize = cellsize * cellsperrow;
public final char[] marker = new char [] {'X'};
public String boardRep = "___|___|___\n___|___|___\n | | ";
public final char [] [] board = new char[cellsperrow][cellsperrow];
public Board(){
for(int R = 0; R < board.length; ++R){
for(int C = 0; C < board[R].length; ++C){
board[R][C] = ' ';
}
}
}
boolean IsEmpty(int row, int col){
return board[row][col] == ' ';
}
public boolean markBoard(char marker, int row, int col){
if(!IsEmpty(row,col) || !isInRangeIndex(row,col)) {
boardRep = boardRep.substring(0, row*rowsize) + boardRep.substring(row*rowsize,(row*rowsize) + (col*cellsize) + 1) + marker + boardRep.substring((row*rowsize) + (col*cellsize) + 2, boardRep.length());
return false;
}
board[row][col] = marker;
return true;
}
boolean isInRange(int V){
return V >= 0 && V <= 2;
}
boolean isInRangeIndex(int r, int c){
return isInRange(r) && isInRange(c);
}
}
This is the Main:
Board B = new Board();
char [] markers = {'X','O'};
int marker = 0;
int numRows = 3;
int numCols = 3;
for(int row = 0; row < numRows; ++row){
for(int col = 0; col < numCols; ++col){
while(true){
System.out.println(B.boardRep);
B.markBoard(markers[marker],row,col);
marker = (marker + 1) %markers.length;
System.out.println(B.boardRep);
}
}
}
}
}
Any suggestions are appreciated. Thank you! I apologize if this is not formatted right I am newer to this and have never used this website before.

Pattern in a matrix with dot and hash

Find patterns in a given matrix.
I have a matrix with values '.' and '#'
Now I want to find count with the given pattern in the matrix :
a)
##
b)
#
#
For the above pattern, the cells if exist surrounding them should be '.'
I am able to create successful logic for it:
static int getMatches(String[] B, int m, int n) {
int count = 0;
boolean[][] flag = new boolean[m][n];
for (int i = 0; i < m; i++) {
String S = B[i];
for (int j = 0; j < n; j++) {
char c = S.charAt(j);
boolean valid = true;
if (c == '#' && flag[i][j] == false) {
if (j + 1 < n && S.charAt(j + 1) == '#' && flag[i][j + 1] == false) {
int[][] adj = { { 0, -1 }, { 0, 2 }, { -1, 0 }, { -1, 1 }, { 1, 0 }, { 1, 1 } };
valid = isValid(adj, i, j, m, n, B);
} else {
valid = false;
}
} else {
valid = false;
}
if (c == '#' && !valid && flag[i][j] == false) {
if (i + 1 < m && S.charAt(i + 1) == '#' && flag[i + 1][i] == false) {
int[][] adj = { { 0, -1 }, { 1, -1 }, { 1, 1 }, { 0, 1 }, { -1, 0 }, { 2, 0 } };
valid = isValid(adj, i, j, m, n, B);
} else {
valid = false;
}
}
flag[i][j] = true;
if (valid) {
count++;
}
}
}
return count;
}
static boolean isValid(int[][] adj, int i, int j, int m, int n, String[] B) {
for (int a = 0; a < adj.length; a++) {
int i1 = i + adj[a][0];
int j1 = j + adj[a][1];
if (i1 >= 0 && i1 < m) {
if (j1 >= 0 && j1 < n) {
char d = B[i1].charAt(j1);
if (d == '#') {
return false;
}
}
}
}
return true;
}
Now I want to change the pattern to 3 cells like this:
a)
###
b)
#
#
#
c)
##
#
d)
##
#
e)
#
##
f)
#
##
How to build logic for this? Is their a way to extend my above code or is there a better approach to solve this problem.
As far as I understand, the problem can be simplified to finding the adjacent # fields, and their area must match a certain number.
So I have created the following code:
public static int getMatches(String[] matrix, int m, int n, int patternArea) {
int count = 0;
for (int i = 0; i < m; i++) {
String row = matrix[i];
for (int j = 0; j < n; j++) {
char item = row.charAt(j);
if (item == '#' && countArea(matrix, i, j) + 1 == patternArea) {
count++;
}
}
}
return count;
}
private static int countArea( String[] matrix, final int i, final int j ) {
int area = 0;
setVisited(matrix, i,j);
if (matrix[Math.max(i-1, 0)].charAt(j) == '#') {
area += countArea(matrix, i-1, j) + 1;
}
if (matrix[Math.min(i+1, matrix.length-1)].charAt(j) == '#') {
area += countArea(matrix, i+1, j) + 1;
}
if (matrix[i].charAt(Math.max(j-1, 0)) == '#') {
area += countArea(matrix, i, j-1) + 1;
}
if (matrix[i].charAt(Math.min(j+1, matrix[0].length()-1)) == '#') {
area += countArea(matrix, i, j+1) + 1;
}
return area;
}
private static void setVisited( final String[] matrix, final int i, final int j ) {
char[] rowChars = matrix[i].toCharArray();
rowChars[j] = '0';
matrix[i] = String.valueOf(rowChars);
}
Explanation:
Find at least 1 # field
From that position, recursively find any adjacent # fields - countArea method
Always mark already visited fields - I chose 0, but any other char will do other than . and #
Finally, if the area is matching a given number (patternArea), increase count variable
This is working only, if you include all of the patterns for a certain number. Given your example, you did just that. In case you really want to do exact pattern matching, then this approach will not be useful for your case.
Shared solution should work with any matrix of any symbols and number of rows/columns
Let's assume next parameters that we'll have as our input:
Matrix is represented as two-dimensional array - matrix[r][c], where r - number of rows in matrix, c - number of columns in matrix
Matrix has all its cells filled with some symbols
Pattern is represented as two-dimensional array - arr[k][m], where k - number of rows in pattern, m - number of columns in pattern
Algorithm will iterate each column of each row in matrix
Pattern can potentially be present in cell[x][y] only if next conditions are met:
x + k <= r (there are enough of matrix rows below this one (including current row) to include number of pattern rows)
y + m <= c (there are enough of matrix columns right of this one (including current column) to include number of pattern columns)
Comparison of pattern to current matrix cells says that they are equal. Comparison in done based on next conditions:
if pattern character is null - continue comparison
if pattern character is equal to matrix character - continue comparison
if pattern character is not equal to matrix character - end comparison, pattern is not located in this cell
if all pattern symbols checked - pattern is found in given matrix cell
Result of comparison in represented in 0-based index pairs
Let's get to the code.
We will have next classes:
Pattern Rule - represents pattern to be found. please specify nulls manually to make actually 2-dimensional array of equal row/col count
private static final class PatternRule {
private final Character[][] pattern;
private final int rowCount;
private final int colCount;
private PatternRule(Character[][] pattern) {
this.pattern = pattern;
this.rowCount = pattern.length;
this.colCount = pattern[0].length;
}
public int getRowCount() {
return rowCount;
}
public int getColCount() {
return colCount;
}
public Character getCharacterAt(int row, int column) {
return pattern[row][column];
}
}
Found Pattern Location - class to represent found cells for pattern locations
private static final class FoundPatternLocation {
private final int rowIndex;
private final int colIndex;
private FoundPatternLocation(int rowIndex, int colIndex) {
this.rowIndex = rowIndex;
this.colIndex = colIndex;
}
#Override
public String toString() {
return "[" + rowIndex + "][" + colIndex + "]";
}
}
Matrix - class that creates matrix and performs search of pattern locations
private static final class Matrix {
private final Character[][] matrix;
private final int rowCount;
private final int colCount;
private Matrix(int rowCount, int colCount, Character[][] matrix) {
this.rowCount = rowCount;
this.colCount = colCount;
this.matrix = matrix;
}
public static Matrix createMatrix(int rowCount, int colCount, char[] matrixSymbols) {
Character[][] newMatrix = new Character[colCount][rowCount];
Random rand = new Random();
for (int rowIndex = 0; rowIndex < rowCount; rowIndex++) {
for (int colIndex = 0; colIndex < colCount; colIndex++) {
// select random char from allowed symbols
newMatrix[rowIndex][colIndex] = matrixSymbols[rand.nextInt(matrixSymbols.length)];
}
}
return new Matrix(rowCount, colCount, newMatrix);
}
public void printMatrix() {
System.out.println("---- Matrix -----");
for (int rowIndex = 0; rowIndex < rowCount; rowIndex++) {
List<String> rowValues = new ArrayList<>();
for (int colIndex = 0; colIndex < colCount; colIndex++) {
rowValues.add(String.valueOf(matrix[rowIndex][colIndex]));
}
String printableRowString = String.join(" ", rowValues);
System.out.println(printableRowString);
}
System.out.println("-----------------");
}
public List<FoundPatternLocation> findPatternLocations(PatternRule patternRule) {
List<FoundPatternLocation> actualPatternLocation = new ArrayList<>();
for (int rowNum = 0; rowNum < this.rowCount; rowNum++) {
for (int colNum = 0; colNum < this.colCount; colNum++) {
if (isPatternFittingToCurrentCell(rowNum, colNum, patternRule)) { // can pattern be located in this cell?
if (isPatternLocatedInCell(rowNum, colNum, patternRule)) { // is pattern actually located in this cell?
actualPatternLocation.add(new FoundPatternLocation(rowNum, colNum));
}
}
}
}
return actualPatternLocation;
}
private boolean isPatternFittingToCurrentCell(int matrixRowIndex, int matrixColIndex, PatternRule patternRule) {
int patternRowsCount = patternRule.getRowCount();
int patternColumnsCount = patternRule.getColCount();
int availableMatrixRowsForPattern = rowCount - matrixRowIndex;
int availableMatrixColsForPattern = colCount - matrixColIndex;
return patternRowsCount <= availableMatrixRowsForPattern && patternColumnsCount <= availableMatrixColsForPattern;
}
private boolean isPatternLocatedInCell(int rowNum, int colNum, PatternRule patternRule) {
int patternRowsCount = patternRule.getRowCount();
int patternColumnsCount = patternRule.getColCount();
for (int currentPatternRowIndex = 0; currentPatternRowIndex < patternRowsCount; currentPatternRowIndex++) {
for (int currentPatternColIndex = 0; currentPatternColIndex < patternColumnsCount; currentPatternColIndex++) {
int currentMatrixRowIndex = currentPatternRowIndex + rowNum;
int currentMatrixColIndex = currentPatternColIndex + colNum;
Character currentMatrixCharacter = matrix[currentMatrixRowIndex][currentMatrixColIndex];
Character currentPatternCharacter = patternRule.getCharacterAt(currentPatternRowIndex, currentPatternColIndex);
if (currentPatternCharacter == null) {
continue;
}
if (Objects.equals(currentMatrixCharacter, currentPatternCharacter)) {
continue;
}
return false;
}
}
return true;
}
}
Class to perform execution
public static void main(String[] args) {
int rowCount = 5;
int colCount = 5;
char[] matrixSymbols = new char[] {'✓', 'X'};
Matrix matrix = Matrix.createMatrix(rowCount, colCount, matrixSymbols);
matrix.printMatrix();
PatternRule patternRuleA = createPatternRuleA();
PatternRule patternRuleB = createPatternRuleB();
PatternRule patternRuleC = createPatternRuleC();
List<FoundPatternLocation> patternLocationsA = matrix.findPatternLocations(patternRuleA);
printPatternLocations(patternLocationsA, "Pattern A");
List<FoundPatternLocation> patternLocationsB = matrix.findPatternLocations(patternRuleB);
printPatternLocations(patternLocationsB, "Pattern B");
List<FoundPatternLocation> patternLocationsC = matrix.findPatternLocations(patternRuleC);
printPatternLocations(patternLocationsC, "Pattern C");
}
private static void printPatternLocations(List<FoundPatternLocation> patternLocations, String patternName) {
System.out.println("---- " + patternName + " ----");
String string = patternLocations.stream().map(FoundPatternLocation::toString).collect(Collectors.joining("; "));
System.out.println(string);
System.out.println("--------");
}
private static PatternRule createPatternRuleA() {
Character[][] chars = {
{'✓', '✓', '✓'}
};
return new PatternRule(chars);
}
private static PatternRule createPatternRuleB() {
Character[][] chars = {
{'✓'},
{'✓'},
{'✓'}
};
return new PatternRule(chars);
}
private static PatternRule createPatternRuleC() {
Character[][] chars = {
{'✓', '✓'},
{'✓', null}
};
return new PatternRule(chars);
}
Example of execution:
---- Matrix -----
✓ ✓ X ✓ X
✓ ✓ ✓ ✓ ✓
X X X X ✓
X ✓ X X ✓
X X ✓ ✓ ✓
-----------------
---- Pattern A ----
[1][0]; [1][1]; [1][2]; [4][2]
--------
---- Pattern B ----
[1][4]; [2][4]
--------
---- Pattern C ----
[0][0]
--------

find the best ratios to minimize the cost of the box ( 100 % ratio or less ) from multiple values

I have array of targets values and list of components need to pick the best ratio of each or some of it that make the final return ratio is 100 % or less and meet the targets array with minimum cost in java
here is the code that i tried to solve the problem with and it work correctly as i need but take so long time and need some optimization
inputs
InputMaxRates[] --the max possible rate that the final solution can have from the ith protect
inputMinRates[] --the min possible rate that the final solution can have from the ith protect if it included
valuesMatrix[][] --array of the values inside 100% in the ith protect
targetsArray[] --the target values that the final box need to cover
costOfTheProdects[] --the cost of 100% if the ith protect
IsRequired[] --boolen array to tell if the ith protect must be in the final box
output
array with size of input protects number with the best ratio of each / some of the protects that meet the targets with minimum cost
output must be array with total of 100 or less and if no possible solution return array with -1
anyone can help please here is my code
import java.util.Arrays;
import java.util.Vector;
import javax.swing.JOptionPane;
import javax.swing.JTable;
public class AISolver {
double InputMaxRates[], inputMinRates[] , costOfTheProdects[];
double targetsArray[];
double[] bestRatios = null;
double[] bestValues = null;
boolean IsRequired[];
double minPriceCost = 1000000000;
int minPriceMet = -1;
double[][] valuesMatrix;
int numberOfTargets = 9;//number of vectors
int numberOfRows = 0;
public AISolver(double[] InputMaxRates, double[] inputMinRates, double[][] valuesMatrix,
double[] targetsArray, boolean IsRequired[], double[] costOfTheProdects) {
this.InputMaxRates = InputMaxRates;
this.inputMinRates = inputMinRates;
this.valuesMatrix = valuesMatrix;
this.targetsArray = targetsArray;
this.costOfTheProdects = costOfTheProdects;
this.IsRequired = IsRequired;
numberOfTargets = targetsArray.length;
numberOfRows = inputMinRates.length;
}
int hitflag = 0;
private void checkTheVictor(Vector<Double> v) {
double[] thisRatioValues = getTheNewValues(v);
double thisRatioCost = calcCostFromRates(v);
int checkmet = checkMeetTargets(thisRatioValues);
if (checkmet > 0 && checkmet >= minPriceMet) {
if (checkmet > minPriceMet) {
//JOptionPane.showMessageDialog(dataTable, "Meet -> " + minPriceMet);
minPriceCost = 1000000000;
}
minPriceMet = checkmet;
if (checkmet == numberOfTargets) {
// JOptionPane.showMessageDialog(dataTable, "Meet -> " + minPriceMet + " cost = " + thisRatioCost);
// if (hitflag == 0) {
// minPriceCost = 1000000000;
// }
if (minPriceCost > thisRatioCost) {
minPriceCost = thisRatioCost;
bestRatios = new double[numberOfRows];
for (int i = 0; i < bestRatios.length; i++) {
try {
bestRatios[i] = v.get(i);
} catch (Exception e) {
bestRatios[i] = 0;
}
}
bestValues = new double[numberOfTargets];
for (int i = 0; i < thisRatioValues.length; i++) {
bestValues[i] = thisRatioValues[i];
}
}
}
}
}
public double[] bestRatioFinder(Vector<Double> v) {
if ((v.size() == numberOfRows && getRatesVectorSum(v) <= 100) || getRatesVectorSum(v) >= 100) {
checkTheVictor(v);
} else if (inputMinRates[v.size()] == InputMaxRates[v.size()]) {
v.add(inputMinRates[v.size()]);
bestRatioFinder(v);
} else {
//leave the prodect option
if (IsRequired[v.size()] == false) {
v.add(0.0);
// new Thread(() -> {
// Vector<Double> vt = new Vector<>();
// for (Double tx : v) {
// vt.add(tx);
// }
// bestRatioFinder(v);
// }).start();
bestRatioFinder(v);
v.removeElementAt(v.size() - 1);
}
//contune
Double maxPossibleRate = Math.min(101 - getRatesVectorSum(v), InputMaxRates[v.size()] + 1);
for (Double i = inputMinRates[v.size()]; i < maxPossibleRate; i++) {
v.add(i);
//System.out.println(Arrays.toString(v.toArray()));
// new Thread(() -> {
// Vector<Double> vt = new Vector<>();
// for (Double tx : v) {
// vt.add(tx);
// }
// bestRatioFinder(v);
// }).start();
bestRatioFinder(v);
v.removeElementAt(v.size() - 1);
}
}
return bestRatios;
}
private int getRatesVectorSum(Vector<Double> v) {
int sum = 0;
for (int i = 0; i < v.size(); i++) {
Double el = v.elementAt(i);
sum += el;
}
return sum;
}
private double calcCostFromRates(Vector<Double> v) {
double sum = 0;
for (int i = 0; i < v.size(); i++) {
Double el = v.elementAt(i);
double cost = costOfTheProdects[i];
sum += el * cost;
}
return sum;
}
private double[] getTheNewValues(Vector<Double> v) {
//need to update
double[] gvalus = new double[numberOfTargets];
for (int rowCounter = 0; rowCounter < v.size(); rowCounter++) {
Double el = v.elementAt(rowCounter);
for (int colCounter = 0; colCounter < numberOfTargets; colCounter++) {
Double cItemRatio = el;
double theCourntValueOfTheItem = valuesMatrix[rowCounter][colCounter];
double theValueToAdd = cItemRatio * theCourntValueOfTheItem / 100;
gvalus[colCounter] += theValueToAdd;
}
}
return gvalus;
}
private int checkMeetTargets(double[] ratvals) {
int met = 0;
for (int i = 0; i < ratvals.length; i++) {
if (ratvals[i] >= targetsArray[i]) {
met++;
}
}
return met;
}
}

OpenCL compression of binary data

I'd like to ask for your help if you're experience in OpenCL.
The task is so trivial, it's a shame I can't see what's wrong, but I couldn't solve this for 2 days now.
We have a binary 3D volume data stored in 2D slices. On the CPU side in Java, each slice is compressed into a bit array, that is, each slice's size is calculated as:
sliceSize = (width*height+31)/32;
The Java code for compressing slices from 1 byte/voxel to 1 int/32 voxels is:
hostUncompressed = new byte[depth * height * width];
hostCompressed = new int[depth * sliceSize];
deviceUncompressed = new byte[depth * height * width];
deviceCompressed = new int[depth * sliceSize];
int numOnes = 0;
int k = 0;
for (int i = 0; i < depth; ++i) {
for (int y = 0; y < height; ++y) {
for (int x = 0; x < width; ++x) {
hostUncompressed[k++] = (byte) (((int) (Math.random() * 1000)) % 2);
numOnes += (hostUncompressed[k - 1] == 1) ? 1 : 0;
}
}
}
for (int i = 0; i < depth; ++i) {
int start = i * sliceSize;
int index = start;
int targetIndex = 0;
int mask = 1;
int buffer = 0;
for (int y = 0; y < height; ++y) {
for (int x = 0; x < width; ++x) {
if (hostUncompressed[index] > 0) {
buffer |= mask;
}
++index;
if ((index & 31) == 0) {
hostCompressed[start + targetIndex++] = buffer;
buffer = 0;
mask = 1;
} else {
mask <<= 1;
}
}
}
}
My OpenCL port of it looks like this:
public void compress(cl_mem vol, int[] size3, int[] voxels) {
int totalCompressedSize = voxels.length;
cl_mem devCompressed = CL.clCreateBuffer(cl.getContext(),
CL.CL_MEM_WRITE_ONLY, Sizeof.cl_int * totalCompressedSize,
null, null);
int[] sliceSizeInts = new int[]{(size3[0] * size3[1] + 31) / 32};
int[] dimensions = new int[]{size3[0], size3[1], size3[2], 0};
long[] localWorkSize = new long[]{1, 1, 1};
long[] globalWorkSize = new long[]{sliceSizeInts[0], size3[2], 1};
cl.calcLocalWorkSize(globalWorkSize, localWorkSize);
CLUtils.round_size(localWorkSize, globalWorkSize);
int k = 0;
CL.clSetKernelArg(kernels[1], k++, Sizeof.cl_mem,
Pointer.to(devCompressed));
CL.clSetKernelArg(kernels[1], k++, Sizeof.cl_mem, Pointer.to(vol));
CL.clSetKernelArg(kernels[1], k++, Sizeof.cl_int4,
Pointer.to(dimensions));
CL.clEnqueueNDRangeKernel(cl.getCommandQueue(), kernels[1], 2, null,
globalWorkSize, localWorkSize, 0, null, null);
CL.clEnqueueReadBuffer(cl.getCommandQueue(), devCompressed, CL.CL_TRUE,
0, Sizeof.cl_int * totalCompressedSize, Pointer.to(voxels), 0,
null, null);
CL.clReleaseMemObject(devCompressed);
CL.clFinish(cl.getCommandQueue());
}
kernel void roiVolume_dataCompress(
global int* compressed,
global char* raw,
int4 dimensions) {
int comprSubId = get_global_id(0);
int sliceIndex = get_global_id(1);
int rawSliceSize = dimensions.y * dimensions.x;
int comprSliceSize = (rawSliceSize + 31)/32;
if ( sliceIndex < 0 || sliceIndex >= dimensions.z ||
comprSubId < 0 || comprSubId >= comprSliceSize )
return;
int rawIndex;
int rawSubIndex;
int value = 0;
for (int i = 0; i < 32; ++i)
{
rawSubIndex = comprSubId*32+i;
if ( rawSubIndex < rawSliceSize)
{
rawIndex = sliceIndex * rawSliceSize + rawSubIndex;
if (raw[rawIndex] != 0)
value |= (1 << i);
}
}
int comprIndex = sliceIndex * comprSliceSize + comprSubId;
compressed[comprIndex] = value;
}
It works if depth=1, so if executed only on one slice, but from the second slice it gets wrong and I can't see any pattern in the array that could help.
Any help would really be appreciated.
Thank you.

Image filter - Convolution

I am trying to implement image filter ( using convulution). I've spent all day trying to figure out what's going on and I cannot find a mistake. The filter works only when I use it to blur the image. In other cases it doesn't work properly: For example this is the original picture(before filtering):
And this is the picture after filtering with this matrix:
I use Marvin Image Processing Framework and jblas library in my code:
public class FiltrySploty extends MarvinAbstractImagePlugin {
#Override
public void load() {
}
#Override
public MarvinAttributesPanel getAttributesPanel() {
return null;
}
#Override
public void process(
MarvinImage imageIn,
MarvinImage imageOut,
MarvinAttributes attributesOut,
MarvinImageMask mask,
boolean previewMode) {
double norm=0;
DoubleMatrix filter = (DoubleMatrix)getAttribute("filter");
for ( int i = 0; i < filter.getRows();i++)
{
for ( int j = 0; j < filter.getColumns();j++)
{
norm=norm+filter.get(i, j);
}
}
int marginx = ((filter.getRows()-1)/2);
int marginy = ((filter.getColumns()-1)/2);
for (int x = marginx; x < imageIn.getWidth()-marginx; x++) {
for (int y = marginy; y < imageIn.getHeight()-marginy; y++) {
double SumRed=0;
double SumGreen=0;
double SumBlue=0;
for ( int i = x-marginx,k=0 ; k < filter.getRows();i++,k++)
{
for ( int j = y-marginy, l=0 ; l <filter.getColumns();j++,l++)
{
SumRed= SumRed+(filter.get(k, l)*imageIn.getIntComponent0(i, j));
SumGreen= SumGreen+(filter.get(k, l)*imageIn.getIntComponent1(i, j));
SumBlue= SumBlue+(filter.get(k, l)*imageIn.getIntComponent2(i, j));
}
}
SumRed = SumRed/norm;
SumGreen = SumGreen/norm;
SumBlue = SumBlue/norm; // normalization
if(SumRed>255.0) SumRed=255.0;
else if(SumRed<0.0) SumRed=0.0;
if(SumGreen>255.0) SumGreen=255.0;
else if(SumGreen<0.0) SumGreen=0.0;
if(SumBlue>255.0) SumBlue=255.0;
else if(SumBlue<0.0) SumBlue=0.0;
imageOut.setIntColor(x, y, (int)(SumRed), (int)(SumGreen), (int)(SumBlue));
}
}
}
}
Seeing the effect of filtering I suppose that the SumRed, SumGreen and SumBlue are out of range and they are setting to 255 or 0 values. But I have no idea why.

Categories