/* * Copyright (c) 2009, 2010, 2011 Daniel Rendall * This file is part of FractDim. * * FractDim 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 3 of the License, or * (at your option) any later version. * * FractDim 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. * * You should have received a copy of the GNU General Public License * along with FractDim. If not, see <http://www.gnu.org/licenses/> */ package uk.co.danielrendall.fractdim.generate; import org.apache.commons.lang.text.StrTokenizer; import org.kohsuke.args4j.CmdLineException; import org.kohsuke.args4j.CmdLineParser; import org.kohsuke.args4j.Option; import org.w3c.dom.svg.SVGDocument; import uk.co.danielrendall.mathlib.geom2d.Line; import uk.co.danielrendall.mathlib.geom2d.Point; import javax.xml.transform.*; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.OutputStream; /** * @author Daniel Rendall * @created 23-May-2009 12:18:58 */ public class Generator { @Option(name = "-rules", aliases = {"-r"}, usage = "Procedure to use (default KochCurve)") private String rules = "KochCurve"; @Option(name = "-output", aliases = {"-o"}, usage = "Output file (default <rule>.svg)") private String output = ""; @Option(name = "-start", aliases = {"-s"}, usage = "Start as x,y (default 0,0)") private String start = "0,0"; @Option(name = "-end", aliases = {"-e"}, usage = "End as x,y (default 1000,0)") private String end = "1000,0"; @Option(name = "-depth", aliases = {"-d"}, usage = "Iteration depth (default 3)") int depth = 3; public static void main(String[] args) { Generator generator = new Generator(); CmdLineParser parser = new CmdLineParser(generator); try { parser.parseArgument(args); generator.run(); } catch (CmdLineException e) { System.err.println(e.getMessage()); parser.printUsage(System.err); } } public void run() throws CmdLineException { Procedure ruleClass; try { Class clazz = Class.forName("uk.co.danielrendall.fractdim.generate.fractals." + rules); if (!Procedure.class.isAssignableFrom(clazz)) { throw new CmdLineException("The rules '" + rules + "' are not valid fractal rules"); } ruleClass = (Procedure) clazz.newInstance(); } catch (ClassNotFoundException e) { throw new CmdLineException("The rules '" + rules + "' could not be found"); } catch (IllegalAccessException e) { throw new CmdLineException("The rules '" + rules + "' could not be accessed"); } catch (InstantiationException e) { throw new CmdLineException("The rules '" + rules + "' could not be created"); } if ("".equals(output)) { output = rules + ".svg"; } Point startPoint; Point endPoint; try { startPoint = getPoint(start); } catch (Exception e) { throw new CmdLineException("Start point was invalid"); } try { endPoint = getPoint(end); } catch (Exception e) { throw new CmdLineException("End point was invalid"); } SVGDocument doc = generateFractal(ruleClass, startPoint, endPoint, depth); try { // Prepare the DOM document for writing Source source = new DOMSource(doc); // Prepare the output file File file = new File(output); OutputStream fos = new FileOutputStream(file); Result result = new StreamResult(fos); // Write the DOM document to the file Transformer xformer = TransformerFactory.newInstance().newTransformer(); xformer.transform(source, result); } catch (TransformerConfigurationException e) { e.printStackTrace(); } catch (TransformerException e) { e.printStackTrace(); } catch (FileNotFoundException e) { throw new CmdLineException("Couldn't create file '" + output + "'"); } } public SVGDocument generateFractal(Procedure ruleClass, Point startPoint, Point endPoint, int iterDepth) { Fractal f = new Fractal(new Line(startPoint, endPoint), ruleClass); SVGGeneratorVisitor fv = new SVGGeneratorVisitor(iterDepth); f.accept(fv); SVGDocument doc = fv.getDocument(); return doc; } private Point getPoint(String point) throws Exception { StrTokenizer tok = new StrTokenizer(point, ","); if (tok.size() != 2) throw new Exception("Wrong number of tokens"); String xs = tok.getTokenArray()[0].trim(); String ys = tok.getTokenArray()[1].trim(); double x = Double.parseDouble(xs); double y = Double.parseDouble(ys); return new Point(x,y); } }