package jadex.micro.examples.mandelbrot; import jadex.commons.Future; import jadex.commons.IFuture; import jadex.commons.service.BasicService; /** * Calculate service implementation. */ public class CalculateService extends BasicService implements ICalculateService { //-------- attributes -------- /** The agent. */ protected CalculateAgent agent; //-------- constructors -------- /** * Create a new service. */ public CalculateService(CalculateAgent agent) { super(agent.getServiceProvider().getId(), ICalculateService.class, null); this.agent = agent; } //-------- methods -------- /** * Calculate colors for an area of points. */ public IFuture calculateArea(AreaData data) { // System.out.println("calc: "+data.getId()+" "+agent.getComponentIdentifier()); agent.setHadJob(true); agent.setTaskId(data.getId()); // This code iterates over the area in a bounding boxes // If a complete bounding box has is in the set the rest // is just set to -1 without calculation. This is more // efficient for areas with 'much black'. Future ret = new Future(); double stepx = (data.getXEnd()-data.getXStart())/data.getSizeX(); double stepy = (data.getYEnd()-data.getYStart())/data.getSizeY(); int[][] res = new int[data.getSizeX()][data.getSizeY()]; int xstart = 0; int xend = data.getSizeX()-1; int ystart = 0; int yend = data.getSizeY()-1; boolean allin = true; boolean justfill = false; int fillcol = -2; boolean usejustfill = data.getXStart()<2 && data.getXStart()>-2 || data.getYStart()<2 && data.getYStart()>-2 || data.getXEnd()<2 && data.getXEnd()>-2 || data.getYEnd()<2 && data.getYEnd()>-2; int size = data.getSizeX()*data.getSizeY(); int cnt = 0; while(true) { if(xstart>xend) break; for(int xi=xstart; xi<=xend; xi++) { res[xi][ystart] = justfill? fillcol: determineColor(data.getXStart()+xi*stepx, data.getYStart()+ystart*stepy, data.getMax()); if(!justfill && xi==xstart) fillcol = res[xi][ystart]; if(allin && res[xi][ystart]!=fillcol) allin = false; cnt++; agent.setProgress(cnt*100/size); } ystart++; if(ystart>yend) break; for(int yi=ystart; yi<=yend; yi++) { res[xend][yi] = justfill? fillcol: determineColor(data.getXStart()+xend*stepx, data.getYStart()+yi*stepy, data.getMax()); if(allin && res[xend][yi]!=fillcol) allin = false; cnt++; agent.setProgress(cnt*100/size); } xend--; if(xstart>xend) break; for(int xi=xend; xi>=xstart; xi--) { res[xi][yend] = justfill? fillcol: determineColor(data.getXStart()+xi*stepx, data.getYStart()+yend*stepy, data.getMax()); if(allin && res[xi][yend]!=fillcol) allin = false; cnt++; agent.setProgress(cnt*100/size); } yend--; if(ystart>yend) break; for(int yi=yend; yi>=ystart; yi--) { res[xstart][yi] = justfill? fillcol: determineColor(data.getXStart()+xstart*stepx, data.getYStart()+yi*stepy, data.getMax()); if(allin && res[xstart][yi]!=fillcol) allin = false; cnt++; agent.setProgress(cnt*100/size); } xstart++; if(allin && usejustfill) { justfill = true; // System.out.println("justfill"+fillcol); allin = false; } else if(!justfill) { allin = true; } } agent.setTaskId(null); agent.setProgress(0); data.setData(res); ret.setResult(data); return ret; } // /** // * Calculate colors for an area of points. // */ // public IFuture calculateArea(AreaData data) // { //// System.out.println("calc: "+data); // // Future ret = new Future(); // // double stepx = (data.getXEnd()-data.getXStart())/data.getSizeX(); // double stepy = (data.getYEnd()-data.getYStart())/data.getSizeY(); // // int[][] res = new int[data.getSizeX()][data.getSizeY()]; // // for(int yi=0; yi<data.getSizeY(); yi++) // { // for(int xi=0; xi<data.getSizeX(); xi++) // { // res[xi][yi] = determineColor(data.getXStart()+xi*stepx, data.getYStart()+yi*stepy, data.getMax()); // } // } // // data.setData(res); // ret.setResult(data); // // return ret; // } /** * Determine the color of a point. */ protected int determineColor(double xn, double yn, int max) { double x0 = xn; double y0 = yn; int i = 0; double c = Math.sqrt(xn*xn + yn*yn); for(i=0; c<2 && i<max; i++) { double xn1 = xn*xn - yn*yn + x0; double yn1 = 2*xn*yn + y0; xn = xn1; yn = yn1; c = Math.sqrt(xn*xn + yn*yn); } return i==max? -1: i; } // /** // * // */ // public static void main(String[] args) // { // AreaData ad = new AreaData(0, 1, 0, 1, 5, 5, 3, 1, 1, null, null); // calculateArea(ad); // } }