package edu.hawaii.jmotif.performance.digits;
/*
* MooreNeighbor.java
*
* Created on 26 noiembrie 2005, 23:13
*
* To change this template, choose Tools | Options and locate the template under
* the Source Creation and Management node. Right-click the template and choose
* Open. You can then make changes to the template in the Source Editor.
*/
/**
*
* @author Strainu
*/
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Point;
import java.util.ArrayList;
import java.util.Arrays;
import javax.swing.JButton;
import javax.swing.JPanel;
public class MooreNeighbor extends javax.swing.JApplet {
private static double[] dat = {
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 87.0, 173.0, 162.0, 151.0, 76.0, 0.0, 11.0, 21.0, 87.0, 152.0, 152.0, 152.0, 152.0, 152.0, 173.0, 193.0, 214.0, 234.0, 143.0, 51.0, 26.0, 0.0, 0.0, 0.0, 0.0, 0.0, 15.0, 31.0, 112.0, 193.0, 182.0, 171.0, 111.0, 51.0, 61.0, 72.0, 124.0, 177.0, 177.0, 177.0, 177.0, 177.0, 193.0, 208.0, 223.0, 239.0, 163.0, 86.0, 43.0, 0.0, 0.0, 0.0, 0.0, 0.0, 53.0, 123.0, 197.0, 253.0, 252.0, 232.0, 215.0, 203.0, 209.0, 223.0, 239.0, 253.0, 254.0, 252.0, 253.0, 253.0, 253.0, 252.0, 255.0, 253.0, 235.0, 192.0, 96.0, 0.0, 0.0, 0.0, 20.0, 32.0, 121.0, 212.0, 246.0, 255.0, 255.0, 251.0, 249.0, 248.0, 250.0, 252.0, 254.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 254.0, 255.0, 254.0, 255.0, 238.0, 119.0, 0.0, 0.0, 0.0, 61.0, 123.0, 194.0, 249.0, 255.0, 254.0, 254.0, 254.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 255.0, 253.0, 253.0, 254.0, 253.0, 253.0, 253.0, 254.0, 255.0, 253.0, 126.0, 0.0, 0.0, 0.0, 102.0, 215.0, 248.0, 254.0, 255.0, 253.0, 253.0, 254.0, 255.0, 255.0, 251.0, 247.0, 246.0, 248.0, 250.0, 252.0, 253.0, 253.0, 253.0, 252.0, 253.0, 254.0, 255.0, 247.0, 124.0, 0.0, 0.0, 0.0, 117.0, 234.0, 255.0, 253.0, 255.0, 254.0, 254.0, 253.0, 251.0, 244.0, 223.0, 203.0, 198.0, 203.0, 222.0, 243.0, 251.0, 254.0, 254.0, 253.0, 255.0, 254.0, 255.0, 233.0, 117.0, 0.0, 0.0, 0.0, 56.0, 109.0, 189.0, 255.0, 255.0, 255.0, 236.0, 198.0, 140.0, 84.0, 55.0, 40.0, 27.0, 36.0, 100.0, 173.0, 222.0, 253.0, 255.0, 252.0, 255.0, 241.0, 170.0, 96.0, 48.0, 0.0, 0.0, 0.0, 23.0, 37.0, 133.0, 224.0, 238.0, 214.0, 158.0, 92.0, 43.0, 7.0, 0.0, 0.0, 0.0, 4.0, 95.0, 191.0, 234.0, 254.0, 255.0, 255.0, 247.0, 214.0, 112.0, 25.0, 13.0, 0.0, 0.0, 0.0, 8.0, 13.0, 88.0, 159.0, 166.0, 137.0, 70.0, 5.0, 0.0, 0.0, 0.0, 0.0, 30.0, 82.0, 166.0, 242.0, 255.0, 254.0, 255.0, 248.0, 211.0, 156.0, 70.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 42.0, 81.0, 80.0, 61.0, 29.0, 0.0, 0.0, 0.0, 0.0, 0.0, 93.0, 193.0, 235.0, 252.0, 255.0, 253.0, 242.0, 212.0, 138.0, 61.0, 21.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 7.0, 14.0, 14.0, 10.0, 5.0, 0.0, 0.0, 0.0, 15.0, 55.0, 153.0, 245.0, 255.0, 253.0, 255.0, 255.0, 199.0, 121.0, 57.0, 10.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, 0.0, 0.0, 71.0, 156.0, 216.0, 255.0, 255.0, 255.0, 239.0, 201.0, 118.0, 38.0, 7.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, 1.0, 20.0, 61.0, 153.0, 239.0, 255.0, 253.0, 255.0, 239.0, 173.0, 96.0, 35.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, 0.0, 0.0, 21.0, 116.0, 214.0, 246.0, 253.0, 255.0, 254.0, 224.0, 172.0, 81.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, 0.0, 0.0, 0.0, 45.0, 112.0, 188.0, 250.0, 255.0, 253.0, 255.0, 255.0, 175.0, 76.0, 25.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, 0.0, 0.0, 19.0, 104.0, 194.0, 236.0, 255.0, 255.0, 255.0, 236.0, 196.0, 104.0, 17.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, 0.0, 0.0, 25.0, 73.0, 162.0, 243.0, 255.0, 255.0, 255.0, 249.0, 175.0, 89.0, 32.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, 0.0, 0.0, 0.0, 70.0, 152.0, 211.0, 252.0, 255.0, 253.0, 246.0, 212.0, 103.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, 0.0, 0.0, 0.0, 0.0, 5.0, 120.0, 236.0, 255.0, 253.0, 255.0, 234.0, 150.0, 59.0, 17.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, 0.0, 0.0, 0.0, 41.0, 102.0, 188.0, 255.0, 255.0, 253.0, 238.0, 199.0, 95.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, 0.0, 0.0, 0.0, 0.0, 0.0, 95.0, 198.0, 238.0, 253.0, 255.0, 252.0, 200.0, 130.0, 54.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, 0.0, 0.0, 0.0, 0.0, 0.0, 99.0, 204.0, 242.0, 255.0, 255.0, 253.0, 149.0, 41.0, 7.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, 0.0, 0.0, 0.0, 15.0, 25.0, 130.0, 235.0, 255.0, 253.0, 255.0, 252.0, 191.0, 135.0, 159.0, 176.0, 91.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, 0.0, 49.0, 97.0, 180.0, 251.0, 255.0, 254.0, 255.0, 255.0, 225.0, 181.0, 150.0, 114.0, 53.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, 10.0, 10.0, 87.0, 174.0, 227.0, 255.0, 255.0, 255.0, 252.0, 231.0, 188.0, 130.0, 51.0, 0.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, 41.0, 41.0, 117.0, 193.0, 223.0, 252.0, 253.0, 253.0, 192.0, 130.0, 65.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, 0.0, 0.0, 0.0, 10.0, 10.0, 29.0, 48.0, 56.0, 63.0, 63.0, 63.0, 48.0, 33.0, 16.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, 0.0, 0.0, 0.0
};
/**
*
*/
private static final long serialVersionUID = -6506079731650980743L;
protected static final int STEP = 7;
private static final int THRESHOLD =1;
private static final int RUN_THRESHOLD = 150;
public CanvasMatrice canvas = new CanvasMatrice();
public JButton but = new JButton("Run MooreNeighbor");
/** Creates a new instance of RadialSweep */
public MooreNeighbor() {
}
public void paint(Graphics g) {
}
public void init() {
setSize(780, 300);
GridBagLayout grid = new GridBagLayout();
setLayout(grid);
canvas.setSize(600, 300);
canvas.addMouseListener(new Matrice(canvas));
// matrix
int[][] mat = canvas.m1;
for (int i = 0; i < dat.length; i++) {
int row = i % 28;
int col = i / 28;
if (dat[i] < THRESHOLD) {
mat[row][col] = 0;
}
else {
mat[row][col] = 1;
}
}
but.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
Integer[] chain = algoritm();
System.out.println(Arrays.toString(chain).replace("[", "").replace("]", "")
.replace(",", ""));
ArrayList<Double> curve = new ArrayList<Double>();
ArrayList<Double> curve2 = new ArrayList<Double>();
for (int i = 0; i < chain.length; i++) {
int[] forwardHist = null;
int[] backwardHist = null;
if (i >= STEP && i < chain.length - STEP) {
forwardHist = histogram(Arrays.copyOfRange(chain, i, i + STEP));
backwardHist = histogram(Arrays.copyOfRange(chain, i - STEP, i));
}
else if (i < STEP) {
forwardHist = histogram(Arrays.copyOfRange(chain, i, i + STEP));
backwardHist = histogram(glue(
Arrays.copyOfRange(chain, chain.length - (STEP - i), chain.length),
Arrays.copyOfRange(chain, 0, i)));
}
else if (i >= chain.length - STEP) {
forwardHist = histogram(glue(Arrays.copyOfRange(chain, i, chain.length),
Arrays.copyOfRange(chain, 0, STEP - (chain.length - i))));
backwardHist = histogram(Arrays.copyOfRange(chain, i - STEP, i));
}
double roi = roInverse(forwardHist, backwardHist);
curve.add(roi);
double ro2 = buildRo2(roi, forwardHist, backwardHist);
curve2.add(ro2);
}
System.out.println(Arrays.toString(curve.toArray(new Double[curve.size()]))
.replace("[", "").replace("]", ""));
System.out.println(Arrays.toString(curve2.toArray(new Double[curve2.size()]))
.replace("[", "").replace("]", ""));
}
private double buildRo2(double roi, int[] forwardHist, int[] backwardHist) {
int modF = mod(forwardHist);
int modG = mod(backwardHist);
int i1 = (modG + 1) % 8;
int i2 = (modG + 3) % 8;
int i3 = (modG - 1) % 8;
int i4 = (modG - 3) % 8;
int sign = 1;
// if (Math.min(i1, i2) <= modF && modF <= Math.max(i1, i2)) {
// sign = 1;
// }
if (modF == modG) {
return 0;
}
if (Math.min(i3, i4) <= modF && modF <= Math.max(i3, i4)) {
sign = -1;
}
return Math.abs(roi - 1) * sign;
}
private Integer[] glue(Integer[] arr1, Integer[] arr2) {
Integer[] res = new Integer[arr1.length + arr2.length];
for (int i = 0; i < arr1.length; i++) {
res[i] = arr1[i];
}
for (int i = 0; i < arr2.length; i++) {
res[i + arr1.length] = arr2[i];
}
return res;
}
private int mod(int[] hist) {
int resDirection = -1;
int maxVal = -1;
for (int i = 0; i < hist.length; i++) {
if (hist[i] > maxVal) {
resDirection = i;
maxVal = hist[i];
}
}
return resDirection;
}
private double roInverse(int[] forwardHist, int[] backwardHist) {
double meanForward = mean(forwardHist);
double meanBackward = mean(backwardHist);
double up = 0.;
double lowLeft = 0.;
double lowRight = 0.;
for (int i = 0; i < 8; i++) {
up = up + (forwardHist[i] - meanForward) * (backwardHist[i] - meanBackward);
lowLeft = lowLeft + (forwardHist[i] - meanForward) * (forwardHist[i] - meanForward);
lowRight = lowRight + (backwardHist[i] - meanBackward) * (backwardHist[i] - meanBackward);
}
return up / Math.sqrt(lowLeft * lowRight);
}
private double mean(int[] forwardHist) {
double res = 0.;
for (int i = 0; i < forwardHist.length; i++) {
res = res + (double) forwardHist[i];
}
return res / (double) forwardHist.length;
}
private int[] histogram(Integer[] array) {
int[] res = new int[8];
for (int i = 0; i < array.length; i++) {
res[array[i]]++;
}
return res;
}
});
// cream panoul pentru buton, ca sa nu ocupe toata zona
JPanel panou = new JPanel();
panou.setSize(200, 200);
panou.setAlignmentY(50);
panou.add(but);
// incepem sa descriem constrangerile
GridBagConstraints c = new GridBagConstraints();
// primu vine butonul, care ocupa o celula
c.gridx = 0;
c.gridy = 0;
c.gridwidth = 1;
grid.setConstraints(panou, c);
// apoi vine canvasul care ocupa 2 celule
c.gridx = 1;
c.gridwidth = 2;
grid.setConstraints(canvas, c);
add(panou);
add(canvas);
validate();
}
private int sum(int[] t) {
int res = 0;
for (int i = 0; i < t.length; i++) {
res = res + t[i];
}
return res;
}
/** ne deplasam prin matrice in jurul punctului p, incepand de la punctul prev */
private int deplasare(Point p, Point prev) {
int t[] = new int[8];
int start = 0, i = 0;
if (p.x == 0 && p.y != 0 && p.y != 27) {
t[0] = t[6] = t[7] = 0;
t[1] = canvas.m1[p.x][p.y - 1];
t[2] = canvas.m1[p.x + 1][p.y - 1];
t[3] = canvas.m1[p.x + 1][p.y];
t[4] = canvas.m1[p.x + 1][p.y + 1];
t[5] = canvas.m1[p.x][p.y + 1];
}
else if (p.x == 27 && p.y != 0 && p.y != 27) {
t[2] = t[3] = t[4] = 0;
t[0] = canvas.m1[p.x - 1][p.y - 1];
t[1] = canvas.m1[p.x][p.y - 1];
t[5] = canvas.m1[p.x][p.y + 1];
t[6] = canvas.m1[p.x - 1][p.y + 1];
t[7] = canvas.m1[p.x - 1][p.y];
}
else if (p.y == 0 && p.x != 0 && p.x != 27) {
t[0] = t[1] = t[2] = 0;
t[3] = canvas.m1[p.x + 1][p.y];
t[4] = canvas.m1[p.x + 1][p.y + 1];
t[5] = canvas.m1[p.x][p.y + 1];
t[6] = canvas.m1[p.x - 1][p.y + 1];
t[7] = canvas.m1[p.x - 1][p.y];
}
else if (p.y == 27 && p.x != 0 && p.x != 27) {
t[6] = t[5] = t[4] = 0;
t[0] = canvas.m1[p.x - 1][p.y - 1];
t[1] = canvas.m1[p.x][p.y - 1];
t[2] = canvas.m1[p.x + 1][p.y - 1];
t[3] = canvas.m1[p.x + 1][p.y];
t[7] = canvas.m1[p.x - 1][p.y];
}
else if (p.x == 0 && p.y == 0) {
t[0] = t[6] = t[7] = t[2] = t[1] = 0;
t[3] = canvas.m1[p.x + 1][p.y];
t[4] = canvas.m1[p.x + 1][p.y + 1];
t[5] = canvas.m1[p.x][p.y + 1];
}
else if (p.x == 0 && p.y == 27) {
t[0] = t[6] = t[7] = t[5] = t[4] = 0;
t[1] = canvas.m1[p.x][p.y - 1];
t[2] = canvas.m1[p.x + 1][p.y - 1];
t[3] = canvas.m1[p.x + 1][p.y];
}
else if (p.x == 27 && p.y == 0) {
t[0] = t[1] = t[2] = t[3] = t[4] = 0;
t[5] = canvas.m1[p.x][p.y + 1];
t[6] = canvas.m1[p.x - 1][p.y + 1];
t[7] = canvas.m1[p.x - 1][p.y];
}
else if (p.x == 27 && p.y == 27) {
t[6] = t[5] = t[4] = t[2] = t[3] = 0;
t[0] = canvas.m1[p.x - 1][p.y - 1];
t[1] = canvas.m1[p.x][p.y - 1];
t[7] = canvas.m1[p.x - 1][p.y];
}
else {
t[0] = canvas.m1[p.x - 1][p.y - 1];
t[1] = canvas.m1[p.x][p.y - 1];
t[2] = canvas.m1[p.x + 1][p.y - 1];
t[3] = canvas.m1[p.x + 1][p.y];
t[4] = canvas.m1[p.x + 1][p.y + 1];
t[5] = canvas.m1[p.x][p.y + 1];
t[6] = canvas.m1[p.x - 1][p.y + 1];
t[7] = canvas.m1[p.x - 1][p.y];
}
if (prev.x == p.x - 1 && prev.y == p.y - 1)
start = 0;
if (prev.x == p.x && prev.y == p.y - 1)
start = 1;
if (prev.x == p.x + 1 && prev.y == p.y - 1)
start = 2;
if (prev.x == p.x + 1 && prev.y == p.y)
start = 3;
if (prev.x == p.x + 1 && prev.y == p.y + 1)
start = 4;
if (prev.x == p.x && prev.y == p.y + 1)
start = 5;
if (prev.x == p.x - 1 && prev.y == p.y + 1)
start = 6;
if (prev.x == p.x - 1 && prev.y == p.y)
start = 7;
for (i = start + 1; i < 8; i++) {
if (t[i] == 1)
break;
}
if (i == 8)
for (i = 0; i <= start; i++)
if (t[i] == 1)
break;
/*
* prev.x=p.x; prev.y=p.y;
*/
if (i == 0) {
prev.x = p.x - 1;
prev.y = p.y;
p.x = p.x - 1;
p.y = p.y - 1;
}
if (i == 1) {
prev.x = p.x - 1;
prev.y = p.y - 1;
p.x = p.x;
p.y = p.y - 1;
}
if (i == 2) {
prev.x = p.x;
prev.y = p.y - 1;
p.x = p.x + 1;
p.y = p.y - 1;
}
if (i == 3) {
prev.x = p.x + 1;
prev.y = p.y - 1;
p.x = p.x + 1;
p.y = p.y;
}
if (i == 4) {
prev.x = p.x + 1;
prev.y = p.y;
p.x = p.x + 1;
p.y = p.y + 1;
}
if (i == 5) {
prev.x = p.x + 1;
prev.y = p.y + 1;
p.x = p.x;
p.y = p.y + 1;
}
if (i == 6) {
prev.x = p.x;
prev.y = p.y + 1;
p.x = p.x - 1;
p.y = p.y + 1;
}
if (i == 7) {
prev.x = p.x - 1;
prev.y = p.y + 1;
p.x = p.x - 1;
p.y = p.y;
}
return i;
}
/** algoritmul MooreNeighbor */
public Integer[] algoritm() {
boolean solutionFound = false;
int solutionCounter = 0;
ArrayList<Integer> chainCode = new ArrayList<Integer>(); // resulting chain code
do {
Point start = new Point();// punctul de inceput
Point prev_start = new Point();// punctul de inceput
Point prev = new Point();
Point p = new Point();// punctul curent
int orientare = 0;// {0,1,2,3} cu 0 -in sus;1-la dreapta, etc..
int i, j, dati = 0;
// golim matricea a doua
canvas.golire(2);
// gasesc punctul de inceput
chainCode = new ArrayList<Integer>(); // resulting chain code
for (i = 0; i < 28; i++) {
for (j = 27; j >= 0; j--)
if (canvas.m1[i][j] == 1) {
prev_start.x = prev.x = i;
prev_start.y = prev.y = j + 1;
start.x = p.x = i;
start.y = p.y = j;
System.out.println(p.x + " " + p.y + "\t" + prev.x + " " + prev.y);
canvas.m2[i][j] = 1;
canvas.repaint();
break;
}
if (j >= 0)
break;
}
/** cautam marginea desenului pana nu am ajuns in punctul de start din acelasi predecesor */
int codeCounter = 0;
do {
int direction = deplasare(p, prev);
chainCode.add(direction);
System.out.println(p.x + " " + p.y + "\t" + prev.x + " " + prev.y);
if (p.x == 6 && p.y == 20) {
System.out.println("gotcha");
}
canvas.m2[p.x][p.y] = 1;
Thread fir = new Thread(canvas);
fir.start();
try {
Thread.sleep(100);
}
catch (InterruptedException e) {
System.out.println("eroare");
}
codeCounter++;
if (codeCounter > RUN_THRESHOLD) {
break;
}
if ((p.x == start.x && p.y == start.y)
&& (prev.x != prev_start.x || prev.y != prev_start.y) && direction == 6) {
prev.x = p.x;
prev.y = p.y + 1;
}
}
while (p.x != start.x || p.y != start.y || prev.x != prev_start.x || prev.y != prev_start.y);
solutionFound = true;
if (codeCounter > RUN_THRESHOLD) {
solutionFound = false;
solutionCounter++;
canvas.m1 = rotate(canvas.m1);
canvas.golire(2);
canvas.repaint();
}
if (solutionCounter > 3) {
System.out.println("bummer!");
}
}
while (!(solutionFound));
/*
* lista1.clear(); lista2.clear();
*/
System.out.println("exit");
Integer[] chain = chainCode.toArray(new Integer[chainCode.size()]);
return chain;
}
private int[][] rotate(int[][] mat) {
int n = mat.length;
int m = mat[0].length;
int transpose[][] = new int[n][m];
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
transpose[i][j] = mat[j][m - i - 1];
}
}
return transpose;
}
}