/* * MindSun.java * * A View for GZZ 0.6.X. * * @author asko.soukka@iki.fi * @version 0.1 * * I was not satisfied with MindSundiew view. It wasted too much space * and still did not show enough information. So, I dropped using full circles. * Still this view is optimized for cyclic structures. * * Copyright (c) 2002 Asko Soukka * Contains a few parts of CompassView.java (c) 2002 Tuukka Hastrup * GZigZag is written by Tuomas Lukka * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * See the LICENSE.lgpl for the specific terms of the license. * * This library 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 * Library General Public License for more details. */ /* To do: Commenting code :) (javadoc-spesific) */ package org.gzigzag.module; import org.gzigzag.*; import java.awt.Color; import java.awt.Dimension; import java.awt.Point; import java.lang.Math; import java.util.Vector; class MindSun implements FlobView, ZOb { /** */ public static final String rcsid = "$Id: MindSun.java,v 1.1.2.3 2002/02/16 16:33:06 tuukkah Exp $"; public MindSun() {} /** * @param */ public String readParams(ZZCell c) { return null; }; /** * @param * @param * @param * @param * @param */ public void raster(FlobSet into, FlobFactory fact, ZZCell view, String[] dims, ZZCell accursed) { /** */ Dimension d = into.getSize(); int midx = d.width / 2; int midy = d.height / 2; int r = d.width / 5; /** */ ZZUtil.showFlobDims(into, fact, view, 3); /** */ Vector cells = getAllCells(dims[1], accursed); if (cells.size() > 0) { drawCircle(midx, midy, into, fact, dims[1], cells, r, 1, false); drawTopCurves(midx, midy, into, fact, dims, cells, r, 1.95 * Math.PI, 2, 4, true); drawSubCurves(midx, midy, into, fact, dims, cells, r, 0.95 * Math.PI, 2.95 * Math.PI, 2, 3, true); /** */ Dimension c = fact.getSize(null, 1); int cw = c.width; int ch = c.height; for (int i = 1; i < 4; i++) { if (accursed.s(dims[2], -i) != null) { fact.makeFlob(into, accursed.s(dims[2], -i), accursed.s(dims[2], -i), (float)0.75, midx + x(1.95 * Math.PI, r)-cw/2, midy+y(1.95 * Math.PI, r)-ch/2*(i+1), i+1, (int)(cw * 0.75), (int)(ch * 0.75)); } if (accursed.s(dims[2], i) != null) { fact.makeFlob(into, accursed.s(dims[2], i), accursed.s(dims[2], i), (float)0.75, midx + x(1.95 * Math.PI, r)-cw/2, midy+y(1.95 * Math.PI, r)-ch/3+ch/2*i, i+1, (int)(cw * 0.75), (int)(ch * 0.75)); } } } } /** * @param * @param */ private Vector getAllCells(String dim, ZZCell accursed) { /** */ int LIMIT = 20; /** */ Vector cells = new Vector(); /** */ ZZCell next = null; /** */ cells.addElement(accursed); /** */ int i = 1; do { if (cells.size() > LIMIT / 2) break; next = accursed.s(dim, i++); if(next != null && !cells.contains(next)) cells.addElement(next); else break; } while (true); /** */ i = -1; do { if (i < -LIMIT / 2) break; next = accursed.s(dim, i--); } while (next != null && !cells.contains(next)); /** */ if (next != accursed) { i += 2; do { if (cells.size() > LIMIT) break; next = accursed.s(dim, i++); if(next != null && !cells.contains(next)) cells.addElement(next); else break; } while (true); } /** */ return cells; } /** * @param * @param * @param * @param * @param * @param * @param * @param */ private void drawTopCurves(int midx, int midy, FlobSet into, FlobFactory fact, String[] dims, Vector cells, int r, double angle, int startLevel, int endLevel, boolean vanishing) { /** */ float factor = (float) (-Math.log(startLevel) / (-Math.log(startLevel)+2.7) + 1); /** */ double angleStep = 2 * Math.PI / cells.size(); /** */ for (int i=0; i= endAngle - angleStep / 3 * 2 || cells.size()%2 != 0 && angle >= endAngle) angle = (startAngle + (endAngle - startAngle) / 2) - (cells.size() - (i + 1)) * angleStep; } /** */ if (backup != null) cells.insertElementAt(backup, 0); } /** * @param * @param * @param * @param * @param * @param * @param * @param */ private void drawCurve(int midx, int midy, FlobSet into, FlobFactory fact, Vector cells, double startAngle, double endAngle, int r, int level, boolean vanishing) { /** */ Dimension c = fact.getSize(null, 1); int cw = c.width; int ch = c.height; /** */ double angle = startAngle + (endAngle - startAngle) / 2; /** */ int i = 0; ZZCell backup = null; /** */ if (cells.elementAt(0) != null && ((ZZCell)cells.elementAt(0)).getText().equals("")) { int dx = x(angle, r-cw/8); int dy = y(angle, r-cw/8); float factor = (float)-Math.log(level)/4+1; fact.makeFlob(into, (ZZCell)cells.elementAt(i), (ZZCell)cells.elementAt(i), factor, midx + dx-cw/2, midy+dy-ch/2, level+2, (int)(cw * factor), (int)(ch * factor)); backup = (ZZCell)cells.elementAt(0); cells.removeElementAt(0); } /** */ double angleStep; if (cells.size()%2 == 0) angleStep = (endAngle - startAngle) / (cells.size() + 1); else angleStep = (endAngle - startAngle) / cells.size(); /** */ while (i < cells.size()) { int dx = x(angle, r); int dy = y(angle, r); /** */ float factor; if (i == 0) factor = (float)(-Math.log(level)/4+1.1); else factor = (float)-Math.log(level)/4+1; if(cells.elementAt(i) != null) fact.makeFlob(into, (ZZCell)cells.elementAt(i), (ZZCell)cells.elementAt(i), factor, midx + dx-cw/2, midy+dy-ch/2, level, (int)(cw * factor), (int)(ch * factor)); /** */ if (vanishing) { if (i < cells.size() / 2) level ++; else if (i > cells.size() / 2) level --; } i++; /** */ angle += angleStep; if (cells.size()%2 == 0 && angle >= endAngle - angleStep / 3 * 2 || cells.size()%2 != 0 && angle >= endAngle) angle = (startAngle + (endAngle - startAngle) / 2) - (cells.size() - i) * angleStep; } /** */ if (backup != null) cells.insertElementAt(backup, 0); } /** * @param * @param * @param * @param * @param * @param * @param * @param */ private void drawCircle(int midx, int midy, FlobSet into, FlobFactory fact, String dim, Vector cells, int r, int level, boolean vanishing) { /** */ LineDecor.Builder line = new LineDecor.Builder(into, Color.red); line.startl(4, 1); /** */ Dimension c = fact.getSize(null, 1); int cw = c.width; int ch = c.height; /** */ double angleStep = 2 * Math.PI / cells.size(); double angle = (double) 1.95 * Math.PI; /** */ int i = 0; while (i < cells.size()) { int dx = x(angle, r); int dy = y(angle, r); /** */ float factor = (float)-Math.log(level)/4+1; if(cells.elementAt(i) != null) /* fact.centerFlob(into, (ZZCell)cells.elementAt(i), (ZZCell)cells.elementAt(i), factor, new Point(midx + dx-cw/2, midy+dy-ch/2), 0, 0, level);*/ fact.makeFlob(into, (ZZCell)cells.elementAt(i), (ZZCell)cells.elementAt(i), factor, midx + dx-cw/2, midy+dy-ch/2, level, (int)(cw * factor), (int)(ch * factor)); /** */ if (vanishing) { if (i < cells.size() / 2) level ++; else if (i > cells.size() / 2) level --; } /** */ angle += angleStep; /** */ if (cells.elementAt(i)!=null && cells.size() > 1) { if (((ZZCell)cells.elementAt(i)).s(dim, 1) == null) { line.l(midx+x(angle - angleStep / 2 - 0.01, r-ch)-cw/2, midy+y(angle - angleStep / 2 - 0.01, r-ch)-ch/2, midx+x(angle - angleStep / 2 - 0.01, r+ch)-cw/2, midy+y(angle - angleStep / 2 - 0.01, r+ch)-ch/2); line.l(midx+x(angle - angleStep / 2 + 0.01, r-ch)-cw/2, midy+y(angle - angleStep / 2 + 0.01, r-ch)-ch/2, midx+x(angle - angleStep / 2 + 0.01, r+ch)-cw/2, midy+y(angle - angleStep / 2 + 0.01, r+ch)-ch/2); } else if (i < cells.size() - 1) { if (((ZZCell)cells.elementAt(i)).s(dim, 1) != (ZZCell)cells.elementAt(i+1)) line.l(midx+x(angle - angleStep / 2, r-ch)-cw/2, midy+y(angle - angleStep / 2, r-ch)-ch/2, midx+x(angle - angleStep / 2, r+ch)-cw/2, midy+y(angle - angleStep / 2, r+ch)-ch/2); } else { if (((ZZCell)cells.elementAt(i)).s(dim, 1) != (ZZCell)cells.elementAt(0)) { line.l(midx+x(angle - angleStep / 2, r-ch)-cw/2, midy+y(angle - angleStep / 2, r-ch)-ch/2, midx+x(angle - angleStep / 2, r+ch)-cw/2, midy+y(angle - angleStep / 2, r+ch)-ch/2); line.l(midx+x(angle - angleStep / 2 + 0.01, r-ch)-cw/2, midy+y(angle - angleStep / 2 + 0.01, r-ch)-ch/2, midx+x(angle - angleStep / 2 + 0.01, r+ch)-cw/2, midy+y(angle - angleStep / 2 + 0.01, r+ch)-ch/2); } } } /** */ i++; } /** */ line.endl(); } protected int x(double angle, int length) { return (int)(Math.cos(angle) * length); } protected int y(double angle, int length) { return (int)(Math.sin(angle) * length); } }