/* ... */ import java.io.*; import java.applet.*; import java.awt.*; import java.awt.event.*; //CirclesPacking osztaly definicio public class CirclesPacking extends Applet implements Runnable { Graphics g; // a korok kozeppontjat tarolja a "virtualis" negyzetben Coordinate origos[]; //a kirajzolando korok kozeppontjait tarolja Coordinate realOrigos[]; //a legjobb eredmeny kozeppontjait tarolja Coordinate best[]; // a korok tulajdonsagait tarolja Circles circles; // a kezelofelulet elemeit tarolja CpControls controls; Thread CpThread = null; // a "virtuális" négyzet merete static final int wp=1000; // a mozgatas kezdeti merteke double step; // a mozgatas nagysagat ezzel osztom static final double div=1.5; // max ilyen kicsi lehet a mozgatas erteke static final double limit=0.01; // a korok aktualis teruletet tarolja double s; // az aktualis probalkozas szamat tarolja int t; // ebben a stringbe kerul a HTML fajbol atvett megfelelo parameter String bests; // igaz ha a Checkbox be van kapcsolva boolean view; //igaz ha az algoritmus fut boolean doing; // a korok tulajdonsagait tartalmazo osztaly public class Circles { int n; double r; int tr; public int getN() { return n; } public void setN(int n) { this.n=n; } public int getTr() { return tr; } public void setTr(int tr) { this.tr=tr; } public Circles(int n, int tr) { this.n=n; this.tr=tr; } public double getSurface() { if(n==1) { return (n*r*r*Math.PI); } else { return (n*r*r*Math.PI)/((wp+2*r)*(wp+2*r)); } } } // a korok kozeppontjait tarolo osztaly public class Coordinate { double x; double y; public Coordinate(double x, double y) { this.x=x; this.y=y; } } // a kezelofelulet elemeit tarolo osztaly public class CpControls extends Panel { TextField circlesN = new TextField(4); TextField circlesTr = new TextField(8); Checkbox view = new Checkbox(" Show me only the best results"); public CpControls() { add(new Label("Number of circles:")); add(circlesN); add(new Label("Number of try-outs:")); add(circlesTr); add(new Button(" Start ")); add(new Button(" Stop ")); add(view); setBackground(Color.white); } } // inicializalo fuggveny public void init() { g=getGraphics(); setLayout(new BorderLayout()); controls=new CpControls(); add("South", controls); setCircles(new Circles(9, 10)); bests="0.0"; s=0; t=0; view=true; doing=false; repaint(); } // a Start fuggveny public void start() { CpThread = new Thread(this); CpThread.start(); } // ezt hivja meg a Start public void run() { while(true) { if(doing==true) { examine(); doing=false; } try { Thread.sleep(100); } catch(InterruptedException e) { } } } // beallitja a circles objektum argumentumainak ertekeit public void setCircles(Circles circles) { this.circles=circles; controls.circlesN.setText(""+circles.getN()); controls.circlesTr.setText(""+circles.getTr()); } /* megvizsgalja es lekezeli a kulonleges eseteket, meghivja a pontok mozgatasaert felelos movePoints() metodust */ public void examine() { double r=0; origos = new Coordinate[circles.n]; realOrigos= new Coordinate[circles.n]; best= new Coordinate[circles.n]; if(circles.n==0) { s=0; repaint(); } if(circles.n==1) { circles.r=0.5; s=circles.getSurface(); repaint(); } else if(circles.n>1) { for(int i=1; i<=circles.tr; ++i) { if(doing==false) { break; } t=i; movePoints(); if(circles.r>r) { r=circles.r; s=circles.getSurface(); circlesDraw(best, 0); } } } } // veletlenszeruen elhelyezi a pontokat a "virtualis" negyzetben public void randomPoints() { double x,y; for(int i=0; i<=(circles.n-1); ++i) { x=wp*Math.random(); y=wp*Math.random(); origos[i] = new Coordinate(x, y); } } // a pontok mozgatasaert felelos metodus public void movePoints() { boolean moved; double closest; double distance; double x, y; step=200; randomPoints(); circles.r=(minimumDistance(origos)/2.0); if(circles.r==0.0) { do { randomPoints(); circles.r=(minimumDistance(origos)/2.0); } while(circles.r==0.0); } do { if(doing==false) { break; } moved=false; for(int i=0; i<=(circles.n-1); ++i) { x=origos[i].x; y=origos[i].y; closest=nearestNeighbour(origos, i, x, y); x=origos[i].x+step; if(x>wp) { x=wp; } distance=nearestNeighbour(origos, i, x, y); if(distance>closest) { origos[i].x=x; moved=true; closest=nearestNeighbour(origos, i, x, y); } x=origos[i].x-step; y=origos[i].y; if(x<0) { x=0; } distance=nearestNeighbour(origos, i, x, y); if(distance>closest) { origos[i].x=x; moved=true; closest=nearestNeighbour(origos, i, x, y); } y=origos[i].y+step; x=origos[i].x; if(y>wp) { y=wp; } distance=nearestNeighbour(origos, i, x, y); if(distance>closest) { origos[i].y=y; moved=true; closest=nearestNeighbour(origos, i, x, y); } y=origos[i].y-step; x=origos[i].x; if(y<0) { y=0; } distance=nearestNeighbour(origos, i, x, y); if(distance>closest) { origos[i].y=y; moved=true; } } if(moved==false ) { step/=div; } circles.r=(minimumDistance(origos)/2.0); circlesDraw(realOrigos, 370); } while(step>limit); } // az adott ponthoz legkozelebb levo pont tavolsagat adja vissza public double nearestNeighbour(Coordinate points[], int index, double a, double b) { double nearest; double dist; nearest=Math.sqrt(2*wp*wp); for(int j=0; j<=(circles.n-1); ++j) { if(index!=j) { dist=Math.sqrt(((a-points[j].x)*(a-points[j].x)) +((b-points[j].y)*(b-points[j].y))); if(dist=1 && (circles.n>1)) { d=(int) (minimumDistance(best)); for(int i=0; i<=(circles.n-1); ++i) { x=(int) (best[i].x+d/2); y=(int) (best[i].y+d/2); g.setColor(Color.yellow); g.fillOval(x-d/2, y-d/2, d, d); g.setColor(Color.black); g.drawOval(x-d/2, y-d/2, d, d); g.fillOval(x-2, y-2, 4, 4); } } if((t==circles.tr && view==true) && (circles.n>1)) { d=(int) (minimumDistance(realOrigos)); for(int i=0; i<=(circles.n-1); ++i) { x=(int) (realOrigos[i].x+d/2); y=(int) (realOrigos[i].y+d/2); g.setColor(Color.yellow); g.fillOval((x-d/2)+370, y-d/2, d, d); g.setColor(Color.black); g.drawOval((x-d/2)+370, y-d/2, d, d); g.fillOval((x-2)+370, y-2, 4, 4); } } } // lekezeli az esemenyeket public boolean action(Event e, Object arg) { Checkbox id; if(e.target instanceof Button) { String label=(String) arg; if (label.equals(" Start ")) { circles.setN( Integer.parseInt(controls.circlesN.getText())); circles.setTr( Integer.parseInt(controls.circlesTr.getText())); setCircles(circles); doing=true; } else { doing=false; } } if(e.target instanceof Checkbox) { id = (Checkbox) e.target; if(id.getLabel() == " Show me only the best results") { if(id.getState()) { view=false; } else { view=true; } } } return true; } }