/** Orientierungsprogramm.java
* Written by Paul Bertram from the 10th of July to the 14th of July, 2006
* based on the programm "Superpredator" by Jürgen Hubert
*/
import java.awt.*;
import java.awt.color.*;
import java.awt.event.*;
import java.applet.*;
import java.math.*;
import java.util.*;
public class Orientierungsprogramm
extends Applet
implements ActionListener
{
TextField stepNrField;
TextField orientNrField;
TextField rateOrientField;
TextField abcField;
TextField festeWField;
TextField radiusField;
Random r = new Random();
double di= 0;
double p = 0; //Variablen werden erzeugt
double eAlt = 0;
double eNeu = 0;
double eDiff = 0;
double eAltb = 0;
double eNeub = 0;
double eDiffb = 0;
double b;
double l = Math.sqrt(2);
double festeW = 0;
double radius = 2;
int x,y;
int x_rel,y_rel;
int red, green, blue;
int q;
int w;
int ente;
int ergebnis;
int ergebnis2;
int xSize = 100;
int ySize = 100;
int xSizeb = 142;
int ySizeb = 142;
int a=4;
double[][] orient = new double [xSize][ySize];
double[][] orientNeu = new double[xSize][ySize];
double[][] orientSave = new double[xSize][ySize];
double[][] orientb = new double [xSizeb][ySizeb];
double[][] orientNeub = new double[xSizeb][ySizeb];
double[][] orientSaveb = new double[xSizeb][ySizeb];
int orientNr;
double stepNr;
int iterNr;
double rateOrient;
public void init() //initialize layout, calculate starting values
{
setLayout(null);
Button resetButton = new Button("Neu"); // erzeugt einen Button
resetButton.setBounds(20,430,100,40);
resetButton.addActionListener(this);
add(resetButton);
setLayout(null);
Button calculateButton = new Button("Rechnen"); // erzeugt einen Button
calculateButton.setBounds(130,430,100,40);
calculateButton.addActionListener(this);
add(calculateButton);
stepNrField = new TextField("1"); // erzeugt ein Textfeld
stepNrField.setBounds(100,480,100,40);
add(stepNrField);
orientNrField = new TextField("4"); // erzeugt ein Textfeld
orientNrField.setBounds(340,530,100,40);
add(orientNrField);
rateOrientField = new TextField("1"); // erzeugt ein Textfeld
rateOrientField.setBounds(100,530,100,40);
add(rateOrientField);
abcField = new TextField("0"); // erzeugt ein Textfeld
abcField.setBounds(340,480,100,40);
add(abcField);
festeWField = new TextField("0");
festeWField.setBounds(440,430,100,40);
add(festeWField);
radiusField = new TextField("1.5");
radiusField.setBounds(300,640,100,40);
add(radiusField);
orientNr = Integer.parseInt(orientNrField.getText()); // weist orientNr einen Wert zu
rateOrient = Double.parseDouble(rateOrientField.getText()); // weist rateOrient einen Wert zu
festeW = Double.parseDouble(festeWField.getText()); // weist festeW einen Wert zu
radius = Double.parseDouble(radiusField.getText()); // weist radius einen Wert zu
ResetValues();
repaint();
}
public void paint(Graphics g) //draw text and displays
{
g.drawString("Wahrscheinlichkeitswert :",280,450);
g.drawString("Schritte ;",10,510);
g.drawString("Orientierungen :",220,550);
g.drawString("O-wechsel :",10,550);
g.drawString("Aktueller Schritt: " + iterNr,460,510);
g.drawString("Zufallsstärke: ",220,510);
g.drawString("Radius : ",10,640);
for(x=0;x<xSize;x++) { // im folgendem werden den Orientierungen Farben zugewiesen
for(y=0;y<ySize;y++) {
if (orient[x][y] < 0.166666 ) {
blue = 255;
green = (int)((orient[x][y]*6.0)*255.0);
red = 0;
}
else if (orient[x][y] < 0.333334 ) {
blue = (int)((((0.33333)-orient[x][y])*6.0)*255.0);
green = 255;
red = 0;
}
else if (orient[x][y] < 0.5 ) {
blue = 0;
green = 255;
red = (int)(-((orient[x][y]-(0.5))*6.0)*255.0);
}
else if (orient[x][y] < 0.66666 ) {
blue = 0;
green = (int)((((0.66666)-orient[x][y])*6.0)*255.0);
red = 255;
}
else if (orient[x][y] < 0.833334 ) {
blue = (int)(-((orient[x][y]-(0.83333))*6.0)*255.0);
green = 0;
red = 255;
}
else if (orient[x][y] <= 1.0) {
blue = 255;
green = 0;
red = (int)(((1.0-orient[x][y])*6.0)*255.0);
}
g.setColor(new Color(red,green,blue));
g.fillRect(x*a,y*a,a,a); // hier wird gemalt
}
}
for(x=0;x<xSizeb;x++) { // im folgendem werden den Orientierungen Farben zugewiesen
for(y=0;y<ySizeb;y++) {
for(ente=0;ente<=71;ente++){
ergebnis = (x-ente)+(y-ente);
if(ergebnis!=70 && ergebnis!=71){
}
else{
ergebnis2=x+y;
if(ergebnis2!=213){
if((x-ente)>0 && (y-ente)>0){
if (orientb[x][y] < 0.166666 ) {
blue = 255;
green = (int)((orientb[x][y]*6.0)*255.0);
red = 0;
}
else if (orientb[x][y] < 0.333334 ) {
blue = (int)((((0.33333)-orientb[x][y])*6.0)*255.0);
green = 255;
red = 0;
}
else if (orientb[x][y] < 0.5 ) {
blue = 0;
green = 255;
red = (int)(-((orientb[x][y]-(0.5))*6.0)*255.0);
}
else if (orientb[x][y] < 0.66666 ) {
blue = 0;
green = (int)((((0.66666)-orientb[x][y])*6.0)*255.0);
red = 255;
}
else if (orientb[x][y] < 0.833334 ) {
blue = (int)(-((orientb[x][y]-(0.83333))*6.0)*255.0);
green = 0;
red = 255;
}
else if (orientb[x][y] <= 1.0) {
blue = 255;
green = 0;
red = (int)(((1.0-orientb[x][y])*6.0)*255.0);
}
g.setColor(new Color(red,green,blue));
g.fillRect(600+x*a,y*a,a,a); // hier wird gemalt
}
}
}
}
}
}
}
public void actionPerformed(ActionEvent event) //react to buttons
{
int i;
int x, y;
boolean calculate, reset;
calculate = event.getActionCommand().equals("Rechnen");
reset = event.getActionCommand().equals("Neu");
if(calculate) {
rateOrient = Double.parseDouble(rateOrientField.getText()); // Variabeln werden eingelesene Werte zugewiesen
stepNr = Integer.parseInt(stepNrField.getText());
b = Double.parseDouble(abcField.getText());
festeW = Double.parseDouble(festeWField.getText()); // weist festeW einen Wert zu
radius = Double.parseDouble(radiusField.getText());
iterNr +=stepNr;
for(i=1;i<=stepNr;i++) {
CalculateStep(); // es wird gerechnet
}
repaint();
}
if(reset) {
orientNr = Integer.parseInt(orientNrField.getText());
rateOrient = Double.parseDouble(rateOrientField.getText());
b = Double.parseDouble(abcField.getText());
festeW = Double.parseDouble(festeWField.getText());
radius = Double.parseDouble(radiusField.getText());
ResetValues();
repaint();
}
}
void CalculateStep()
{
int x, y;
for(x=0;x<xSizeb;x++){
for(y=0;y<ySizeb;y++){
UpdateZelle(x,y);
}
}
for(x=0;x<xSizeb;x++){
for(y=0;y<ySizeb;y++){
if(x<xSize && y<ySize) orient[x][y] = orientSave[x][y];
orientb[x][y] = orientSaveb[x][y];
}
}
}
void UpdateZelle(int x, int y)
{
eAlt=0;
eNeu=0;
int radi, w2, q2;
radi = (int) Math.floor(radius);
if(x<xSize){
if(y<ySize){
orientNeu[x][y] = Math.floor(GetRandom()*((double)orientNr))/((double)orientNr); // eine zufällige neue Orientierung wird gewählt
for(q=x-radi;q<=x+radi;q++){
q2 = q;
if(q2<0) q2 += xSize;
if(q2>=xSize) q2 -= xSize;
for(w=y-radi;w<=y+radi;w++){
w2 = w;
if(w2<0) w2 += ySize;
if(w2>=ySize) w2 -= ySize;
if((q!=x) || (w!=y)) {
di = Math.sqrt(Math.pow(Math.abs(q-x), 2)+Math.pow(Math.abs(w-y), 2)) ;
if(di<=radius){
eAlt = eAlt + (Math.abs(Math.sin((orient[q2][w2]-orient[x][y])*Math.PI)))/di ;
eNeu = eNeu + (Math.abs(Math.sin((orient[q2][w2]-orientNeu[x][y])*Math.PI)))/di ;
}
}
}
}
eDiff = eNeu - eAlt; //Berechnung der Energie-Differrenz
p = rateOrient*(1-Math.pow(Math.E, eDiff)) + b*GetRandom2(); //Berechnung der Wahrscheinlichkeit, dass die Orientierung sich ändert
if(festeW != 0) {
if(p > festeW){
orientSave[x][y] = orientNeu[x][y]; //Neue Orientierung
}
else orientSave[x][y] = orient[x][y]; //Alte Orientierung
}
else {
if(p > GetRandom()) {
orientSave[x][y] = orientNeu[x][y]; //Neue Orientierung
}
else orientSave[x][y] = orient[x][y]; //Alte Orientierung
}
}
}
// Feld B
/*
eAltb=0;
eNeub=0;
w2=0;
q2=0;
radi = (int) Math.floor(radius);
orientNeub[x][y] = Math.floor(GetRandom()*((double)orientNr))/((double)orientNr); // eine zufällige neue Orientierung wird gewählt
for(q=x-radi;q<=x+radi;q++){
q2 = q;
if(q2<0) q2 += xSizeb;
if(q2>=xSizeb) q2 -= xSizeb;
for(w=y-radi;w<=y+radi;w++){
w2 = w;
if(w2<0) w2 += ySizeb;
if(w2>=ySizeb) w2 -= ySizeb;
if((q!=x) || (w!=y)) {
di = Math.sqrt(Math.pow(Math.abs(q-x), 2)+Math.pow(Math.abs(w-y), 2)) ;
if(di<=radius){
eAltb = eAltb + (Math.abs(Math.sin((orient[q2][w2]-orient[x][y])*Math.PI)))/di ;
eNeub = eNeub + (Math.abs(Math.sin((orient[q2][w2]-orientNeu[x][y])*Math.PI)))/di ;
}
}
}
}
eDiffb = eNeub - eAltb; //Berechnung der Energie-Differrenz
p = rateOrient*(1-Math.pow(Math.E, eDiff)) + b*GetRandom2(); //Berechnung der Wahrscheinlichkeit, dass die Orientierung sich ändert
if(festeW != 0) {
if(p > festeW){
orientSaveb[x][y] = orientNeub[x][y]; //Neue Orientierung
}
else orientSaveb[x][y] = orientb[x][y]; //Alte Orientierung
}
else {
if(p > GetRandom()) {
orientSaveb[x][y] = orientNeub[x][y]; //Neue Orientierung
}
else orientSaveb[x][y] = orientb[x][y]; //Alte Orientierung
}
*/
}
void ResetValues()
{
int x, y;
iterNr = 0;
for(x=0;x<xSize;x++) {
for(y=0;y<ySize;y++) {
orient[x][y] = Math.floor(GetRandom()*((double)orientNr))/((double)orientNr); //den Zellen werden
// Orientierungen zugewiesen
}
}
for(x=0;x<xSizeb;x++) {
for(y=0;y<ySizeb;y++) {
for(ente=0;ente<=71;ente++){
ergebnis = (x-ente)+(y-ente);
if(ergebnis!=70 && ergebnis!=71){
}
else{
ergebnis2=x+y;
if(ergebnis2!=213){
if((x-ente)>0 && (y-ente)>0){
orientb[x][y] = Math.floor(GetRandom()*((double)orientNr))/((double)orientNr); //den Zellen werden
// Orientierungen zugewiesen
}
}
}
}
}
}
}
double GetRandom()
{
double ranVal = Math.abs(Math.random());
return ranVal - Math.floor(ranVal); // Eine Zahl zwischen 0 und 1 wird ausgewürfelt
}
double GetRandom2()
{
return GetRandom()*2-1; // Eine Zahl zwischen -1 und 1 wird ausgewürfelt
}
}