/* * File : HolesMaker.java * Created : 22-oct-2001 12:00 * By : fbusquets * * JClic - Authoring and playing system for educational activities * * Copyright (C) 2000 - 2005 Francesc Busquets & Departament * d'Educacio de la Generalitat de Catalunya * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details (see the LICENSE file). */ package edu.xtec.jclic.shapers; import java.awt.Shape; import java.awt.geom.*; /** * * @author Francesc Busquets (fbusquets@xtec.cat) * @version 13.08.28 */ public class HolesMaker { Holes h; int nx, ny; boolean[][] flagDone; int nIds; int[][] ids; int[] newIds; Rectangle2D.Double r; boolean skipOnes; boolean singleCells; public HolesMaker(int setNx, int setNy, int[] setIds, boolean useIds, boolean skipOnes, boolean singleCells){ this.skipOnes=skipOnes; this.singleCells=singleCells; nx=setNx; ny=setNy; h=new Holes(nx, ny); flagDone=new boolean[nx][ny]; ids=new int[nx][ny]; for(int y=0; y<ny; y++) for(int x=0; x<nx; x++){ flagDone[x][y]=false; ids[x][y]=setIds[y*nx+x]; } nIds=0; newIds=new int[nx*ny]; h.scaleW=nx; h.scaleH=ny; r=new Rectangle2D.Double(0,0,1,1); ShapeData[] shapeDataX=new ShapeData[nx*ny]; int j=0; for(int y=0; y<ny; y++) for(int x=0; x<nx; x++){ if(!flagDone[x][y] && ids[x][y]>=0){ Area a=scan(null, x, y); Shape sh=a; if(a.isRectangular()) sh=a.getBounds2D(); shapeDataX[j]=ShapeData.getShapeData(sh, null); shapeDataX[j].scaleTo(nx, ny); j++; } } if(!useIds){ int maxId=0; for(int i=0; i<j; i++) if(newIds[i]>maxId) maxId=newIds[i]; int nCells=maxId+1; h.nCells=nCells; h.shapeData=new ShapeData[nCells]; for(int i=0; i<nCells; i++){ int k; for(k=0; k<j; k++) if(newIds[k]==i) break; if(k==j){ // should not happen! h.shapeData[i]=shapeDataX[0]; System.err.println("HolesMaker error buliding shape for cell: "+i); } else h.shapeData[i]=shapeDataX[k]; } } else{ h.nCells=j; h.shapeData=new ShapeData[j]; System.arraycopy(shapeDataX, 0, h.shapeData, 0, j); } h.nCols=nx; h.nRows=ny; h.enclosingShapeData=ShapeData.getShapeData(new Rectangle2D.Double(0, 0, 1, 1), null); } public Holes getShaper(){ return h; } public int[] getIds(){ int[]result=new int[nIds]; System.arraycopy(newIds, 0, result, 0, nIds); return result; } protected Area scan(Area a, int xx, int y){ int id=ids[xx][y]; for(int x=xx; x<nx; x++){ if(flagDone[x][y] || ids[x][y]!=id) break; flagDone[x][y]=true; r.x=x; r.y=y; if(a==null){ a=new Area(r); newIds[nIds++]=id; } else a.add(new Area(r)); if(singleCells || (skipOnes && id==1)) break; if(x>0 && !flagDone[x-1][y] && ids[x-1][y]==id) scan(a, x-1, y); if(y>0 && !flagDone[x][y-1] && ids[x][y-1]==id) scan(a, x, y-1); if(y<(ny-1) && !flagDone[x][y+1] && ids[x][y+1]==id) scan(a, x, y+1); } return a; } }