/*
* 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.calculation;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
import org.w3c.dom.svg.SVGDocument;
import uk.co.danielrendall.fractdim.app.controller.FractalController;
import uk.co.danielrendall.fractdim.app.model.FractalDocument;
import uk.co.danielrendall.fractdim.app.model.FractalDocumentMetadata;
import uk.co.danielrendall.mathlib.geom2d.BezierCubic;
import uk.co.danielrendall.mathlib.geom2d.Line;
import uk.co.danielrendall.mathlib.geom2d.Point;
import uk.co.danielrendall.mathlib.geom2d.Vec;
import uk.co.danielrendall.fractdim.logging.Log;
import uk.co.danielrendall.fractdim.generate.fractals.KochCurve;
import uk.co.danielrendall.fractdim.generate.Generator;
import uk.co.danielrendall.fractdim.calculation.grids.Grid;
import uk.co.danielrendall.fractdim.calculation.grids.GridSquare;
import uk.co.danielrendall.fractdim.calculation.grids.GridCollectionBuilder;
import uk.co.danielrendall.fractdim.calculation.iterators.UniformAngleIterator;
import uk.co.danielrendall.fractdim.calculation.iterators.LogarithmicResolutionIterator;
import uk.co.danielrendall.fractdim.calculation.iterators.UniformDisplacementIterator;
import javax.xml.transform.*;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.dom.DOMSource;
import java.util.Iterator;
import java.io.File;
import java.io.OutputStream;
import java.io.FileOutputStream;
import java.io.FileNotFoundException;
/**
* @author Daniel Rendall
* @created 31-May-2009 11:20:00
*/
public class SquareCounterTest {
@Test
public void testStraightLine() {
Point start = new Point(50.0, 30.0);
Point end = new Point(250.0, 90.0);
Grid pg = new Grid(100.0d);
GridCollectionBuilder builder = new GridCollectionBuilder();
builder.grid(pg);
SquareCounter gc = new SquareCounter(null, builder.build(), 1000);
gc.handleCurve(new Line(start, end));
assertEquals(3, pg.getSquareCount());
}
@Test
public void testSimpleKoch100() {
Point start = new Point(0.0, 0.0);
Point p1 = new Point(333.3333333333333, 250.0);
Point p2 = new Point(283.49364905389035, 663.6751345948129);
Point p3 = new Point(666.6666666666667, 500.0);
Point end = new Point(999.999999999, 749.9999999999); // no spill over
Grid pg = new Grid(100.0d);
GridCollectionBuilder builder = new GridCollectionBuilder();
builder.grid(pg);
SquareCounter gc = new SquareCounter(null, builder.build(), 1000);
gc.handleCurve(new Line(start, p1));
gc.handleCurve(new Line(p1, p2));
gc.handleCurve(new Line(p2, p3));
gc.handleCurve(new Line(p3, end));
for (Iterator it1 = pg.squareIterator(); it1.hasNext();) {
Log.test.debug(it1.next());
}
Iterator<GridSquare> it = pg.squareIterator();
assertTrue(GridSquare.create(0, 0).equals(it.next()));
assertTrue(GridSquare.create(1, 0).equals(it.next()));
assertTrue(GridSquare.create(1, 1).equals(it.next()));
assertTrue(GridSquare.create(2, 1).equals(it.next()));
assertTrue(GridSquare.create(2, 2).equals(it.next()));
assertTrue(GridSquare.create(3, 2).equals(it.next()));
assertTrue(GridSquare.create(3, 3).equals(it.next()));
assertTrue(GridSquare.create(3, 4).equals(it.next()));
assertTrue(GridSquare.create(2, 5).equals(it.next()));
assertTrue(GridSquare.create(3, 5).equals(it.next()));
assertTrue(GridSquare.create(4, 5).equals(it.next()));
assertTrue(GridSquare.create(5, 5).equals(it.next()));
assertTrue(GridSquare.create(6, 5).equals(it.next()));
assertTrue(GridSquare.create(7, 5).equals(it.next()));
assertTrue(GridSquare.create(2, 6).equals(it.next()));
assertTrue(GridSquare.create(3, 6).equals(it.next()));
assertTrue(GridSquare.create(4, 6).equals(it.next()));
assertTrue(GridSquare.create(8, 6).equals(it.next()));
assertTrue(GridSquare.create(9, 6).equals(it.next()));
assertTrue(GridSquare.create(9, 7).equals(it.next()));
}
@Test
public void testSimpleKoch69() {
Point start = new Point(0.0, 0.0);
Point p1 = new Point(333.3333333333333, 250.0);
Point p2 = new Point(283.49364905389035, 663.6751345948129);
Point p3 = new Point(666.6666666666667, 500.0);
Point end = new Point(999.999999999, 749.9999999999); // no spill over
Grid pg = new Grid(69.0d);
GridCollectionBuilder builder = new GridCollectionBuilder();
builder.grid(pg);
SquareCounter gc = new SquareCounter(null, builder.build(), 1000);
gc.handleCurve(new Line(start, p1));
gc.handleCurve(new Line(p1, p2));
gc.handleCurve(new Line(p2, p3));
gc.handleCurve(new Line(p3, end));
for (Iterator it1 = pg.squareIterator(); it1.hasNext();) {
Log.test.debug(it1.next());
}
Iterator<GridSquare> it = pg.squareIterator();
assertTrue(GridSquare.create(0, 0).equals(it.next()));
assertTrue(GridSquare.create(1, 0).equals(it.next()));
assertTrue(GridSquare.create(1, 1).equals(it.next()));
assertTrue(GridSquare.create(2, 1).equals(it.next()));
assertTrue(GridSquare.create(2, 2).equals(it.next()));
assertTrue(GridSquare.create(3, 2).equals(it.next()));
assertTrue(GridSquare.create(4, 3).equals(it.next()));
assertTrue(GridSquare.create(4, 4).equals(it.next()));
assertTrue(GridSquare.create(4, 5).equals(it.next()));
assertTrue(GridSquare.create(4, 6).equals(it.next()));
assertTrue(GridSquare.create(4, 7).equals(it.next()));
assertTrue(GridSquare.create(7, 7).equals(it.next()));
assertTrue(GridSquare.create(8, 7).equals(it.next()));
assertTrue(GridSquare.create(9, 7).equals(it.next()));
assertTrue(GridSquare.create(10, 7).equals(it.next()));
assertTrue(GridSquare.create(4, 8).equals(it.next()));
assertTrue(GridSquare.create(5, 8).equals(it.next()));
assertTrue(GridSquare.create(6, 8).equals(it.next()));
assertTrue(GridSquare.create(7, 8).equals(it.next()));
assertTrue(GridSquare.create(10, 8).equals(it.next()));
assertTrue(GridSquare.create(11, 8).equals(it.next()));
assertTrue(GridSquare.create(4, 9).equals(it.next()));
assertTrue(GridSquare.create(5, 9).equals(it.next()));
assertTrue(GridSquare.create(12, 9).equals(it.next()));
assertTrue(GridSquare.create(13, 9).equals(it.next()));
assertTrue(GridSquare.create(13, 10).equals(it.next()));
assertTrue(GridSquare.create(14, 10).equals(it.next()));
}
@Test
public void testMultipleGridsWithLine() {
Point start = new Point(50.001, 30.001);
Point end = new Point(249.999, 89.999);
Grid pg100 = new Grid(100.0d);
Grid pg80 = new Grid(80);
Grid pg60 = new Grid(60);
Grid pg40 = new Grid(40);
Grid pg20 = new Grid(20);
Grid pg10 = new Grid(10);
GridCollectionBuilder builder = new GridCollectionBuilder();
builder.grid(pg100).
grid(pg80).
grid(pg60).
grid(pg40).
grid(pg20).
grid(pg10);
SquareCounter gc = new SquareCounter(null, builder.build(), 1000);
gc.handleCurve(new Line(start, end));
assertEquals(3, pg100.getSquareCount());
assertEquals(5, pg80.getSquareCount());
assertEquals(6, pg60.getSquareCount());
assertEquals(8, pg40.getSquareCount());
assertEquals(14, pg20.getSquareCount());
assertEquals(24, pg10.getSquareCount());
}
@Test
public void testMultipleGridsWithBezier() {
Point start = new Point(50.001, 30.001);
Point control1 = new Point(100.0, 150.0);
Point control2 = new Point(210.0, 160.0);
Point end = new Point(249.999, 90.001);
Grid pg100 = new Grid(100.0d);
Grid pg80 = new Grid(80);
Grid pg60 = new Grid(60);
Grid pg40 = new Grid(40);
Grid pg20 = new Grid(20);
Grid pg10 = new Grid(10);
GridCollectionBuilder builder = new GridCollectionBuilder();
builder.grid(pg100).
grid(pg80).
grid(pg60).
grid(pg40).
grid(pg20).
grid(pg10);
SquareCounter gc = new SquareCounter(null, builder.build(), 1000);
gc.handleCurve(new BezierCubic(start, control1, control2, end));
assertEquals(5, pg100.getSquareCount());
assertEquals(5, pg80.getSquareCount());
assertEquals(8, pg60.getSquareCount());
assertEquals(10, pg40.getSquareCount());
assertEquals(18, pg20.getSquareCount());
assertEquals(34, pg10.getSquareCount());
}
@Test
public void testCreateCollection() {
SquareCounterBuilder squareCounterBuilder = new SquareCounterBuilder();
squareCounterBuilder.maxDepth(1000).
angleIterator(new UniformAngleIterator(1)).
resolutionIterator(new LogarithmicResolutionIterator(1.0d, 10.0d, 10)).
displacementIterator(new UniformDisplacementIterator(1)).
fractalDocument(null);
SquareCounter collection = squareCounterBuilder.build();
assertEquals(10, collection.count());
// four angles
squareCounterBuilder.angleIterator(new UniformAngleIterator(4));
collection = squareCounterBuilder.build();
assertEquals(40, collection.count());
// four angles, 3 displacement points (= 9 displacement vectors)
squareCounterBuilder.displacementIterator(new UniformDisplacementIterator(3));
collection = squareCounterBuilder.build();
assertEquals(360, collection.count());
}
@Test
public void testGridDisplacements() {
Point start = new Point(29.198, 29.198);
Point end = new Point(286.171, 88.963);
Grid pg100 = new Grid(100.0d);
Grid pg100_x1 = new Grid(100.0d, new Vec(0.5d, 0.0d));
Grid pg100_y1 = new Grid(100.0d, new Vec(0.0d, 0.5d));
Grid pg100_x1_y1 = new Grid(100.0d, new Vec(0.5d, 0.5d));
GridCollectionBuilder builder = new GridCollectionBuilder();
builder.grid(pg100).
grid(pg100_x1).
grid(pg100_y1).
grid(pg100_x1_y1);
SquareCounter gc = new SquareCounter(null, builder.build(), 1000);
gc.handleCurve(new Line(start, end));
assertEquals(3, pg100.getSquareCount());
assertEquals(4, pg100_x1.getSquareCount());
assertEquals(4, pg100_y1.getSquareCount());
assertEquals(5, pg100_x1_y1.getSquareCount());
}
@Test
public void testGridRotation() {
Point start = new Point(50.001, 30.001);
Point control1 = new Point(100.0, 150.0);
Point control2 = new Point(210.0, 160.0);
Point end = new Point(249.999, 90.001);
Grid pg100 = new Grid(100.0d);
Grid pg100_10 = new Grid(Math.PI / 18.0d, 100.0d);
Grid pg100_20 = new Grid(2.0d * Math.PI / 18.0d, 100.0d);
Grid pg100_30 = new Grid(3.0d * Math.PI / 18.0d, 100.0d);
Grid pg100_40 = new Grid(4.0d * Math.PI / 18.0d, 100.0d);
Grid pg100_50 = new Grid(5.0d * Math.PI / 18.0d, 100.0d);
Grid pg100_60 = new Grid(6.0d * Math.PI / 18.0d, 100.0d);
Grid pg100_70 = new Grid(7.0d * Math.PI / 18.0d, 100.0d);
Grid pg100_80 = new Grid(8.0d * Math.PI / 18.0d, 100.0d);
Grid pg100_90 = new Grid(9.0d * Math.PI / 18.0d, 100.0d);
GridCollectionBuilder builder = new GridCollectionBuilder();
builder.grid(pg100).
grid(pg100_10).
grid(pg100_20).
grid(pg100_30).
grid(pg100_40).
grid(pg100_50).
grid(pg100_60).
grid(pg100_70).
grid(pg100_80).
grid(pg100_90).
grid(pg100_10);
SquareCounter gc = new SquareCounter(null, builder.build(), 1000);
gc.handleCurve(new BezierCubic(start, control1, control2, end));
assertEquals(5, pg100.getSquareCount());
assertEquals(4, pg100_10.getSquareCount());
assertEquals(4, pg100_20.getSquareCount());
assertEquals(4, pg100_30.getSquareCount());
assertEquals(4, pg100_40.getSquareCount());
assertEquals(5, pg100_50.getSquareCount());
assertEquals(4, pg100_60.getSquareCount());
assertEquals(4, pg100_70.getSquareCount());
assertEquals(5, pg100_80.getSquareCount());
assertEquals(5, pg100_90.getSquareCount());
}
@Test
public void testGridRotationAndDisplacement() {
Point start = new Point(50.001, 30.001);
Point control1 = new Point(100.0, 150.0);
Point control2 = new Point(210.0, 160.0);
Point end = new Point(249.999, 90.001);
Grid pg60 = new Grid(60.0d);
Grid pg60_30 = new Grid(3.0d * Math.PI / 18.0d, 60.0d);
Grid pg60_70 = new Grid(7.0d * Math.PI / 18.0d, 60.0d);
Grid pg60_x1 = new Grid(60.0d, new Vec(0.5d, 0.0d));
Grid pg60_30_x1 = new Grid(3.0d * Math.PI / 18.0d, 60.0d, new Vec(0.5d, 0.0d));
Grid pg60_70_x1 = new Grid(7.0d * Math.PI / 18.0d, 60.0d, new Vec(0.5d, 0.0d));
Grid pg60_y1 = new Grid(60.0d, new Vec(0.0d, 0.5d));
Grid pg60_30_y1 = new Grid(3.0d * Math.PI / 18.0d, 60.0d, new Vec(0.0d, 0.5d));
Grid pg60_70_y1 = new Grid(7.0d * Math.PI / 18.0d, 60.0d, new Vec(0.0d, 0.5d));
Grid pg60_x1_y1 = new Grid(60.0d, new Vec(0.5d, 0.5d));
Grid pg60_30_x1_y1 = new Grid(3.0d * Math.PI / 18.0d, 60.0d, new Vec(0.5d, 0.5d));
Grid pg60_70_x1_y1 = new Grid(7.0d * Math.PI / 18.0d, 60.0d, new Vec(0.5d, 0.5d));
GridCollectionBuilder builder = new GridCollectionBuilder();
builder.grid(pg60).
grid(pg60_30).
grid(pg60_70).
grid(pg60_x1).
grid(pg60_30_x1).
grid(pg60_70_x1).
grid(pg60_y1).
grid(pg60_30_y1).
grid(pg60_70_y1).
grid(pg60_x1_y1).
grid(pg60_30_x1_y1).
grid(pg60_70_x1_y1);
SquareCounter gc = new SquareCounter(null, builder.build(), 1000);
gc.handleCurve(new BezierCubic(start, control1, control2, end));
assertEquals(8, pg60.getSquareCount());
assertEquals(6, pg60_30.getSquareCount());
assertEquals(8, pg60_70.getSquareCount());
assertEquals(7, pg60_x1.getSquareCount());
assertEquals(6, pg60_30_x1.getSquareCount());
assertEquals(6, pg60_70_x1.getSquareCount());
assertEquals(6, pg60_y1.getSquareCount());
assertEquals(7, pg60_30_y1.getSquareCount());
assertEquals(6, pg60_70_y1.getSquareCount());
assertEquals(5, pg60_x1_y1.getSquareCount());
assertEquals(7, pg60_30_x1_y1.getSquareCount());
assertEquals(7, pg60_70_x1_y1.getSquareCount());
}
@Test
public void testCalculateFractalDimension() {
for (int i=0; i< 4; i++) {
Generator gen = new Generator();
double angle = (Math.PI / 2.0) * (double) i;
double startX = 0.1d * Math.cos(angle);
double startY = 0.1d * Math.sin(angle);
double endX = 1001.0d * Math.cos(angle);
double endY = 1001.0d * Math.sin(angle);
SVGDocument svg = gen.generateFractal(new KochCurve(), new Point(startX, startY).rotate(Math.PI / 90d), new Point(endX, endY).rotate(Math.PI / 90d), 3);
FractalController controller = FractalController.fromDocument(svg, "Test " + i);
FractalDocument fractalDocument = controller.getDocument();
FractalDocumentMetadata metadata = FractalMetadataUtil.getMetadata(fractalDocument.getSvgDoc());
fractalDocument.setMetadata(metadata);
try {
// Prepare the DOM document for writing
Source source = new DOMSource(svg);
// Prepare the output file
File file = new File("/tmp/koch" + i + ".svg");
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) {
e.printStackTrace();
}
StatisticsCalculatorBuilder statisticsCalculatorBuilder = new StatisticsCalculatorBuilder();
statisticsCalculatorBuilder.minAngle(StatisticsCalculator.TWO_DEGREES).
fractalDocument(fractalDocument);
StatisticsCalculator sc = statisticsCalculatorBuilder.build();
Statistics stats = sc.process();
Log.test.info(stats.toString());
// CalculationSettings settings = FractalController.createCalculationSettings(fractalDocument.getMetadata());
// Log.test.info(settings.toString());
SquareCounterBuilder squareCounterBuilder = new SquareCounterBuilder();
// squareCounterBuilder.maxDepth(30).
// angleIterator(new UniformAngleIterator(settings.getNumberOfAngles().getValue())).
// resolutionIterator(new LogarithmicResolutionIterator(settings.getMinimumSquareSize().getValue(), settings.getMaximumSquareSize().getValue(), settings.getNumberOfResolutions().getValue())).
// displacementIterator(new UniformDisplacementIterator(settings.getNumberOfDisplacements().getValue())).
// fractalDocument(fractalDocument);
//
// SquareCounter counter = squareCounterBuilder.build();
//
// SquareCountingResult result = counter.process();
// GridSquare.resetCount();
}
}
}