/* ManyToManyRaster.zob * * Copyright (c) 2000, Ted Nelson and Tuomas Lukka * * You may use and distribute under the terms of either the GNU Lesser * General Public License, either version 2 of the license or, * at your choice, any later version. Alternatively, you may use and * distribute under the terms of the XPL. * * See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of * the licenses. * * This software 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 README * file for more details. * */ /* * Written by Tuomas Lukka and Tuukka Hastrup */ package org.gzigzag; import java.awt.*; import java.awt.event.*; import java.util.*; public class ManyToManyView implements FlobView, ZOb { public static final String rcsid = "$Id$"; public static final boolean dbg = false; static final void p(String s) { if(dbg) System.out.println(s); } static final void pa(String s) { System.out.println(s); } // Following are the parameters out of which the constructor // is created. STRUCTPARAMS { /** The factor to shrink the cells with when moving away from * center. */ float[] shrink // 2..2 = new float[] {(float)0.75, (float)0.95}; /** The factor the center cell is enlarged with from default. */ float initmul = (float)1.0; /** The distance between neighbouring cells. */ int[] gap // 2..2 = new int[] {0, 0}; } public void raster(FlobSet into, FlobFactory fact, ZZCell view, String[] dims, ZZCell accursed) { Dimension fs = into.getSize(); Dimension maxsz = fact.getSize(null, initmul); // Calculate number of X and Y divisions. // There are two of each cell size. Go on until that is // too much. int nx = 0; float curl = maxsz.width; for(int xw = 0; xw <= fs.width - maxsz.width && curl>2; nx++) { xw += 2 * (int)curl; curl *= shrink[0]; } int ny = 0; curl = maxsz.height; for(int yw = 0; yw <= fs.height - maxsz.height && curl>2; ny++) { yw += 2 * (int)curl; curl *= shrink[1]; } nx *= 2; ny *= 2; ZZCell[][] grid = new ZZCell[nx][ny]; int[] xsz = new int[nx+1]; int[] ysz = new int[ny+1]; xsz[0] = maxsz.width / 2; xsz[1] = maxsz.width; ysz[0] = 2*maxsz.height; ysz[1] = maxsz.height; curl = maxsz.width; for(int i=0; i 0 && cur != null; x--) { ld.detect(cur); cur = cur.s(dims[0], -1); if(cur == xhead) break; grid[x][cy] = cur; } ld.reset(); cur = accursed; for(int y = cy-1; y > 0 && cur != null; y--) { ld.detect(cur); cur = cur.s(dims[1], -1); if(cur == yhead) break; grid[cx][y] = cur; } // Poswards ld.reset(); cur = accursed; for(int x = cx+1; x < nx && cur != null; x++) { ld.detect(cur); grid[x][cy] = cur = cur.s(dims[0], 1); } ld.reset(); cur = accursed; for(int y = cy+1; y < ny && cur != null; y++) { ld.detect(cur); grid[cx][y] = cur = cur.s(dims[1], 1); } // Other headcells for(int x = 1; x < nx; x ++) if(grid[x][cy] != null) { grid[x][0] = grid[x][cy].h(dims[1], -1); if(grid[x][0]!=null) heads.put(grid[x][0], new Integer(x)); } for(int y = 1; y < ny; y ++) if(grid[cx][y] != null) { ZZCell c = grid[0][y] = grid[cx][y].h(dims[0], -1); if(c!=null) heads.put(c, new Integer(0)); c = c.s(dims[0], 1); ld.reset(); while(c!=null) { // Show other intersections ld.detect(c); Integer xpos = (Integer)heads.get(c.h(dims[1], -1)); if(xpos!=null) grid[xpos.intValue()][y] = c; c = c.s(dims[0], 1); } } LineDecor.Builder bdline = new LineDecor.Builder(into, Color.red); bdline.startl(400, 1); // Find out which cells are shown Hashtable shown = new Hashtable(); for(int x = 0; x < nx; x++) { for( int y = 0; y < ny; y++) { if(grid[x][y]!=null) shown.put(grid[x][y], grid[x][y]); } } // Render the flobs for(int x = 0; x < nx; x ++) { for( int y = 0; y < ny; y ++) { if(grid[x][y] == null) continue; int xcoord = xsz[x]; int ycoord = ysz[y]; int width = xsz[x+1] - xcoord; int height = ysz[y+1] - ycoord; if(x != 0 && y != 0 && heads.get(grid[x][y])!=null) continue; Flob fl = fact.makeFlob(into, grid[x][y], grid[x][y], initmul * height / (float)maxsz.height, xcoord, ycoord, 1, width, height); /* if(x == 0 || y == 0) fl.flobPath="headcell";*/ // Place a red line if the neighbour isn't shown ZZCell c = grid[x][y]; for(int dx=-1;dx<=1;dx+=2) { ZZCell n = c.s(dims[0], dx); if(n!=null && shown.get(n)==null && (y!=0 || (x+dx>0 && x+dx0 && y+dy