Sebastian Rieger
7 years ago
3 changed files with 429 additions and 0 deletions
-
285VerteilteSysteme-Examples/src/verteiltesysteme/mandelbrot/rmi/MGuiRMI.java
-
14VerteilteSysteme-Examples/src/verteiltesysteme/mandelbrot/rmi/RMIMandelbrotCalculationsInterface.java
-
130VerteilteSysteme-Examples/src/verteiltesysteme/mandelbrot/rmi/RMIMandelbrotCalculationsServer.java
@ -0,0 +1,285 @@ |
|||||
|
package verteiltesysteme.mandelbrot.rmi; |
||||
|
|
||||
|
//Mandelbot Example A. Gepperth |
||||
|
|
||||
|
import java.awt.Color; |
||||
|
import java.awt.Graphics; |
||||
|
import java.awt.event.ActionEvent; |
||||
|
import java.awt.event.ActionListener; |
||||
|
import java.awt.event.MouseEvent; |
||||
|
import java.awt.event.MouseListener; |
||||
|
import java.awt.event.MouseMotionListener; |
||||
|
|
||||
|
import java.awt.image.BufferedImage; |
||||
|
import java.rmi.NotBoundException; |
||||
|
import java.rmi.RemoteException; |
||||
|
import java.rmi.registry.LocateRegistry; |
||||
|
import java.rmi.registry.Registry; |
||||
|
|
||||
|
import javax.swing.ImageIcon; |
||||
|
import javax.swing.JButton; |
||||
|
import javax.swing.JFrame; |
||||
|
import javax.swing.JLabel; |
||||
|
import javax.swing.JPanel; |
||||
|
import javax.swing.JSlider; |
||||
|
import javax.swing.event.ChangeEvent; |
||||
|
import javax.swing.event.ChangeListener; |
||||
|
|
||||
|
class MyJLabel extends JLabel { |
||||
|
|
||||
|
/** |
||||
|
* |
||||
|
*/ |
||||
|
private static final long serialVersionUID = -7750935382747799343L; |
||||
|
|
||||
|
int boxULx, boxULy, boxW, boxH; |
||||
|
|
||||
|
MyJLabel() { |
||||
|
super(); |
||||
|
} |
||||
|
|
||||
|
MyJLabel(String s) { |
||||
|
super(s); |
||||
|
} |
||||
|
|
||||
|
void setBox(int boxULx, int boxULy, int boxW, int boxH) { |
||||
|
this.boxULx = boxULx; |
||||
|
this.boxULy = boxULy; |
||||
|
this.boxW = boxW; |
||||
|
this.boxH = boxH; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
protected void paintComponent(Graphics g) { |
||||
|
super.paintComponent(g); |
||||
|
g.setColor(Color.black); |
||||
|
g.drawRect(this.boxULx, this.boxULy, this.boxW, this.boxH); |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
public class MGuiRMI implements ActionListener, ChangeListener, MouseListener, MouseMotionListener { |
||||
|
|
||||
|
// GUI elements |
||||
|
JFrame frame; |
||||
|
JPanel panel; |
||||
|
JButton endButton; |
||||
|
JButton backButton; |
||||
|
JButton calcButton; |
||||
|
JSlider maxIterations; |
||||
|
MyJLabel view; |
||||
|
int nrIterations; |
||||
|
|
||||
|
// box management |
||||
|
int boxULx, boxULy, boxW, boxH; |
||||
|
boolean dragging = false; |
||||
|
|
||||
|
// this one does all the calculating work |
||||
|
RMIMandelbrotCalculationsInterface remoteCalcObj; |
||||
|
|
||||
|
// how many points in the image? |
||||
|
// change if you want a higher resolution |
||||
|
public static final int RESX = 600; |
||||
|
public static final int RESY = 600; |
||||
|
|
||||
|
MGuiRMI() { |
||||
|
// set up GUI |
||||
|
this.frame = new JFrame("Mandelbrotmenge"); |
||||
|
this.panel = new JPanel(); |
||||
|
this.endButton = new JButton("Ende"); |
||||
|
this.panel.add(this.endButton); |
||||
|
this.backButton = new JButton("Zurueck"); |
||||
|
this.panel.add(this.backButton); |
||||
|
this.calcButton = new JButton("Rechnen"); |
||||
|
this.panel.add(this.calcButton); |
||||
|
this.frame.add(this.panel); |
||||
|
this.frame.setSize(500, 500); |
||||
|
this.frame.setVisible(true); |
||||
|
this.view = new MyJLabel("Platzhalter"); |
||||
|
this.maxIterations = new JSlider(0, 50, 30); |
||||
|
this.panel.add(this.maxIterations); |
||||
|
this.panel.add(this.view); |
||||
|
|
||||
|
this.endButton.addActionListener(this); |
||||
|
this.backButton.addActionListener(this); |
||||
|
this.calcButton.addActionListener(this); |
||||
|
this.maxIterations.addChangeListener(this); |
||||
|
|
||||
|
this.maxIterations.setMajorTickSpacing(10); |
||||
|
this.maxIterations.setPaintTicks(true); |
||||
|
this.maxIterations.setPaintLabels(true); |
||||
|
|
||||
|
this.view.addMouseListener(this); |
||||
|
this.view.addMouseMotionListener(this); |
||||
|
|
||||
|
this.boxULx = 0; |
||||
|
this.boxULy = 0; |
||||
|
this.boxW = MGuiRMI.RESX; |
||||
|
this.boxH = MGuiRMI.RESY; |
||||
|
|
||||
|
// Non-Gui stuff |
||||
|
String host = ""; |
||||
|
try { |
||||
|
Registry registry = LocateRegistry.getRegistry(host); |
||||
|
this.remoteCalcObj = (RMIMandelbrotCalculationsInterface) registry.lookup("RMIEchoInterface"); |
||||
|
} catch (RemoteException | NotBoundException e) { |
||||
|
// TODO Auto-generated catch block |
||||
|
e.printStackTrace(); |
||||
|
} |
||||
|
this.nrIterations = 1000; |
||||
|
} |
||||
|
|
||||
|
// visualization related stuff, do not touch! |
||||
|
int[] generateLookupTable(int nrHues) { |
||||
|
int[] tmp = new int[nrHues + 1]; |
||||
|
int cycle = 2048; |
||||
|
for (int i = 0; i < nrHues; i++) { |
||||
|
float hue = 1 * ((float) (i % cycle)) / cycle/* ((float)nrHues) */ ; |
||||
|
tmp[i] = Color.HSBtoRGB(hue, 0.8f, 1.0f); |
||||
|
} |
||||
|
tmp[0] = Color.HSBtoRGB(0f, 1.0f, 0.0f); |
||||
|
return tmp; |
||||
|
} |
||||
|
|
||||
|
// visualization |
||||
|
static void applyLookupTable(int[] data, int[] dest, int[] lookupTable) { |
||||
|
for (int i = 0; i < data.length; i++) { |
||||
|
dest[i] = lookupTable[data[i]]; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// here we check what the buttons do |
||||
|
public void actionPerformed(ActionEvent ae) { |
||||
|
if (ae.getSource() == this.endButton) { |
||||
|
System.out.println("Ende"); |
||||
|
System.exit(0); |
||||
|
} else |
||||
|
|
||||
|
if (ae.getSource() == this.backButton) { |
||||
|
System.out.println("Zurueck"); |
||||
|
double ULx = -0.16099999999999995; |
||||
|
double ULy = -0.9365333333333333; |
||||
|
double LRx = -0.03533333333333327; |
||||
|
double LRy = -0.8108666666666666; |
||||
|
this.boxULx = 0; |
||||
|
this.boxULy = 0; |
||||
|
this.boxW = MGuiRMI.RESX; |
||||
|
this.boxH = MGuiRMI.RESY; |
||||
|
this.view.setBox(this.boxULx, this.boxULy, this.boxW, this.boxH); |
||||
|
this.view.repaint(); |
||||
|
try { |
||||
|
this.remoteCalcObj.setView(ULx, ULy, LRx, LRy); |
||||
|
} catch (RemoteException e) { |
||||
|
// TODO Auto-generated catch block |
||||
|
e.printStackTrace(); |
||||
|
} |
||||
|
} else |
||||
|
|
||||
|
if (ae.getSource() == this.calcButton) { |
||||
|
System.out.println("Rechnen"); |
||||
|
long timestampStart = System.currentTimeMillis(); |
||||
|
|
||||
|
double ULx = 0; |
||||
|
double ULy = 0; |
||||
|
double LRx = 0; |
||||
|
double LRy = 0; |
||||
|
try { |
||||
|
ULx = this.remoteCalcObj.getULx(); |
||||
|
ULy = this.remoteCalcObj.getULy(); |
||||
|
LRx = this.remoteCalcObj.getLRx(); |
||||
|
LRy = this.remoteCalcObj.getLRy(); |
||||
|
} catch (RemoteException e) { |
||||
|
// TODO Auto-generated catch block |
||||
|
e.printStackTrace(); |
||||
|
} |
||||
|
double w = LRx - ULx; |
||||
|
double h = LRy - ULy; |
||||
|
ULx = ULx + w * this.boxULx / (double) MGuiRMI.RESX; |
||||
|
ULy = ULy + h * this.boxULy / (double) MGuiRMI.RESY; |
||||
|
w *= this.boxW / (double) (RESX); |
||||
|
h *= this.boxH / (double) (RESX); |
||||
|
LRx = ULx + w; |
||||
|
LRy = ULy + h; |
||||
|
System.out.println(ULx + "/" + ULy + "/" + LRx + "/" + LRy); |
||||
|
this.boxULx = 0; |
||||
|
this.boxULy = 0; |
||||
|
this.boxW = MGuiRMI.RESX; |
||||
|
this.boxH = MGuiRMI.RESY; |
||||
|
int[] colors = null; |
||||
|
try { |
||||
|
this.remoteCalcObj.setView(ULx, ULy, LRx, LRy); |
||||
|
this.remoteCalcObj.iterateAllPoints(this.maxIterations.getValue() * 1000, MGuiRMI.RESX, MGuiRMI.RESY); |
||||
|
int[] lookupTable = generateLookupTable(this.maxIterations.getValue() * 1000); |
||||
|
colors = new int[MGuiRMI.RESX * MGuiRMI.RESY]; |
||||
|
MGuiRMI.applyLookupTable(remoteCalcObj.getResult(), colors, lookupTable); |
||||
|
} catch (RemoteException e) { |
||||
|
// TODO Auto-generated catch block |
||||
|
e.printStackTrace(); |
||||
|
} |
||||
|
|
||||
|
BufferedImage colorImage = new BufferedImage(MGuiRMI.RESX, MGuiRMI.RESY, BufferedImage.TYPE_INT_ARGB); |
||||
|
colorImage.setRGB(0, 0, MGuiRMI.RESX, MGuiRMI.RESY, colors, 0, MGuiRMI.RESX); |
||||
|
this.view.setIcon(new ImageIcon(colorImage)); |
||||
|
|
||||
|
this.view.setBox(this.boxULx, this.boxULy, this.boxW, this.boxH); |
||||
|
this.view.repaint(); |
||||
|
|
||||
|
long timestampEnd = System.currentTimeMillis(); |
||||
|
|
||||
|
String timeElapsed = "Zeit: " + ((timestampEnd - timestampStart) / 1000.0) + " sec"; |
||||
|
System.out.println(timeElapsed); |
||||
|
this.view.setText(timeElapsed); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public void mousePressed(MouseEvent e) { |
||||
|
this.boxULx = e.getX(); |
||||
|
this.boxULy = e.getY(); |
||||
|
this.boxW = 1; |
||||
|
this.boxH = 1; |
||||
|
this.view.setBox(this.boxULx, this.boxULy, this.boxW, this.boxH); |
||||
|
} |
||||
|
|
||||
|
public void mouseDragged(MouseEvent e) { |
||||
|
this.boxW = e.getX() - this.boxULx + 1; |
||||
|
this.boxH = e.getY() - this.boxULy + 1; |
||||
|
int m = Math.min(boxW, boxH); |
||||
|
this.boxW = m; |
||||
|
this.boxH = m; |
||||
|
this.view.setBox(this.boxULx, this.boxULy, this.boxW, this.boxH); |
||||
|
this.view.repaint(); |
||||
|
} |
||||
|
|
||||
|
public void mouseReleased(MouseEvent e) { |
||||
|
|
||||
|
if (e.getButton() == MouseEvent.BUTTON1) { |
||||
|
this.view.repaint(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public void mouseMoved(MouseEvent e) { |
||||
|
} |
||||
|
|
||||
|
public void mouseExited(MouseEvent e) { |
||||
|
} |
||||
|
|
||||
|
public void mouseEntered(MouseEvent e) { |
||||
|
} |
||||
|
|
||||
|
public void mouseClicked(MouseEvent e) { |
||||
|
} |
||||
|
|
||||
|
// process a new slider value |
||||
|
public void stateChanged(ChangeEvent ce) { |
||||
|
if (ce.getSource() == this.maxIterations) { |
||||
|
//System.out.println("Neuer Wert"); |
||||
|
this.nrIterations = this.maxIterations.getValue() * 1000; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// main, just instantiate an MGui object, gives control to the Gui |
||||
|
public static void main(String[] args) { |
||||
|
@SuppressWarnings("unused") |
||||
|
MGuiRMI gui = new MGuiRMI(); |
||||
|
} |
||||
|
} |
@ -0,0 +1,14 @@ |
|||||
|
package verteiltesysteme.mandelbrot.rmi; |
||||
|
|
||||
|
import java.rmi.Remote; |
||||
|
import java.rmi.RemoteException; |
||||
|
|
||||
|
public interface RMIMandelbrotCalculationsInterface extends Remote { |
||||
|
void iterateAllPoints(int maxIterations, double nrPointsX, double nrPointsY) throws RemoteException; |
||||
|
public int[] getResult() throws RemoteException; |
||||
|
public double getULx() throws RemoteException; |
||||
|
public double getLRx() throws RemoteException; |
||||
|
public double getULy() throws RemoteException; |
||||
|
public double getLRy() throws RemoteException; |
||||
|
public void setView(double ULx, double ULy, double LRx, double LRy) throws RemoteException; |
||||
|
} |
@ -0,0 +1,130 @@ |
|||||
|
package verteiltesysteme.mandelbrot.rmi; |
||||
|
|
||||
|
import java.rmi.registry.LocateRegistry; |
||||
|
import java.rmi.registry.Registry; |
||||
|
import java.rmi.server.UnicastRemoteObject; |
||||
|
|
||||
|
class Complex { |
||||
|
double r; |
||||
|
double i; |
||||
|
|
||||
|
Complex() { |
||||
|
r = 0.0; |
||||
|
i = 0.0; |
||||
|
} |
||||
|
|
||||
|
Complex(double r, double i) { |
||||
|
this.r = r; |
||||
|
this.i = i; |
||||
|
} |
||||
|
|
||||
|
void mulBy(Complex other) { |
||||
|
double rTmp = this.r * other.r - this.i * other.i; |
||||
|
this.i = this.r * other.i + this.i * other.r; |
||||
|
this.r = rTmp; |
||||
|
} |
||||
|
|
||||
|
void add(Complex other) { |
||||
|
this.r += other.r; |
||||
|
this.i += other.i; |
||||
|
} |
||||
|
|
||||
|
void sub(Complex other) { |
||||
|
this.r -= other.r; |
||||
|
this.i -= other.i; |
||||
|
} |
||||
|
|
||||
|
double absValue() { |
||||
|
return Math.sqrt(this.r * this.r + this.i * this.i); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public class RMIMandelbrotCalculationsServer implements RMIMandelbrotCalculationsInterface { |
||||
|
public RMIMandelbrotCalculationsServer() {} |
||||
|
|
||||
|
public static void main(String args[]) { |
||||
|
|
||||
|
try { |
||||
|
RMIMandelbrotCalculationsServer obj = new RMIMandelbrotCalculationsServer(); |
||||
|
RMIMandelbrotCalculationsInterface stub = (RMIMandelbrotCalculationsInterface) UnicastRemoteObject.exportObject(obj, 0); |
||||
|
|
||||
|
// Bind the remote object's stub in the registry |
||||
|
Registry registry = LocateRegistry.getRegistry(); |
||||
|
registry.bind("RMIEchoInterface", stub); |
||||
|
|
||||
|
System.err.println("Server ready"); |
||||
|
} catch (Exception e) { |
||||
|
System.err.println("Server exception: " + e.toString()); |
||||
|
e.printStackTrace(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// hier wird das Ergebnis von iterateAll() gespeichert |
||||
|
protected int[] result = null; |
||||
|
|
||||
|
// der augenblicklich gewaehlte Ausschnitt |
||||
|
//double ULx = -2, ULy = -2, LRx = 2, LRy = 2; |
||||
|
double ULx = -0.16099999999999995, ULy = -0.9365333333333333, LRx = -0.03533333333333327, LRy = -0.8108666666666666; |
||||
|
|
||||
|
int iterateOnePoint(Complex c, int maxIterations, double maxModulus) { |
||||
|
Complex z = new Complex(0., 0.); |
||||
|
|
||||
|
for (int i = 0; i < maxIterations; i++) { |
||||
|
z.mulBy(z); |
||||
|
z.add(c); |
||||
|
double m = z.absValue(); |
||||
|
if (m > maxModulus) { |
||||
|
return i; |
||||
|
} |
||||
|
} |
||||
|
return maxIterations; |
||||
|
} |
||||
|
|
||||
|
public void iterateAllPoints(int maxIterations, double nrPointsX, double nrPointsY) { |
||||
|
|
||||
|
this.result = new int[(int) (nrPointsX * nrPointsY)]; |
||||
|
|
||||
|
int counter = 0; |
||||
|
double stepX = (this.LRx - this.ULx) / nrPointsX; |
||||
|
double stepY = (this.LRy - this.ULy) / nrPointsY; |
||||
|
double i = this.ULy; |
||||
|
for (int cy = 0; cy < nrPointsY; cy++) { |
||||
|
double r = this.ULx; |
||||
|
for (int cx = 0; cx < nrPointsX; cx++) { |
||||
|
Complex c = new Complex(r, i); |
||||
|
this.result[counter] = maxIterations - this.iterateOnePoint(c, maxIterations, 2.0); |
||||
|
counter += 1; |
||||
|
r += stepX; |
||||
|
} |
||||
|
i += stepY; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public int[] getResult() { |
||||
|
return this.result; |
||||
|
} |
||||
|
|
||||
|
public double getULx() { |
||||
|
return this.ULx; |
||||
|
} |
||||
|
|
||||
|
public double getLRx() { |
||||
|
return this.LRx; |
||||
|
} |
||||
|
|
||||
|
public double getULy() { |
||||
|
return this.ULy; |
||||
|
} |
||||
|
|
||||
|
public double getLRy() { |
||||
|
return this.LRy; |
||||
|
} |
||||
|
|
||||
|
public void setView(double ULx, double ULy, double LRx, double LRy) { |
||||
|
this.ULx = ULx; |
||||
|
this.ULy = ULy; |
||||
|
this.LRx = LRx; |
||||
|
this.LRy = LRy; |
||||
|
} |
||||
|
|
||||
|
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue