/* * Copyright 2011 Uwe Krueger. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.mandelsoft.mand.util; import java.awt.Dimension; import java.io.File; import java.math.BigDecimal; import java.util.HashSet; import java.util.Set; import com.mandelsoft.io.AbstractFile; import com.mandelsoft.mand.MandelAreaSpec; import com.mandelsoft.mand.MandelData; import com.mandelsoft.mand.MandelInfo; import com.mandelsoft.mand.MandelName; import com.mandelsoft.mand.QualifiedMandelName; import com.mandelsoft.mand.scan.ContextMandelScanner; import com.mandelsoft.mand.scan.MandelHandle; import com.mandelsoft.mand.scan.MandelScanner; import com.mandelsoft.mand.scan.MandelScannerUtils; import java.io.IOException; /** * * @author Uwe Krueger */ public class MandUtils extends MandArith { static public final int PRECISION=3; static public int toInt(double d) { return (int)Math.round(d); } static public int toInt(long l) { return (int)l; } static public String time(int d) { int h=d/3600; d=d%3600; int m=d/60; d=d%60; if (h!=0) return h+":"+m+":"+d; return m+":"+d; } public static MandelName lookupRoot(MandelScanner scan, MandelAreaSpec spec) { return lookupRoot(scan,MandelName.ROOT,spec); } public static MandelName lookupRoot(MandelScanner scan, MandelName mn, MandelAreaSpec spec) { MandelName found=null; MandelData md; while (mn!=null) { found=mn; MandelName s=mn.sub(); while (s!=null) { //System.out.println("checking "+s); try { MandelHandle handle=scan.getMandelInfo(s); if (handle!=null) { md=handle.getInfo(); if (md!=null) { MandelInfo info=md.getInfo(); if (info!=null) { if (info.contains(spec.getXM(), spec.getYM())) { if (spec.getDX().compareTo(info.getDX())<0 ||spec.getDY().compareTo(info.getDY())<0) { break; } if (info.isSameArea(spec)) return s; } } } } } catch (IOException ex) { // just try next } s=s.next(); } mn=s; } return found; } public static MandelHandle lookupColormap(MandelScanner scan, MandelName n) { MandelHandle cm=null; MandelHandle mc=null; //always prefer explicit areacm MandelHandle mb=null; //then base (non-variant) areas System.out.println("lookup colormap for "+n); while (cm==null && n!=null) { Set<MandelHandle> set=scan.getMandelHandles(n); if (set!=null) { for (MandelHandle h:set) { if (h.getHeader().hasColormap()) { System.out.println("---- found cm "+h.getName()); cm=h; if (h.getHeader().isAreaColormap()) { System.out.println(" ----> area cm"); mc=h; } if (h.getName().getQualifier()==null) { System.out.println(" ----> base cm"); mb=h; if (mc==h) break; } } } // for set } n=n.getParentName(); } if (mc!=null) return mc; if (mb!=null) return mb; return cm; } public static File mapFile(AbstractFile f, String dstSuf, File d) { String n=f.getName(); if (!n.endsWith(dstSuf)) { int ix=n.lastIndexOf('.'); if (ix>=0) n=n.substring(0,ix)+dstSuf; else n=n+dstSuf; } if (d!=null) return new File(d,n); else { if (f.isFile()) return new File(f.getFile().getParentFile(),n); return null; } } public static File mapToRasterName(AbstractFile f) { return mapFile(f,RASTER_SUFFIX,null); } public static File mapToInfoName(AbstractFile f) { return mapFile(f,INFO_SUFFIX,null); } public static File mapToRasterImageName(AbstractFile f) { return mapFile(f,RASTERIMAGE_SUFFIX,null); } public static File mapToImageName(AbstractFile f) { return mapFile(f,IMAGE_SUFFIX,null); } public static File mapToRasterFile(AbstractFile f, File target) { return mapFile(f,RASTER_SUFFIX, target); } public static File mapToInfoFile(AbstractFile f, File target) { return mapFile(f,INFO_SUFFIX, target); } public static File mapToRasterImageFile(AbstractFile f, File target) { return mapFile(f,RASTERIMAGE_SUFFIX, target); } public static File mapToImageFile(AbstractFile f, File target) { return mapFile(f,IMAGE_SUFFIX, target); } static public Set<MandelName> getSubNames(MandelName n, Set<MandelName> set) { Set<MandelName> sub=new HashSet<MandelName>(); for (MandelName s:set) { if (n.equals(s.getParentName())) sub.add(s); } return set; } static public boolean hasSubNames(MandelName n, Set<MandelName> set) { for (MandelName s:set) { if (n.equals(s.getParentName())) return true; } return false; } public static Set<MandelName> getSubNames(MandelName n, MandelScanner scan) { if (scan instanceof ContextMandelScanner) { return ((ContextMandelScanner)scan).getSubNames(n); } else { return MandelScannerUtils.getSubNames(n, null, scan); } } public static boolean hasSubNames(MandelName n, MandelScanner scan) { if (scan instanceof ContextMandelScanner) { return ((ContextMandelScanner)scan).hasSubNames(n); } else { return MandelScannerUtils.hasSubNames(n, null, scan); } } public static boolean hasSubNames(MandelName n, MandelScanner scan, MandelScanner.Filter f) { if (scan instanceof ContextMandelScanner) { return ((ContextMandelScanner)scan).hasSubNames(n,f); } else { return MandelScannerUtils.hasSubNames(n, null, scan, f); } } static public MandelName getNextSubName(MandelName n, Set<MandelName> set) { MandelName s=n.sub(); while (s!=null && set.contains(s)) { s=s.next(); } return s; } static public MandelName getNextSubName(MandelName n, MandelScanner scan) { return getNextSubName(n,scan,true); } static public MandelName getNextSubName(MandelName n, MandelScanner scan, boolean rescan) { MandelName s=n.sub(); if (rescan) scan.rescan(false); while (s!=null && scan.getMandelInfo(s)!=null) { s=s.next(); } return s; } static public MandelName getNextName(MandelName n, MandelScanner scan) { return getNextName(n,scan,true); } static public MandelName getNextName(MandelName s, MandelScanner scan, boolean rescan) { if (rescan) scan.rescan(false); s=s.next(); while (s!=null && scan.getMandelInfo(s)!=null) { s=s.next(); } return s; } static public MandelHandle better(MandelHandle a, MandelHandle b) { if (a==null) return b; if (b==null) return a; MandelHandle r=a; if (b.getHeader().hasRaster()&&!a.getHeader().hasRaster()) a=b; if (b.getHeader().hasModifiableImage()&&!a.getHeader().hasModifiableImage()) a=b; if (b.getQualifier()==null &&a.getQualifier()!=null) a=b; if (b.getHeader().hasAdditional(a.getHeader().getType()) &&(b.getQualifier()==null) ==(a.getQualifier()==null)) a=b; if (a==r && a.getName().equals(b.getName())) { try { MandelData d1=a.getInfo(); MandelData d2=b.getInfo(); if (d2.getInfo().getLimitIt()>d1.getInfo().getLimitIt()) a=b; } catch (IOException ex) { System.out.println("error reading info: "+ex); } } return a; } static public void adjustMandelInfo(MandelInfo info, Dimension raster) { BigDecimal v; if (raster.getWidth()/raster.getHeight() > ((double)info.getRX())/info.getRY()) { v=mul(info.getDY(),info.getRX()); v=div(v,info.getRY()); v=mul(v,raster.getHeight()); v=div(v,raster.getWidth()); info.setDY(v); } else { v=mul(info.getDX(),info.getRY()); v=div(v,info.getRX()); v=mul(v,raster.getWidth()); v=div(v,raster.getHeight()); info.setDX(v); } info.setRX(toInt(raster.getWidth())); info.setRY(toInt(raster.getHeight())); } static public void normalizeImageSize(MandelInfo info) { if (div(info.getDX(),info.getDY()).doubleValue() > ((double)info.getRX())/info.getRY()) { adjustHeight(info); } else { adjustWidth(info); } } static public void adjustHeight(MandelInfo info) { info.setRY((int)(info.getRX()* div(info.getDY(),info.getDX()).doubleValue())); } static public void adjustWidth(MandelInfo info) { info.setRX((int)(info.getRY()* div(info.getDX(),info.getDY()).doubleValue())); } static public void normalize(MandelInfo info) { if (div(info.getDX(),info.getDY()).doubleValue() > ((double)info.getRX())/info.getRY()) { adjustDY(info); } else { adjustDX(info); } } static public void adjustDX(MandelInfo info) { info.setDX(mul(info.getDY(),div(info.getRX(),info.getRY()))); } static public void adjustDY(MandelInfo info) { info.setDY(mul(info.getDX(),div(info.getRY(),info.getRX()))); } static public void round(MandelInfo info) { round(info,PRECISION); } static public void round(MandelInfo info, int r) { info.setXM(round(info.getXM(),info.getDX(),info.getRX(),r)); info.setYM(round(info.getYM(),info.getDY(),info.getRY(),r)); info.setDX(round(info.getDX(),info.getDX(),info.getRX(),r)); info.setDY(round(info.getDY(),info.getDY(),info.getRY(),r)); } static public int getMagnification(MandelInfo i) { BigDecimal d=div(i.getDY(),3.0); // initial size of typical root int m=0; while (d.compareTo(BigDecimal.ONE)<0) { d=d.scaleByPowerOfTen(1); m++; } return m; } static public double getProportion(int rx, int ry, MandelInfo cur) { return div(cur.getDY(), cur.getDX()).doubleValue()* cur.getRX()/cur.getRY()*rx/ry; } static public MandelInfo createRoot() { MandelInfo mi=new MandelInfo(); mi.setXM(-0.55); mi.setYM(0); mi.setDX(4); mi.setDY(4); mi.setLimitIt(64000); mi.setRX(1000); mi.setRY(1000); return mi; } static public boolean isAbove(MandelName name, MandelList list) { for (QualifiedMandelName n:list) { if (name.isAbove(n.getMandelName())) return true; } return false; } static public boolean isAbove(MandelName name, MandelListFolder list) { for (QualifiedMandelName n:list.allentries()) { if (name.isAbove(n.getMandelName())) return true; } return false; } }