/*
* JAME 6.2.1
* http://jame.sourceforge.net
*
* Copyright 2001, 2016 Andrea Medeghini
*
* This file is based on code written by Jan Hubicka and Thomas Marsh (http://xaos.sf.net).
*
* This file is part of JAME.
*
* JAME is an application for creating fractals and other graphics artifacts.
*
* JAME 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.
*
* JAME 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 JAME. If not, see <http://www.gnu.org/licenses/>.
*
*/
package net.sf.jame.mandelbrot.renderer;
import java.awt.AlphaComposite;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
import net.sf.jame.core.math.Complex;
import net.sf.jame.core.util.Colors;
import net.sf.jame.core.util.RenderWorker;
import net.sf.jame.core.util.Surface;
import net.sf.jame.mandelbrot.incolouringFormula.IncolouringFormulaRuntimeElement;
import net.sf.jame.mandelbrot.outcolouringFormula.OutcolouringFormulaRuntimeElement;
/**
* @author Andrea Medeghini
*/
public final class BestXaosMandelbrotRenderer extends AbstractMandelbrotRenderer {
private static final boolean DUMP = false;
private static final boolean DUMP_XAOS = false;
private static final boolean SHOW_REFRESH = false;
private static final boolean SHOW_SYMETRY = false;
private static final boolean SHOW_CALCULATE = false;
private static final boolean SHOW_SOLIDGUESS = false;
private static final boolean PRINT_REALLOCTABLE = false;
private static final boolean PRINT_CALCULATE = false;
private static final boolean PRINT_POSITIONS = false;
private static final boolean PRINT_MOVETABLE = false;
private static final boolean PRINT_FILLTABLE = false;
private static final boolean PRINT_MULTABLE = false;
private static final boolean PRINT_REGION = false;
private static final boolean USE_XAOS = true;
private static final boolean USE_SYMETRY = true;
private static final boolean USE_SOLIDGUESS = false;
private static final boolean USE_MULTITHREAD = true;
private static final int GUESS_RANGE = 4;
private static final int RANGES = 2;
private static final int RANGE = 4;
private static final int STEPS = 8;
private static final int MASK = 0x7;
private static final int DSIZE = (BestXaosMandelbrotRenderer.RANGES + 1);
private static final int FPMUL = 64;
private static final int FPRANGE = BestXaosMandelbrotRenderer.FPMUL * BestXaosMandelbrotRenderer.RANGE;
private static final int MAX_PRICE = Integer.MAX_VALUE;
private static final int NEW_PRICE = BestXaosMandelbrotRenderer.FPRANGE * BestXaosMandelbrotRenderer.FPRANGE;
private static final int[] multable = new int[BestXaosMandelbrotRenderer.FPRANGE * 2];
static {
for (int i = -BestXaosMandelbrotRenderer.FPRANGE; i < BestXaosMandelbrotRenderer.FPRANGE; i++) {
BestXaosMandelbrotRenderer.multable[BestXaosMandelbrotRenderer.FPRANGE + i] = i * i;
}
if (BestXaosMandelbrotRenderer.PRINT_MULTABLE) {
AbstractMandelbrotRenderer.logger.fine("Multable:");
for (int i = -BestXaosMandelbrotRenderer.FPRANGE; i < BestXaosMandelbrotRenderer.FPRANGE; i++) {
AbstractMandelbrotRenderer.logger.fine("i = " + i + ", i * i = " + BestXaosMandelbrotRenderer.multable[BestXaosMandelbrotRenderer.FPRANGE + i]);
}
}
}
private final RenderingStrategy mandelbrotRenderingStrategy = new MandelbrotRenderingStrategy();
private final RenderingStrategy juliaRenderingStrategy = new JuliaRenderingStrategy();
// private final PrepareColumnsWorker prepareColumnsWorker = new PrepareColumnsWorker();
// private final PrepareLinesWorker prepareLinesWorker = new PrepareLinesWorker();
private final MandelbrotWorker2 renderWorker2 = new MandelbrotWorker2();
private final boolean isSolidguessEnabled = true;
private boolean isSolidguessSupported = true;
private final boolean isSymetryEnabled = true;
private boolean isVerticalSymetrySupported = true;
private boolean isHorizontalSymetrySupported = true;
private boolean useCache = false;
private boolean isAborted = false;
private RendererData renderedData;
/**
* @param threadPriority
*/
public BestXaosMandelbrotRenderer(final int threadPriority) {
super(threadPriority);
}
/**
* @see net.sf.jame.mandelbrot.renderer.AbstractMandelbrotRenderer#start()
*/
@Override
public void start() {
// prepareLinesWorker.start();
// prepareColumnsWorker.start();
super.start();
renderWorker2.start();
}
/**
* @see net.sf.jame.mandelbrot.renderer.AbstractMandelbrotRenderer#stop()
*/
@Override
public void stop() {
super.stop();
// prepareLinesWorker.stop();
// prepareColumnsWorker.stop();
renderWorker2.stop();
}
/**
* @see net.sf.jame.AbstractMandelbrotRenderer.core.fractal.renderer.AbstractFractalRenderer#free()
*/
protected void free() {
super.free();
if (renderedData != null) {
renderedData.free();
}
}
/**
* @see net.sf.jame.AbstractMandelbrotRenderer.core.fractal.renderer.AbstractFractalRenderer#init()
*/
protected void init() {
super.init();
renderedData = new RendererData();
renderedData.reallocate(getBufferWidth(), getBufferHeight());
}
/**
*
*/
protected void swapBuffers() {
if (BestXaosMandelbrotRenderer.DUMP) {
AbstractMandelbrotRenderer.logger.fine("Swap buffers...");
}
renderedData.swap();
}
/**
* @see net.sf.jame.AbstractMandelbrotRenderer.core.fractal.renderer.AbstractFractalRenderer#doRender(boolean)
*/
protected void doRender(final boolean dynamic) {
isAborted = false;
updateShift();
updateRegion();
updateTransform();
renderingStrategy.updateParameters();
if (fractalRuntime.getRenderingFormula().getFormulaRuntime() != null) {
fractalRuntime.getRenderingFormula().getFormulaRuntime().prepareForRendering(fractalRuntime.getProcessingFormula().getFormulaRuntime(), fractalRuntime.getOrbitTrap().getOrbitTrapRuntime());
if (fractalRuntime.getOrbitTrap().getOrbitTrapRuntime() != null) {
fractalRuntime.getOrbitTrap().getOrbitTrapRuntime().prepareForProcessing(fractalRuntime.getOrbitTrap().getCenter());
}
}
for (int i = 0; i < fractalRuntime.getOutcolouringFormulaCount(); i++) {
if (fractalRuntime.getOutcolouringFormula(i).getFormulaRuntime() != null) {
if (fractalRuntime.getOutcolouringFormula(i).isAutoIterations() && (fractalRuntime.getRenderingFormula().getFormulaRuntime() != null)) {
fractalRuntime.getOutcolouringFormula(i).getFormulaRuntime().prepareForRendering(fractalRuntime.getRenderingFormula().getFormulaRuntime(), fractalRuntime.getRenderingFormula().getFormulaRuntime().getIterations());
}
else {
fractalRuntime.getOutcolouringFormula(i).getFormulaRuntime().prepareForRendering(fractalRuntime.getRenderingFormula().getFormulaRuntime(), fractalRuntime.getOutcolouringFormula(i).getIterations());
}
}
}
for (int i = 0; i < fractalRuntime.getIncolouringFormulaCount(); i++) {
if (fractalRuntime.getIncolouringFormula(i).getFormulaRuntime() != null) {
if (fractalRuntime.getIncolouringFormula(i).isAutoIterations() && (fractalRuntime.getRenderingFormula().getFormulaRuntime() != null)) {
fractalRuntime.getIncolouringFormula(i).getFormulaRuntime().prepareForRendering(fractalRuntime.getRenderingFormula().getFormulaRuntime(), fractalRuntime.getRenderingFormula().getFormulaRuntime().getIterations());
}
else {
fractalRuntime.getIncolouringFormula(i).getFormulaRuntime().prepareForRendering(fractalRuntime.getRenderingFormula().getFormulaRuntime(), fractalRuntime.getIncolouringFormula(i).getIterations());
}
}
}
if (BestXaosMandelbrotRenderer.PRINT_REGION) {
AbstractMandelbrotRenderer.logger.fine("Region: " + area.toString());
}
final boolean refresh = (renderMode & MandelbrotRenderer.MODE_REFRESH) != 0;
useCache = refresh || !dynamic;
isSolidguessSupported = BestXaosMandelbrotRenderer.USE_SOLIDGUESS && isSolidguessEnabled && isSolidGuessSupported();
isVerticalSymetrySupported = BestXaosMandelbrotRenderer.USE_SYMETRY && isSymetryEnabled && isVerticalSymetrySupported();
isHorizontalSymetrySupported = BestXaosMandelbrotRenderer.USE_SYMETRY && isSymetryEnabled && isHorizontalSymetrySupported();
if (BestXaosMandelbrotRenderer.DUMP) {
AbstractMandelbrotRenderer.logger.fine("Solidguess supported = " + isSolidguessSupported);
AbstractMandelbrotRenderer.logger.fine("Vertical symetry supported = " + isVerticalSymetrySupported);
AbstractMandelbrotRenderer.logger.fine("Horizontal symetry supported = " + isHorizontalSymetrySupported);
AbstractMandelbrotRenderer.logger.fine("Use cache = " + useCache);
}
if (BestXaosMandelbrotRenderer.USE_MULTITHREAD && !BestXaosMandelbrotRenderer.DUMP_XAOS) {
// prepareLinesWorker.executeTask();
// prepareColumnsWorker.executeTask();
// prepareLinesWorker.waitTasks();
// prepareColumnsWorker.waitTasks();
renderWorker2.executeTask();
prepareLines();
renderWorker2.waitTasks();
}
else {
prepareLines();
prepareColumns();
}
if (BestXaosMandelbrotRenderer.PRINT_REALLOCTABLE) {
AbstractMandelbrotRenderer.logger.fine("ReallocTable:");
for (final Realloc element : renderedData.reallocX) {
AbstractMandelbrotRenderer.logger.fine(element.toString());
}
AbstractMandelbrotRenderer.logger.fine("ReallocTable:");
for (final Realloc element : renderedData.reallocY) {
AbstractMandelbrotRenderer.logger.fine(element.toString());
}
}
swapBuffers();
move();
processReallocTable(dynamic, refresh);
updatePosition();
renderMode = 0;
}
private void prepareLines() {
final double beginy = area.points[0].i;
final double endy = area.points[1].i;
double stepy = 0;
if (((renderMode & MandelbrotRenderer.MODE_CALCULATE) == 0) && BestXaosMandelbrotRenderer.USE_XAOS) {
stepy = BestXaosMandelbrotRenderer.makeReallocTable(renderedData.reallocY, renderedData.dynamicy, beginy, endy, renderedData.positionY, !useCache);
}
else {
stepy = BestXaosMandelbrotRenderer.initReallocTableAndPosition(renderedData.reallocY, renderedData.positionY, beginy, endy);
}
if ((fractalRuntime.getRenderingFormula().getFormulaRuntime() != null) && (fractalRuntime.getTransformingFormula().getFormulaRuntime() != null)) {
final double symy = fractalRuntime.getRenderingFormula().getFormulaRuntime().getVerticalSymetryPoint();
if (isVerticalSymetrySupported && fractalRuntime.getRenderingFormula().getFormulaRuntime().isVerticalSymetryAllowed() && fractalRuntime.getTransformingFormula().getFormulaRuntime().isVerticalSymetryAllowed() && (!((beginy > symy) || (symy > endy)))) {
BestXaosMandelbrotRenderer.prepareSymetry(renderedData.reallocY, (int) ((symy - beginy) / stepy), symy, stepy);
}
}
}
private void prepareColumns() {
final double beginx = area.points[0].r;
final double endx = area.points[1].r;
double stepx = 0;
if (((renderMode & MandelbrotRenderer.MODE_CALCULATE) == 0) && BestXaosMandelbrotRenderer.USE_XAOS) {
stepx = BestXaosMandelbrotRenderer.makeReallocTable(renderedData.reallocX, renderedData.dynamicx, beginx, endx, renderedData.positionX, !useCache);
}
else {
stepx = BestXaosMandelbrotRenderer.initReallocTableAndPosition(renderedData.reallocX, renderedData.positionX, beginx, endx);
}
if ((fractalRuntime.getRenderingFormula().getFormulaRuntime() != null) && (fractalRuntime.getTransformingFormula().getFormulaRuntime() != null)) {
final double symx = fractalRuntime.getRenderingFormula().getFormulaRuntime().getHorizontalSymetryPoint();
if (isHorizontalSymetrySupported && fractalRuntime.getRenderingFormula().getFormulaRuntime().isHorizontalSymetryAllowed() && fractalRuntime.getTransformingFormula().getFormulaRuntime().isHorizontalSymetryAllowed() && (!((beginx > symx) || (symx > endx)))) {
BestXaosMandelbrotRenderer.prepareSymetry(renderedData.reallocX, (int) ((symx - beginx) / stepx), symx, stepx);
}
}
}
private static double initReallocTableAndPosition(final Realloc[] realloc, final double[] position, final double begin, final double end) {
if (BestXaosMandelbrotRenderer.DUMP) {
AbstractMandelbrotRenderer.logger.fine("Init ReallocTable and position...");
}
final double step = (end - begin) / realloc.length;
double tmpPosition = begin;
Realloc tmpRealloc = null;
for (int i = 0; i < realloc.length; i++) {
tmpRealloc = realloc[i];
position[i] = tmpPosition;
tmpRealloc.position = tmpPosition;
tmpRealloc.recalculate = true;
tmpRealloc.refreshed = false;
tmpRealloc.dirty = true;
tmpRealloc.isCached = false;
tmpRealloc.plus = i;
tmpRealloc.symTo = -1;
tmpRealloc.symRef = -1;
tmpPosition += step;
}
return step;
}
private void updatePosition() {
if (BestXaosMandelbrotRenderer.DUMP) {
AbstractMandelbrotRenderer.logger.fine("Update position...");
}
for (int k = 0; k < renderedData.reallocX.length; k++) {
renderedData.positionX[k] = renderedData.reallocX[k].position;
}
for (int k = 0; k < renderedData.reallocY.length; k++) {
renderedData.positionY[k] = renderedData.reallocY[k].position;
}
}
private static int price(final int p1, final int p2) {
return BestXaosMandelbrotRenderer.multable[(BestXaosMandelbrotRenderer.FPRANGE + p1) - p2];
}
private static void addPrices(final Realloc[] realloc, int r1, final int r2) {
// if (r1 < r2)
while (r1 < r2) {
final int r3 = r1 + ((r2 - r1) >> 1);
realloc[r3].priority = (realloc[r2].position - realloc[r3].position) * realloc[r3].priority;
if (realloc[r3].symRef != -1) {
realloc[r3].priority /= 2.0;
}
BestXaosMandelbrotRenderer.addPrices(realloc, r1, r3);
// XaosFractalRenderer.addPrices(realloc, r3 + 1, r2);
r1 = r3 + 1;
}
}
private static void prepareSymetry(final Realloc[] realloc, final int symi, double symPosition, final double step) {
if (BestXaosMandelbrotRenderer.DUMP) {
AbstractMandelbrotRenderer.logger.fine("Prepare symetry...");
}
int i = 0;
int j = 0;
double tmp;
double abs;
double distance;
double tmpPosition;
final int size = realloc.length;
final int max = size - BestXaosMandelbrotRenderer.RANGE - 1;
int min = BestXaosMandelbrotRenderer.RANGE;
int istart = 0;
Realloc tmpRealloc = null;
Realloc symRealloc = null;
symPosition *= 2;
int symj = (2 * symi) - size;
if (symj < 0) {
symj = 0;
}
distance = step * BestXaosMandelbrotRenderer.RANGE;
for (i = symj; i < symi; i++) {
if (realloc[i].symTo != -1) {
continue;
}
tmpRealloc = realloc[i];
tmpPosition = tmpRealloc.position;
tmpRealloc.symTo = (2 * symi) - i;
if (tmpRealloc.symTo > max) {
tmpRealloc.symTo = max;
}
j = ((tmpRealloc.symTo - istart) > BestXaosMandelbrotRenderer.RANGE) ? (-BestXaosMandelbrotRenderer.RANGE) : (-tmpRealloc.symTo + istart);
if (tmpRealloc.recalculate) {
while ((j < BestXaosMandelbrotRenderer.RANGE) && ((tmpRealloc.symTo + j) < (size - 1))) {
tmp = symPosition - realloc[tmpRealloc.symTo + j].position;
abs = Math.abs(tmp - tmpPosition);
if (abs < distance) {
if (((i == 0) || (tmp > realloc[i - 1].position)) && (tmp < realloc[i + 1].position)) {
distance = abs;
min = j;
}
}
else if (tmp < tmpPosition) {
break;
}
j += 1;
}
}
else {
while ((j < BestXaosMandelbrotRenderer.RANGE) && ((tmpRealloc.symTo + j) < (size - 1))) {
if (tmpRealloc.recalculate) {
tmp = symPosition - realloc[tmpRealloc.symTo + j].position;
abs = Math.abs(tmp - tmpPosition);
if (abs < distance) {
if (((i == 0) || (tmp > realloc[i - 1].position)) && (tmp < realloc[i + 1].position)) {
distance = abs;
min = j;
}
}
else if (tmp < tmpPosition) {
break;
}
}
j += 1;
}
}
tmpRealloc.symTo += min;
symRealloc = realloc[tmpRealloc.symTo];
if ((min == BestXaosMandelbrotRenderer.RANGE) || (tmpRealloc.symTo <= symi) || (symRealloc.symTo != -1) || (symRealloc.symRef != -1)) {
tmpRealloc.symTo = -1;
continue;
}
if (!tmpRealloc.recalculate) {
tmpRealloc.symTo = -1;
if ((symRealloc.symTo != -1) || !symRealloc.recalculate) {
continue;
}
symRealloc.plus = tmpRealloc.plus;
symRealloc.symTo = i;
istart = tmpRealloc.symTo - 1;
symRealloc.recalculate = false;
symRealloc.refreshed = false;
symRealloc.dirty = true;
symRealloc.isCached = false;
tmpRealloc.symRef = tmpRealloc.symTo;
symRealloc.position = symPosition - tmpRealloc.position;
}
else {
if (symRealloc.symTo != -1) {
tmpRealloc.symTo = -1;
continue;
}
tmpRealloc.plus = symRealloc.plus;
istart = tmpRealloc.symTo - 1;
tmpRealloc.recalculate = false;
tmpRealloc.refreshed = false;
tmpRealloc.dirty = true;
tmpRealloc.isCached = false;
symRealloc.symRef = i;
tmpRealloc.position = symPosition - symRealloc.position;
}
}
}
private static void prepareMove(final Movetable movetable, final Realloc[] reallocX) {
if (BestXaosMandelbrotRenderer.DUMP) {
AbstractMandelbrotRenderer.logger.fine("Prepare move...");
}
final Movetable.Data[] table = movetable.data;
Movetable.Data tmpData = null;
int i = 0;
int j = 0;
int s = 0;
while (i < reallocX.length) {
if (!reallocX[i].dirty) {
tmpData = table[s];
tmpData.to = i;
tmpData.length = 1;
tmpData.from = reallocX[i].plus;
for (j = i + 1; j < reallocX.length; j++) {
if (reallocX[j].dirty || ((j - reallocX[j].plus) != (tmpData.to - tmpData.from))) {
break;
}
tmpData.length += 1;
}
i = j;
s += 1;
}
else {
i += 1;
}
}
tmpData = table[s];
tmpData.length = 0;
if (BestXaosMandelbrotRenderer.PRINT_MOVETABLE) {
AbstractMandelbrotRenderer.logger.fine("Movetable:");
for (i = 0; table[i].length > 0; i++) {
AbstractMandelbrotRenderer.logger.fine("i = " + i + " " + table[i].toString());
}
}
}
private static void prepareFill(final Filltable filltable, final Realloc[] reallocX) {
if (BestXaosMandelbrotRenderer.DUMP) {
AbstractMandelbrotRenderer.logger.fine("Prepare fill...");
}
final Filltable.Data[] table = filltable.data;
Filltable.Data tmpData = null;
int i = 0;
int j = 0;
int k = 0;
int s = 0;
int n = 0;
for (i = 0; i < reallocX.length; i++) {
if (reallocX[i].dirty) {
j = i - 1;
for (k = i + 1; (k < reallocX.length) && reallocX[k].dirty; k++) {
;
}
while ((i < reallocX.length) && reallocX[i].dirty) {
if ((k < reallocX.length) && ((j < i) || ((reallocX[i].position - reallocX[j].position) > (reallocX[k].position - reallocX[i].position)))) {
j = k;
}
else {
if (j < 0) {
break;
}
}
n = k - i;
tmpData = table[s];
tmpData.length = n;
tmpData.from = j;
tmpData.to = i;
while (n > 0) {
reallocX[i].position = reallocX[j].position;
reallocX[i].dirty = false;
n -= 1;
i += 1;
}
s += 1;
}
}
}
tmpData = table[s];
tmpData.length = 0;
if (BestXaosMandelbrotRenderer.PRINT_FILLTABLE) {
AbstractMandelbrotRenderer.logger.fine("Filltable:");
for (i = 0; table[i].length > 0; i++) {
AbstractMandelbrotRenderer.logger.fine("i = " + i + " " + table[i].toString());
}
}
}
private static double makeReallocTable(final Realloc[] realloc, final Dynamic dynamic, final double begin, final double end, final double[] position, final boolean invalidate) {
if (BestXaosMandelbrotRenderer.DUMP) {
AbstractMandelbrotRenderer.logger.fine("Make ReallocTable...");
}
Realloc tmpRealloc = null;
Dynamic.Data prevData = null;
Dynamic.Data bestData = null;
Dynamic.Data tmpData = null;
int bestPrice = BestXaosMandelbrotRenderer.MAX_PRICE;
int price = 0;
int price1 = 0;
int i = 0;
int y = 0;
int p = 0;
int ps = 0;
int pe = 0;
int ps1 = 0;
int yend = 0;
int flag = 0;
final int size = realloc.length;
final double step = (end - begin) / size;
final double tofix = (size * BestXaosMandelbrotRenderer.FPMUL) / (end - begin);
final int[] delta = dynamic.delta;
delta[size] = Integer.MAX_VALUE;
for (i = size - 1; i >= 0; i--) {
delta[i] = (int) ((position[i] - begin) * tofix);
if (delta[i] > delta[i + 1]) {
delta[i] = delta[i + 1];
}
}
if (BestXaosMandelbrotRenderer.DUMP_XAOS) {
AbstractMandelbrotRenderer.logger.fine("positions (fixed point):");
for (i = 0; i < size; i++) {
AbstractMandelbrotRenderer.logger.fine(String.valueOf(delta[i]));
}
}
for (i = 0; i < size; i++) {
dynamic.swap();
yend = y - BestXaosMandelbrotRenderer.FPRANGE;
if (BestXaosMandelbrotRenderer.DUMP_XAOS) {
AbstractMandelbrotRenderer.logger.fine("a0) yend = " + yend);
}
if (yend < 0) {
yend = 0;
}
p = ps;
while (delta[p] < yend) {
p += 1;
}
ps1 = p;
yend = y + BestXaosMandelbrotRenderer.FPRANGE;
if (BestXaosMandelbrotRenderer.DUMP_XAOS) {
AbstractMandelbrotRenderer.logger.fine("a1) yend = " + yend);
}
if (BestXaosMandelbrotRenderer.DUMP_XAOS) {
AbstractMandelbrotRenderer.logger.fine("b0) i = " + i + ", y = " + y + ", ps1 = " + ps1 + ", ps = " + ps + ", pe = " + pe);
}
if ((ps != pe) && (p > ps)) {
if (p < pe) {
prevData = dynamic.oldBest[p - 1];
if (BestXaosMandelbrotRenderer.DUMP_XAOS) {
AbstractMandelbrotRenderer.logger.fine("c0) previous = " + prevData.toString());
}
}
else {
prevData = dynamic.oldBest[pe - 1];
if (BestXaosMandelbrotRenderer.DUMP_XAOS) {
AbstractMandelbrotRenderer.logger.fine("c1) previous = " + prevData.toString());
}
}
price1 = prevData.price;
}
else {
if (i > 0) {
prevData = dynamic.calData[i - 1];
price1 = prevData.price;
if (BestXaosMandelbrotRenderer.DUMP_XAOS) {
AbstractMandelbrotRenderer.logger.fine("c2) previous = " + prevData.toString());
}
}
else {
prevData = null;
price1 = 0;
if (BestXaosMandelbrotRenderer.DUMP_XAOS) {
AbstractMandelbrotRenderer.logger.fine("c3) previous = null");
}
}
}
tmpData = dynamic.calData[i];
price = price1 + BestXaosMandelbrotRenderer.NEW_PRICE;
if (BestXaosMandelbrotRenderer.DUMP_XAOS) {
AbstractMandelbrotRenderer.logger.fine("d0) add row/column " + i + ": price = " + price + " (previous price = " + price1 + ")");
}
bestData = tmpData;
bestPrice = price;
tmpData.price = price;
tmpData.pos = -1;
tmpData.previous = prevData;
if (BestXaosMandelbrotRenderer.DUMP_XAOS) {
// Toolbox.println("d1) bestprice = " + bestprice + ", bestdata = " + bestdata.toString());
}
if (ps != pe) {
if (p == ps) {
if (delta[p] != delta[p + 1]) {
prevData = dynamic.calData[i - 1];
price1 = prevData.price;
price = price1 + BestXaosMandelbrotRenderer.price(delta[p], y);
if (BestXaosMandelbrotRenderer.DUMP_XAOS) {
AbstractMandelbrotRenderer.logger.fine("g0) approximate row/column " + i + " with old row/column " + p + ": price = " + price + " (previous price = " + price1 + ")");
}
if (price < bestPrice) {
tmpData = dynamic.conData[(p << BestXaosMandelbrotRenderer.DSIZE) + (i & BestXaosMandelbrotRenderer.MASK)];
bestData = tmpData;
bestPrice = price;
tmpData.price = price;
tmpData.pos = p;
tmpData.previous = prevData;
if (BestXaosMandelbrotRenderer.DUMP_XAOS) {
// Toolbox.println("g1) bestprice = " + bestprice + ", bestdata = " + bestdata.toString());
}
}
}
if (BestXaosMandelbrotRenderer.DUMP_XAOS) {
AbstractMandelbrotRenderer.logger.fine("g2) store data: p = " + p + ", bestdata = " + bestData.toString());
}
dynamic.newBest[p++] = bestData;
}
prevData = null;
price1 = price;
while (p < pe) {
if (delta[p] != delta[p + 1]) {
// if (prevData != dynamic.oldBest[p - 1])
// {
prevData = dynamic.oldBest[p - 1];
price1 = prevData.price;
price = price1 + BestXaosMandelbrotRenderer.NEW_PRICE;
if (BestXaosMandelbrotRenderer.DUMP_XAOS) {
AbstractMandelbrotRenderer.logger.fine("h0) add row/column " + i + ": price = " + price + " (previous price = " + price1 + ")");
}
if (price < bestPrice) {
tmpData = dynamic.conData[((p - 1) << BestXaosMandelbrotRenderer.DSIZE) + (i & BestXaosMandelbrotRenderer.MASK)];
bestData = tmpData;
bestPrice = price;
tmpData.price = price;
tmpData.pos = -1;
tmpData.previous = prevData;
if (BestXaosMandelbrotRenderer.DUMP_XAOS) {
AbstractMandelbrotRenderer.logger.fine("h1) store data: p - 1 = " + (p - 1) + ", bestdata = " + bestData.toString());
}
dynamic.newBest[p - 1] = bestData;
if (BestXaosMandelbrotRenderer.DUMP_XAOS) {
// Toolbox.println("h2) bestprice = " + bestprice + ", bestdata = " + bestdata.toString());
}
}
price = price1 + BestXaosMandelbrotRenderer.price(delta[p], y);
if (BestXaosMandelbrotRenderer.DUMP_XAOS) {
AbstractMandelbrotRenderer.logger.fine("h3) approximate row/column " + i + " with old row/column " + p + ": price = " + price + " (previous price = " + price1 + ")");
}
if (price < bestPrice) {
tmpData = dynamic.conData[(p << BestXaosMandelbrotRenderer.DSIZE) + (i & BestXaosMandelbrotRenderer.MASK)];
bestData = tmpData;
bestPrice = price;
tmpData.price = price;
tmpData.pos = p;
tmpData.previous = prevData;
if (BestXaosMandelbrotRenderer.DUMP_XAOS) {
// Toolbox.println("h4) bestprice = " + bestprice + ", bestdata = " + bestdata.toString());
}
}
else if (delta[p] > y) {
if (BestXaosMandelbrotRenderer.DUMP_XAOS) {
AbstractMandelbrotRenderer.logger.fine("h5) store data: p = " + p + ", bestdata = " + bestData.toString());
}
dynamic.newBest[p++] = bestData;
break;
}
// }
}
if (BestXaosMandelbrotRenderer.DUMP_XAOS) {
AbstractMandelbrotRenderer.logger.fine("h6) store data: p = " + p + ", bestdata = " + bestData.toString());
}
dynamic.newBest[p++] = bestData;
}
while (p < pe) {
if (delta[p] != delta[p + 1]) {
// if (prevData != dynamic.oldBest[p - 1])
// {
prevData = dynamic.oldBest[p - 1];
price1 = prevData.price;
price = price1 + BestXaosMandelbrotRenderer.NEW_PRICE;
if (BestXaosMandelbrotRenderer.DUMP_XAOS) {
AbstractMandelbrotRenderer.logger.fine("i0) add row/column " + i + ": price = " + price + " (previous price = " + price1 + ")");
}
if (price < bestPrice) {
tmpData = dynamic.conData[((p - 1) << BestXaosMandelbrotRenderer.DSIZE) + (i & BestXaosMandelbrotRenderer.MASK)];
bestData = tmpData;
bestPrice = price;
tmpData.price = price;
tmpData.pos = -1;
tmpData.previous = prevData;
if (BestXaosMandelbrotRenderer.DUMP_XAOS) {
AbstractMandelbrotRenderer.logger.fine("i1) store data: p - 1 = " + (p - 1) + ", bestdata = " + bestData.toString());
}
dynamic.newBest[p - 1] = bestData;
if (BestXaosMandelbrotRenderer.DUMP_XAOS) {
// Toolbox.println("i2) bestprice = " + bestprice + ", bestdata = " + bestdata.toString());
}
}
price = price1 + BestXaosMandelbrotRenderer.price(delta[p], y);
if (BestXaosMandelbrotRenderer.DUMP_XAOS) {
AbstractMandelbrotRenderer.logger.fine("i3) add row/column " + i + ": price = " + price + " (previous price = " + price1 + ")");
}
if (price < bestPrice) {
tmpData = dynamic.conData[(p << BestXaosMandelbrotRenderer.DSIZE) + (i & BestXaosMandelbrotRenderer.MASK)];
bestData = tmpData;
bestPrice = price;
tmpData.price = price;
tmpData.pos = p;
tmpData.previous = prevData;
if (BestXaosMandelbrotRenderer.DUMP_XAOS) {
AbstractMandelbrotRenderer.logger.fine("i4) bestprice = " + bestPrice + ", bestdata = " + bestData.toString());
}
}
// }
}
if (BestXaosMandelbrotRenderer.DUMP_XAOS) {
// Toolbox.println("i5) store data: p = " + p + ", bestdata = " + bestdata.toString());
}
dynamic.newBest[p++] = bestData;
}
if (p > ps) {
prevData = dynamic.oldBest[p - 1];
price1 = prevData.price;
}
else {
prevData = dynamic.calData[i - 1];
price1 = prevData.price;
}
price = price1 + BestXaosMandelbrotRenderer.NEW_PRICE;
if (BestXaosMandelbrotRenderer.DUMP_XAOS) {
AbstractMandelbrotRenderer.logger.fine("l0) add row/column " + i + ": price = " + price + " (previous price = " + price1 + ")");
}
if ((price < bestPrice) && (p > ps1)) {
tmpData = dynamic.conData[((p - 1) << BestXaosMandelbrotRenderer.DSIZE) + (i & BestXaosMandelbrotRenderer.MASK)];
bestData = tmpData;
bestPrice = price;
tmpData.price = price;
tmpData.pos = -1;
tmpData.previous = prevData;
if (BestXaosMandelbrotRenderer.DUMP_XAOS) {
AbstractMandelbrotRenderer.logger.fine("l1) store data: p - 1 = " + (p - 1) + ", bestdata = " + bestData.toString());
}
dynamic.newBest[p - 1] = bestData;
if (BestXaosMandelbrotRenderer.DUMP_XAOS) {
// Toolbox.println("l2) bestprice = " + bestprice + ", bestdata = " + bestdata.toString());
}
}
while (delta[p] < yend) {
if (delta[p] != delta[p + 1]) {
price = price1 + BestXaosMandelbrotRenderer.price(delta[p], y);
if (BestXaosMandelbrotRenderer.DUMP_XAOS) {
AbstractMandelbrotRenderer.logger.fine("l3) approximate row/column " + i + " with old row/column " + p + ": price = " + price + " (previous price = " + price1 + ")");
}
if (price < bestPrice) {
tmpData = dynamic.conData[(p << BestXaosMandelbrotRenderer.DSIZE) + (i & BestXaosMandelbrotRenderer.MASK)];
bestData = tmpData;
bestPrice = price;
tmpData.price = price;
tmpData.pos = p;
tmpData.previous = prevData;
if (BestXaosMandelbrotRenderer.DUMP_XAOS) {
// Toolbox.println("l4) bestprice = " + bestprice + ", bestdata = " + bestdata.toString());
}
}
else if (delta[p] > y) {
break;
}
}
if (BestXaosMandelbrotRenderer.DUMP_XAOS) {
AbstractMandelbrotRenderer.logger.fine("l5) store data: p = " + p + ", bestdata = " + bestData.toString());
}
dynamic.newBest[p++] = bestData;
}
while (delta[p] < yend) {
if (BestXaosMandelbrotRenderer.DUMP_XAOS) {
AbstractMandelbrotRenderer.logger.fine("l6) store data: p = " + p + ", bestdata = " + bestData.toString());
}
dynamic.newBest[p++] = bestData;
}
}
else {
if (delta[p] < yend) {
if (i > 0) {
prevData = dynamic.calData[i - 1];
price1 = prevData.price;
if (BestXaosMandelbrotRenderer.DUMP_XAOS) {
AbstractMandelbrotRenderer.logger.fine("e0) previous = " + prevData.toString());
}
}
else {
prevData = null;
price1 = 0;
if (BestXaosMandelbrotRenderer.DUMP_XAOS) {
AbstractMandelbrotRenderer.logger.fine("e1) previous = null");
}
}
while (delta[p] < yend) {
if (delta[p] != delta[p + 1]) {
price = price1 + BestXaosMandelbrotRenderer.price(delta[p], y);
if (BestXaosMandelbrotRenderer.DUMP_XAOS) {
AbstractMandelbrotRenderer.logger.fine("f0) approximate row/column " + i + " with old row/column " + p + ": price = " + price + " (previous price = " + price1 + ")");
}
if (price < bestPrice) {
tmpData = dynamic.conData[(p << BestXaosMandelbrotRenderer.DSIZE) + (i & BestXaosMandelbrotRenderer.MASK)];
bestData = tmpData;
bestPrice = price;
tmpData.price = price;
tmpData.pos = p;
tmpData.previous = prevData;
if (BestXaosMandelbrotRenderer.DUMP_XAOS) {
// Toolbox.println("f1) bestprice = " + bestprice + ", bestdata = " + bestdata.toString());
}
}
else if (delta[p] > y) {
break;
}
}
if (BestXaosMandelbrotRenderer.DUMP_XAOS) {
AbstractMandelbrotRenderer.logger.fine("f2) store data: p = " + p + ", bestdata = " + bestData.toString());
}
dynamic.newBest[p++] = bestData;
}
while (delta[p] < yend) {
if (BestXaosMandelbrotRenderer.DUMP_XAOS) {
AbstractMandelbrotRenderer.logger.fine("f3) store data: p = " + p + ", bestdata = " + bestData.toString());
}
dynamic.newBest[p++] = bestData;
}
}
}
ps = ps1;
ps1 = pe;
pe = p;
y += BestXaosMandelbrotRenderer.FPMUL;
}
if ((begin > delta[0]) && (end < delta[size - 1])) {
flag = 1;
}
if ((delta[0] > 0) && (delta[size - 1] < (size * BestXaosMandelbrotRenderer.FPMUL))) {
flag = 2;
}
if (BestXaosMandelbrotRenderer.DUMP_XAOS) {
AbstractMandelbrotRenderer.logger.fine("flag = " + flag);
}
if (BestXaosMandelbrotRenderer.DUMP_XAOS) {
AbstractMandelbrotRenderer.logger.fine("best table:");
}
for (i = size - 1; i >= 0; i--) {
if (BestXaosMandelbrotRenderer.DUMP_XAOS) {
AbstractMandelbrotRenderer.logger.fine("data = " + bestData.toString());
}
tmpData = bestData.previous;
tmpRealloc = realloc[i];
tmpRealloc.symTo = -1;
tmpRealloc.symRef = -1;
if (bestData.pos < 0) {
tmpRealloc.recalculate = true;
tmpRealloc.refreshed = false;
tmpRealloc.dirty = true;
tmpRealloc.isCached = false;
tmpRealloc.plus = tmpRealloc.pos;
}
else {
tmpRealloc.plus = bestData.pos;
tmpRealloc.position = position[bestData.pos];
if (invalidate) {
tmpRealloc.isCached = false;
}
tmpRealloc.recalculate = false;
tmpRealloc.refreshed = false;
tmpRealloc.dirty = false;
}
bestData = tmpData;
}
BestXaosMandelbrotRenderer.newPositions(realloc, size, begin, end, step, position, flag);
return step;
}
private static void newPositions(final Realloc[] realloc, final int size, double begin1, final double end1, final double step, final double[] position, final int flag) {
Realloc tmpRealloc = null;
double delta = 0;
double begin = 0;
double end = 0;
final int l = size;
int s = -1;
int e = -1;
if (begin1 > end1) {
begin1 = end1;
}
if (BestXaosMandelbrotRenderer.PRINT_POSITIONS) {
AbstractMandelbrotRenderer.logger.fine("Positions :");
}
while (s < (l - 1)) {
e = s + 1;
if (realloc[e].recalculate) {
while (e < l) {
if (!realloc[e].recalculate) {
break;
}
e++;
}
if (e < l) {
end = realloc[e].position;
}
else {
end = end1;
}
if (s < 0) {
begin = begin1;
}
else {
begin = realloc[s].position;
}
if ((e == l) && (begin > end)) {
end = begin;
}
if ((e - s) == 2) {
delta = (end - begin) * 0.5;
}
else {
delta = (end - begin) / (e - s);
}
switch (flag) {
case 1: {
for (s++; s < e; s++) {
begin += delta;
tmpRealloc = realloc[s];
tmpRealloc.position = begin;
tmpRealloc.priority = 1 / (1 + (Math.abs((position[s] - begin)) * step));
if (BestXaosMandelbrotRenderer.PRINT_POSITIONS) {
AbstractMandelbrotRenderer.logger.fine("pos = " + s + ",position = " + tmpRealloc.position + ",price = " + tmpRealloc.priority);
}
}
break;
}
case 2: {
for (s++; s < e; s++) {
begin += delta;
tmpRealloc = realloc[s];
tmpRealloc.position = begin;
tmpRealloc.priority = Math.abs((position[s] - begin)) * step;
if (BestXaosMandelbrotRenderer.PRINT_POSITIONS) {
AbstractMandelbrotRenderer.logger.fine("pos = " + s + ",position = " + tmpRealloc.position + ",price = " + tmpRealloc.priority);
}
}
break;
}
default: {
for (s++; s < e; s++) {
begin += delta;
tmpRealloc = realloc[s];
tmpRealloc.position = begin;
tmpRealloc.priority = 1.0;
if (BestXaosMandelbrotRenderer.PRINT_POSITIONS) {
AbstractMandelbrotRenderer.logger.fine("pos = " + s + ",position = " + tmpRealloc.position + ",price = " + tmpRealloc.priority);
}
}
break;
}
}
}
s = e;
}
}
private void processReallocTable(final boolean dynamic, final boolean refresh) {
if (BestXaosMandelbrotRenderer.DUMP) {
AbstractMandelbrotRenderer.logger.fine("Process ReallocTable...");
}
if (dynamic || !BestXaosMandelbrotRenderer.USE_XAOS) {
int total = 0;
total = BestXaosMandelbrotRenderer.initPrices(renderedData.queue, total, renderedData.reallocX);
total = BestXaosMandelbrotRenderer.initPrices(renderedData.queue, total, renderedData.reallocY);
if (BestXaosMandelbrotRenderer.DUMP) {
AbstractMandelbrotRenderer.logger.fine("total = " + total);
}
if (total > 0) {
if (total > 1) {
BestXaosMandelbrotRenderer.sortQueue(renderedData.queue, 0, total - 1);
}
processQueue(total);
}
if (BestXaosMandelbrotRenderer.USE_XAOS) {
processReallocTable(false, refresh);
}
}
else {
final int[] position = renderedData.position;
final int[] offset = renderedData.offset;
position[0] = 1;
offset[0] = 0;
int s = 1;
int i = 0;
int j = 0;
int tocalcx = 0;
int tocalcy = 0;
Realloc[] tmpRealloc = null;
tmpRealloc = renderedData.reallocX;
for (i = 0; i < tmpRealloc.length; i++) {
if (tmpRealloc[i].recalculate) {
tocalcx++;
}
}
tmpRealloc = renderedData.reallocY;
for (i = 0; i < tmpRealloc.length; i++) {
if (tmpRealloc[i].recalculate) {
tocalcy++;
}
}
for (i = 1; i < BestXaosMandelbrotRenderer.STEPS; i++) {
position[i] = 0;
}
while (s < BestXaosMandelbrotRenderer.STEPS) {
for (i = 0; i < BestXaosMandelbrotRenderer.STEPS; i++) {
if (position[i] == 0) {
for (j = i; j < BestXaosMandelbrotRenderer.STEPS; j++) {
if (position[j] != 0) {
break;
}
}
position[offset[s] = (j + i) >> 1] = 1;
s += 1;
}
}
}
// for (i = 0; i < position.length; i++)
// {
// System.out.println(i + " = " + position[i] + ", " + offset[i]);
// }
if (refresh) {
tmpRealloc = renderedData.reallocY;
for (final Realloc element : tmpRealloc) {
if (element.isCached && !element.refreshed) {
refreshLine(element, renderedData.reallocX, renderedData.reallocY);
}
}
tmpRealloc = renderedData.reallocX;
for (final Realloc element : tmpRealloc) {
if (element.isCached && !element.refreshed) {
refreshColumn(element, renderedData.reallocX, renderedData.reallocY);
}
}
}
renderedData.oldTime = renderedData.newTime = System.currentTimeMillis();
for (s = 0; !isAborted && (s < BestXaosMandelbrotRenderer.STEPS); s++) {
// AbstractFractalRenderer.logger.fine("step = " + s);
tmpRealloc = renderedData.reallocY;
for (i = offset[s]; !isAborted && (i < tmpRealloc.length); i += BestXaosMandelbrotRenderer.STEPS) {
if (tmpRealloc[i].recalculate) {
renderLine(tmpRealloc[i], renderedData.reallocX, renderedData.reallocY);
tocalcy -= 1;
}
else if (!tmpRealloc[i].isCached) {
renderLine(tmpRealloc[i], renderedData.reallocX, renderedData.reallocY);
}
if (isInterrupted()) {
isAborted = true;
break;
}
Thread.yield();
}
tmpRealloc = renderedData.reallocX;
for (i = offset[s]; !isAborted && (i < tmpRealloc.length); i += BestXaosMandelbrotRenderer.STEPS) {
if (tmpRealloc[i].recalculate) {
renderColumn(tmpRealloc[i], renderedData.reallocX, renderedData.reallocY);
tocalcx -= 1;
}
else if (!tmpRealloc[i].isCached) {
renderColumn(tmpRealloc[i], renderedData.reallocX, renderedData.reallocY);
}
if (isInterrupted()) {
isAborted = true;
break;
}
Thread.yield();
}
renderedData.newTime = System.currentTimeMillis();
if (!isAborted && ((renderedData.newTime - renderedData.oldTime) > 50) && (s < BestXaosMandelbrotRenderer.STEPS)) {
tmpRealloc = renderedData.reallocY;
for (i = 0; i < tmpRealloc.length; i++) {
tmpRealloc[i].changeDirty = tmpRealloc[i].dirty;
tmpRealloc[i].changePosition = tmpRealloc[i].position;
}
tmpRealloc = renderedData.reallocX;
for (i = 0; i < tmpRealloc.length; i++) {
tmpRealloc[i].changeDirty = tmpRealloc[i].dirty;
tmpRealloc[i].changePosition = tmpRealloc[i].position;
}
percent = (int) (((s + 1) * 100) / (float) BestXaosMandelbrotRenderer.STEPS);
fill();
copy();
Thread.yield();
tmpRealloc = renderedData.reallocY;
for (i = 0; i < tmpRealloc.length; i++) {
tmpRealloc[i].dirty = tmpRealloc[i].changeDirty;
tmpRealloc[i].position = tmpRealloc[i].changePosition;
}
tmpRealloc = renderedData.reallocX;
for (i = 0; i < tmpRealloc.length; i++) {
tmpRealloc[i].dirty = tmpRealloc[i].changeDirty;
tmpRealloc[i].position = tmpRealloc[i].changePosition;
}
renderedData.oldTime = renderedData.newTime;
}
// if (isInterrupted())
// {
// isAborted = true;
// break;
// }
}
if (!isAborted) {
percent = 100;
}
}
fill();
copy();
Thread.yield();
}
private void move() {
BestXaosMandelbrotRenderer.prepareMove(renderedData.moveTable, renderedData.reallocX);
doMove(renderedData.moveTable, renderedData.reallocY);
}
private void fill() {
if (isVerticalSymetrySupported && isHorizontalSymetrySupported) {
doSymetry(renderedData.reallocX, renderedData.reallocY);
}
BestXaosMandelbrotRenderer.prepareFill(renderedData.fillTable, renderedData.reallocX);
doFill(renderedData.fillTable, renderedData.reallocY);
}
private void copy() {
final Graphics2D g2d = getGraphics();
g2d.setComposite(AlphaComposite.Src);
g2d.drawImage(renderedData.newBuffer, 0, 0, null);
}
private static int initPrices(final Realloc[] queue, int total, final Realloc[] realloc) {
int i = 0;
int j = 0;
for (i = 0; i < realloc.length; i++) {
if (realloc[i].recalculate) {
for (j = i; (j < realloc.length) && realloc[j].recalculate; j++) {
queue[total++] = realloc[j];
}
if (j == realloc.length) {
j -= 1;
}
BestXaosMandelbrotRenderer.addPrices(realloc, i, j);
i = j;
}
}
return total;
}
private static void sortQueue(final Realloc[] queue, final int l, final int r) {
if (BestXaosMandelbrotRenderer.DUMP) {
AbstractMandelbrotRenderer.logger.fine("Sort queue...");
}
final double m = (queue[l].priority + queue[r].priority) / 2.0;
Realloc t = null;
int i = l;
int j = r;
do {
while (queue[i].priority > m) {
i++;
}
while (queue[j].priority < m) {
j--;
}
if (i <= j) {
t = queue[i];
queue[i] = queue[j];
queue[j] = t;
i++;
j--;
}
}
while (j >= i);
if (l < j) {
BestXaosMandelbrotRenderer.sortQueue(queue, l, j);
}
if (r > i) {
BestXaosMandelbrotRenderer.sortQueue(queue, i, r);
}
}
private void processQueue(final int size) {
if (BestXaosMandelbrotRenderer.DUMP) {
AbstractMandelbrotRenderer.logger.fine("Process queue...");
}
int i = 0;
for (i = 0; i < size; i++) {
if (renderedData.queue[i].line) {
renderLine(renderedData.queue[i], renderedData.reallocX, renderedData.reallocY);
}
else {
renderColumn(renderedData.queue[i], renderedData.reallocX, renderedData.reallocY);
}
if (isInterrupted()) {
isAborted = true;
break;
}
Thread.yield();
}
}
private void doSymetry(final Realloc[] reallocX, final Realloc[] reallocY) {
if (BestXaosMandelbrotRenderer.DUMP) {
AbstractMandelbrotRenderer.logger.fine("Do symetry...");
}
final int rowsize = getBufferWidth();
int from_offset = 0;
int to_offset = 0;
int i = 0;
int j = 0;
for (i = 0; i < reallocY.length; i++) {
if ((reallocY[i].symTo >= 0) && (!reallocY[reallocY[i].symTo].dirty)) {
from_offset = reallocY[i].symTo * rowsize;
System.arraycopy(renderedData.newRGB, from_offset, renderedData.newRGB, to_offset, rowsize);
if (useCache) {
System.arraycopy(renderedData.newCacheZR, from_offset, renderedData.newCacheZR, to_offset, rowsize);
System.arraycopy(renderedData.newCacheZI, from_offset, renderedData.newCacheZI, to_offset, rowsize);
System.arraycopy(renderedData.newCacheTR, from_offset, renderedData.newCacheTR, to_offset, rowsize);
System.arraycopy(renderedData.newCacheTI, from_offset, renderedData.newCacheTI, to_offset, rowsize);
System.arraycopy(renderedData.newCacheTime, from_offset, renderedData.newCacheTime, to_offset, rowsize);
}
if (BestXaosMandelbrotRenderer.SHOW_SYMETRY) {
for (int k = 0; k < rowsize; k++) {
renderedData.newRGB[to_offset + k] = Colors.mixColors(renderedData.newRGB[to_offset + k], 0xFFFF0000, 127);
}
}
reallocY[i].dirty = false;
reallocY[i].isCached = useCache;
}
to_offset += rowsize;
// Thread.yield();
}
for (i = 0; i < reallocX.length; i++) {
if ((reallocX[i].symTo >= 0) && (!reallocX[reallocX[i].symTo].dirty)) {
to_offset = i;
from_offset = reallocX[i].symTo;
final int[] newRGB = renderedData.newRGB;
final double[] newCacheZR = renderedData.newCacheZR;
final double[] newCacheZI = renderedData.newCacheZI;
final double[] newCacheTR = renderedData.newCacheTR;
final double[] newCacheTI = renderedData.newCacheTI;
final int[] newCacheTime = renderedData.newCacheTime;
for (j = 0; j < reallocY.length; j++) {
newRGB[to_offset] = newRGB[from_offset];
if (useCache) {
newCacheZR[to_offset] = newCacheZR[from_offset];
newCacheZI[to_offset] = newCacheZI[from_offset];
newCacheTR[to_offset] = newCacheTR[from_offset];
newCacheTI[to_offset] = newCacheTI[from_offset];
newCacheTime[to_offset] = newCacheTime[from_offset];
}
if (BestXaosMandelbrotRenderer.SHOW_SYMETRY) {
newRGB[to_offset] = Colors.mixColors(newRGB[to_offset], 0xFFFF0000, 127);
}
to_offset += rowsize;
from_offset += rowsize;
}
reallocX[i].dirty = false;
reallocX[i].isCached = useCache;
}
// Thread.yield();
}
}
private void doMove(final Movetable movetable, final Realloc[] reallocY) {
if (BestXaosMandelbrotRenderer.DUMP) {
AbstractMandelbrotRenderer.logger.fine("Do move...");
}
final Movetable.Data[] table = movetable.data;
Movetable.Data tmpData = null;
final int rowsize = getBufferWidth();
int new_offset = 0;
int old_offset = 0;
int from = 0;
int to = 0;
int i = 0;
int s = 0;
for (i = 0; i < reallocY.length; i++) {
if (!reallocY[i].dirty) {
s = 0;
old_offset = reallocY[i].plus * rowsize;
while ((tmpData = table[s]).length > 0) {
from = old_offset + tmpData.from;
to = new_offset + tmpData.to;
System.arraycopy(renderedData.oldRGB, from, renderedData.newRGB, to, tmpData.length);
if (useCache) {
System.arraycopy(renderedData.oldCacheZR, from, renderedData.newCacheZR, to, tmpData.length);
System.arraycopy(renderedData.oldCacheZI, from, renderedData.newCacheZI, to, tmpData.length);
System.arraycopy(renderedData.oldCacheTR, from, renderedData.newCacheTR, to, tmpData.length);
System.arraycopy(renderedData.oldCacheTI, from, renderedData.newCacheTI, to, tmpData.length);
System.arraycopy(renderedData.oldCacheTime, from, renderedData.newCacheTime, to, tmpData.length);
}
s += 1;
}
}
new_offset += rowsize;
// Thread.yield();
}
}
private void doFill(final Filltable filltable, final Realloc[] reallocY) {
if (BestXaosMandelbrotRenderer.DUMP) {
AbstractMandelbrotRenderer.logger.fine("Do fill...");
}
final Filltable.Data[] table = filltable.data;
Filltable.Data tmpData = null;
final int rowsize = getBufferWidth();
int from_offset = 0;
int to_offset = 0;
int from = 0;
int to = 0;
int i = 0;
int j = 0;
int k = 0;
int t = 0;
int s = 0;
int c = 0;
int d = 0;
// double c_xr = 0;
// double c_xi = 0;
// int c_time = 0;
for (i = 0; i < reallocY.length; i++) {
if (reallocY[i].dirty) {
j = i - 1;
for (k = i + 1; (k < reallocY.length) && reallocY[k].dirty; k++) {
;
}
while ((i < reallocY.length) && reallocY[i].dirty) {
if ((k < reallocY.length) && ((j < i) || ((reallocY[i].position - reallocY[j].position) > (reallocY[k].position - reallocY[i].position)))) {
j = k;
}
else {
if (j < 0) {
break;
}
}
to_offset = i * rowsize;
from_offset = j * rowsize;
if (!reallocY[j].dirty) {
s = 0;
final int[] newRGB = renderedData.newRGB;
// final double[] newCacheR = renderedData.newCacheR;
// final double[] newCacheI = renderedData.newCacheI;
// final int[] newCacheTime = renderedData.newCacheTime;
while ((tmpData = table[s]).length > 0) {
from = from_offset + tmpData.from;
to = from_offset + tmpData.to;
c = newRGB[from];
// if (useCache)
// {
// c_xr = newCacheR[from];
// c_xi = newCacheI[from];
// c_time = newCacheTime[from];
// }
for (t = 0; t < tmpData.length; t++) {
d = to + t;
newRGB[d] = c;
// if (useCache)
// {
// newCacheR[d] = c_xr;
// newCacheI[d] = c_xi;
// newCacheTime[d] = c_time;
// }
}
s += 1;
}
}
System.arraycopy(renderedData.newRGB, from_offset, renderedData.newRGB, to_offset, rowsize);
// if (useCache)
// {
// System.arraycopy(renderedData.newCacheR, from_offset, renderedData.newCacheR, to_offset, rowsize);
// System.arraycopy(renderedData.newCacheI, from_offset, renderedData.newCacheI, to_offset, rowsize);
// System.arraycopy(renderedData.newCacheTime, from_offset, renderedData.newCacheTime, to_offset, rowsize);
// }
reallocY[i].position = reallocY[j].position;
// reallocY[i].isCached = false;
reallocY[i].dirty = false;
i += 1;
}
}
else {
s = 0;
from_offset = i * rowsize;
final int[] newRGB = renderedData.newRGB;
// final double[] newCacheR = renderedData.newCacheR;
// final double[] newCacheI = renderedData.newCacheI;
// final int[] newCacheTime = renderedData.newCacheTime;
while ((tmpData = table[s]).length > 0) {
from = from_offset + tmpData.from;
to = from_offset + tmpData.to;
c = newRGB[from];
// if (useCache)
// {
// c_xr = newCacheR[from];
// c_xi = newCacheI[from];
// c_time = newCacheTime[from];
// }
for (t = 0; t < tmpData.length; t++) {
d = to + t;
newRGB[d] = c;
// if (useCache)
// {
// newCacheR[d] = c_xr;
// newCacheI[d] = c_xi;
// newCacheTime[d] = c_time;
// }
}
s += 1;
}
// reallocY[i].isCached = false;
reallocY[i].dirty = false;
}
// Thread.yield();
}
}
private void renderLine(final Realloc realloc, final Realloc[] reallocX, final Realloc[] reallocY) {
if (BestXaosMandelbrotRenderer.PRINT_CALCULATE) {
AbstractMandelbrotRenderer.logger.fine("Calculate line " + realloc.pos);
}
final int rowsize = getBufferWidth();
final double position = realloc.position;
final int r = realloc.pos;
int offset = r * rowsize;
int i;
int j;
int k;
int n;
double n_zr = 0;
double n_zi = 0;
double n_tr = 0;
double n_ti = 0;
int n_time = 0;
int distl = 0;
int distr = 0;
int distu = 0;
int distd = 0;
int offsetu;
int offsetd;
int offsetl;
int offsetul;
int offsetur;
int offsetdl;
int offsetdr;
int rend = r - BestXaosMandelbrotRenderer.GUESS_RANGE;
final Complex z = new Complex(0, 0);
final Complex w = new Complex(0, 0);
final RenderedPoint p = new RenderedPoint();
final int[] newRGB = renderedData.newRGB;
final double[] newCacheZR = renderedData.newCacheZR;
final double[] newCacheZI = renderedData.newCacheZI;
final double[] newCacheTR = renderedData.newCacheTR;
final double[] newCacheTI = renderedData.newCacheTI;
final int[] newCacheTime = renderedData.newCacheTime;
if (rend < 0) {
rend = 0;
}
for (i = r - 1; (i >= rend) && reallocY[i].dirty; i--) {
;
}
distu = r - i;
rend = r + BestXaosMandelbrotRenderer.GUESS_RANGE;
if (rend >= reallocY.length) {
rend = reallocY.length - 1;
}
for (j = r + 1; (j < rend) && reallocY[j].dirty; j++) {
;
}
distd = j - r;
if ((!isSolidguessSupported) || (i < 0) || (j >= reallocY.length) || reallocY[i].dirty || reallocY[j].dirty) {
for (k = 0; k < reallocX.length; k++) {
if (!reallocX[k].dirty) {
z.r = renderedData.x0;
z.i = renderedData.y0;
w.r = reallocX[k].position;
w.i = position;
p.pr = reallocX[k].position;
p.pi = position;
newRGB[offset] = renderingStrategy.renderPoint(p, z, w);
if (useCache) {
newCacheZR[offset] = p.zr;
newCacheZI[offset] = p.zi;
newCacheTR[offset] = p.tr;
newCacheTI[offset] = p.ti;
newCacheTime[offset] = p.time;
}
if (BestXaosMandelbrotRenderer.SHOW_CALCULATE) {
newRGB[offset] = Colors.mixColors(newRGB[offset], 0xFFFFFF00, 127);
}
}
offset += 1;
}
}
else {
distr = 0;
distl = Integer.MAX_VALUE / 2;
offsetu = offset - (distu * rowsize);
offsetd = offset + (distd * rowsize);
for (k = 0; k < reallocX.length; k++) {
if (!reallocX[k].dirty) {
if (distr <= 0) {
rend = k + BestXaosMandelbrotRenderer.GUESS_RANGE;
if (rend >= reallocX.length) {
rend = reallocX.length - 1;
}
for (j = k + 1; (j < rend) && reallocX[j].dirty; j++) {
distr = j - k;
}
if (j >= rend) {
distr = Integer.MAX_VALUE / 2;
}
}
if ((distr < (Integer.MAX_VALUE / 4)) && (distl < (Integer.MAX_VALUE / 4))) {
offsetl = offset - distl;
offsetul = offsetu - distl;
offsetdl = offsetd - distl;
offsetur = offsetu + distr;
offsetdr = offsetd + distr;
n = newRGB[offsetl];
if (useCache) {
n_zr = newCacheZR[offsetl];
n_zi = newCacheZI[offsetl];
n_tr = newCacheTR[offsetu];
n_ti = newCacheTI[offsetu];
n_time = newCacheTime[offsetl];
}
if ((n == newRGB[offsetu]) && (n == newRGB[offsetd]) && (n == newRGB[offsetul]) && (n == newRGB[offsetur]) && (n == newRGB[offsetdl]) && (n == newRGB[offsetdr])) {
newRGB[offset] = n;
if (useCache) {
newCacheZR[offset] = n_zr;
newCacheZI[offset] = n_zi;
newCacheTR[offset] = n_tr;
newCacheTI[offset] = n_ti;
newCacheTime[offset] = n_time;
}
if (BestXaosMandelbrotRenderer.SHOW_SOLIDGUESS) {
newRGB[offset] = Colors.mixColors(newRGB[offset], 0xFFFF0000, 127);
}
}
else {
z.r = renderedData.x0;
z.i = renderedData.y0;
w.r = reallocX[k].position;
w.i = position;
p.pr = reallocX[k].position;
p.pi = position;
newRGB[offset] = renderingStrategy.renderPoint(p, z, w);
if (useCache) {
newCacheZR[offset] = p.zr;
newCacheZI[offset] = p.zi;
newCacheTR[offset] = p.tr;
newCacheTI[offset] = p.ti;
newCacheTime[offset] = p.time;
}
if (BestXaosMandelbrotRenderer.SHOW_CALCULATE) {
newRGB[offset] = Colors.mixColors(newRGB[offset], 0xFFFFFF00, 127);
}
}
}
else {
z.r = renderedData.x0;
z.i = renderedData.y0;
w.r = reallocX[k].position;
w.i = position;
p.pr = reallocX[k].position;
p.pi = position;
newRGB[offset] = renderingStrategy.renderPoint(p, z, w);
if (useCache) {
newCacheZR[offset] = p.zr;
newCacheZI[offset] = p.zi;
newCacheTR[offset] = p.tr;
newCacheTI[offset] = p.ti;
newCacheTime[offset] = p.time;
}
if (BestXaosMandelbrotRenderer.SHOW_CALCULATE) {
newRGB[offset] = Colors.mixColors(newRGB[offset], 0xFFFFFF00, 127);
}
}
distl = 0;
}
offset += 1;
offsetu += 1;
offsetd += 1;
distr -= 1;
distl += 1;
}
}
realloc.recalculate = false;
realloc.refreshed = true;
realloc.dirty = false;
realloc.isCached = useCache;
}
private void renderColumn(final Realloc realloc, final Realloc[] reallocX, final Realloc[] reallocY) {
if (BestXaosMandelbrotRenderer.PRINT_CALCULATE) {
AbstractMandelbrotRenderer.logger.fine("Calculate column " + realloc.pos);
}
final int rowsize = getBufferWidth();
final double position = realloc.position;
final int r = realloc.pos;
int offset = r;
int rend = r - BestXaosMandelbrotRenderer.GUESS_RANGE;
int i;
int j;
int k;
int n;
double n_zr = 0;
double n_zi = 0;
double n_tr = 0;
double n_ti = 0;
int n_time = 0;
int distl = 0;
int distr = 0;
int distu = 0;
int distd = 0;
int offsetl;
int offsetr;
int offsetu;
int offsetlu;
int offsetru;
int offsetld;
int offsetrd;
int sumu;
int sumd;
final Complex z = new Complex(0, 0);
final Complex w = new Complex(0, 0);
final RenderedPoint p = new RenderedPoint();
final int[] newRGB = renderedData.newRGB;
final double[] newCacheZR = renderedData.newCacheZR;
final double[] newCacheZI = renderedData.newCacheZI;
final double[] newCacheTR = renderedData.newCacheTR;
final double[] newCacheTI = renderedData.newCacheTI;
final int[] newCacheTime = renderedData.newCacheTime;
if (rend < 0) {
rend = 0;
}
for (i = r - 1; (i >= rend) && reallocX[i].dirty; i--) {
;
}
distl = r - i;
rend = r + BestXaosMandelbrotRenderer.GUESS_RANGE;
if (rend >= reallocX.length) {
rend = reallocX.length - 1;
}
for (j = r + 1; (j < rend) && reallocX[j].dirty; j++) {
;
}
distr = j - r;
if ((!isSolidguessSupported) || (i < 0) || (j >= reallocX.length) || reallocX[i].dirty || reallocX[j].dirty) {
for (k = 0; k < reallocY.length; k++) {
if (!reallocY[k].dirty) {
z.r = renderedData.x0;
z.i = renderedData.y0;
w.r = position;
w.i = reallocY[k].position;
p.pr = position;
p.pi = reallocY[k].position;
newRGB[offset] = renderingStrategy.renderPoint(p, z, w);
if (useCache) {
newCacheZR[offset] = p.zr;
newCacheZI[offset] = p.zi;
newCacheTR[offset] = p.tr;
newCacheTI[offset] = p.ti;
newCacheTime[offset] = p.time;
}
if (BestXaosMandelbrotRenderer.SHOW_CALCULATE) {
newRGB[offset] = Colors.mixColors(newRGB[offset], 0xFFFFFF00, 127);
}
}
offset += rowsize;
}
}
else {
distd = 0;
distu = Integer.MAX_VALUE / 2;
offsetl = offset - distl;
offsetr = offset + distr;
for (k = 0; k < reallocY.length; k++) {
if (!reallocY[k].dirty) {
if (distd <= 0) {
rend = k + BestXaosMandelbrotRenderer.GUESS_RANGE;
if (rend >= reallocY.length) {
rend = reallocY.length - 1;
}
for (j = k + 1; (j < rend) && reallocY[j].dirty; j++) {
distd = j - k;
}
if (j >= rend) {
distd = Integer.MAX_VALUE / 2;
}
}
if ((distd < (Integer.MAX_VALUE / 4)) && (distu < (Integer.MAX_VALUE / 4))) {
sumu = distu * rowsize;
sumd = distd * rowsize;
offsetu = offset - sumu;
offsetlu = offsetl - sumu;
offsetru = offsetr - sumu;
offsetld = offsetl + sumd;
offsetrd = offsetr + sumd;
n = newRGB[offsetu];
if (useCache) {
n_zr = newCacheZR[offsetu];
n_zi = newCacheZI[offsetu];
n_tr = newCacheTR[offsetu];
n_ti = newCacheTI[offsetu];
n_time = newCacheTime[offsetu];
}
if ((n == newRGB[offsetl]) && (n == newRGB[offsetr]) && (n == newRGB[offsetlu]) && (n == newRGB[offsetru]) && (n == newRGB[offsetld]) && (n == newRGB[offsetrd])) {
newRGB[offset] = n;
if (useCache) {
newCacheZR[offset] = n_zr;
newCacheZI[offset] = n_zi;
newCacheTR[offset] = n_tr;
newCacheTI[offset] = n_ti;
newCacheTime[offset] = n_time;
}
if (BestXaosMandelbrotRenderer.SHOW_SOLIDGUESS) {
newRGB[offset] = Colors.mixColors(newRGB[offset], 0xFFFF0000, 127);
}
}
else {
z.r = renderedData.x0;
z.i = renderedData.y0;
w.r = position;
w.i = reallocY[k].position;
p.pr = position;
p.pi = reallocY[k].position;
newRGB[offset] = renderingStrategy.renderPoint(p, z, w);
if (useCache) {
newCacheZR[offset] = p.zr;
newCacheZI[offset] = p.zi;
newCacheTR[offset] = p.tr;
newCacheTI[offset] = p.ti;
newCacheTime[offset] = p.time;
}
if (BestXaosMandelbrotRenderer.SHOW_CALCULATE) {
newRGB[offset] = Colors.mixColors(newRGB[offset], 0xFFFFFF00, 127);
}
}
}
else {
z.r = renderedData.x0;
z.i = renderedData.y0;
w.r = position;
w.i = reallocY[k].position;
p.pr = position;
p.pi = reallocY[k].position;
newRGB[offset] = renderingStrategy.renderPoint(p, z, w);
if (useCache) {
newCacheZR[offset] = p.zr;
newCacheZI[offset] = p.zi;
newCacheTR[offset] = p.tr;
newCacheTI[offset] = p.ti;
newCacheTime[offset] = p.time;
}
if (BestXaosMandelbrotRenderer.SHOW_CALCULATE) {
newRGB[offset] = Colors.mixColors(newRGB[offset], 0xFFFFFF00, 127);
}
}
distu = 0;
}
offset += rowsize;
offsetl += rowsize;
offsetr += rowsize;
distd -= 1;
distu += 1;
}
}
realloc.recalculate = false;
realloc.refreshed = true;
realloc.dirty = false;
realloc.isCached = useCache;
}
private void refreshLine(final Realloc realloc, final Realloc[] reallocX, final Realloc[] reallocY) {
if (BestXaosMandelbrotRenderer.DUMP) {
AbstractMandelbrotRenderer.logger.fine("Refresh line...");
}
final int rowsize = getBufferWidth();
int offset = realloc.pos * rowsize;
int k = 0;
final RenderedPoint p = new RenderedPoint();
final int[] newRGB = renderedData.newRGB;
final double[] newCacheZR = renderedData.newCacheZR;
final double[] newCacheZI = renderedData.newCacheZI;
final double[] newCacheTR = renderedData.newCacheTR;
final double[] newCacheTI = renderedData.newCacheTI;
final int[] newCacheTime = renderedData.newCacheTime;
if (realloc.isCached && !realloc.refreshed) {
for (final Realloc tmpRealloc : reallocX) {
if (tmpRealloc.isCached && !tmpRealloc.refreshed) {
k = offset;
p.zr = newCacheZR[k];
p.zi = newCacheZI[k];
p.tr = newCacheTR[k];
p.ti = newCacheTI[k];
p.time = newCacheTime[k];
p.pr = tmpRealloc.position;
p.pi = realloc.position;
newRGB[k] = renderColor(p);
if (BestXaosMandelbrotRenderer.SHOW_REFRESH) {
newRGB[k] = Colors.mixColors(newRGB[k], 0xFF0000FF, 127);
}
}
offset += 1;
}
realloc.refreshed = true;
}
}
private void refreshColumn(final Realloc realloc, final Realloc[] reallocX, final Realloc[] reallocY) {
if (BestXaosMandelbrotRenderer.DUMP) {
AbstractMandelbrotRenderer.logger.fine("Refresh column...");
}
final int rowsize = getBufferWidth();
int offset = realloc.pos;
int k = 0;
final RenderedPoint p = new RenderedPoint();
final int[] newRGB = renderedData.newRGB;
final double[] newCacheZR = renderedData.newCacheZR;
final double[] newCacheZI = renderedData.newCacheZI;
final double[] newCacheTR = renderedData.newCacheTR;
final double[] newCacheTI = renderedData.newCacheTI;
final int[] newCacheTime = renderedData.newCacheTime;
if (realloc.isCached && !realloc.refreshed) {
for (final Realloc tmpRealloc : reallocY) {
if (tmpRealloc.isCached && !tmpRealloc.refreshed) {
k = offset;
p.zr = newCacheZR[k];
p.zi = newCacheZI[k];
p.tr = newCacheTR[k];
p.ti = newCacheTI[k];
p.time = newCacheTime[k];
p.pr = realloc.position;
p.pi = tmpRealloc.position;
newRGB[k] = renderColor(p);
if (BestXaosMandelbrotRenderer.SHOW_REFRESH) {
newRGB[k] = Colors.mixColors(newRGB[k], 0xFF0000FF, 127);
}
}
offset += rowsize;
}
realloc.refreshed = true;
}
}
/**
* @see net.sf.jame.AbstractMandelbrotRenderer.core.fractal.renderer.AbstractFractalRenderer#getMandelbrotRenderingStrategy()
*/
@Override
protected RenderingStrategy getMandelbrotRenderingStrategy() {
return mandelbrotRenderingStrategy;
}
/**
* @see net.sf.jame.AbstractMandelbrotRenderer.core.fractal.renderer.AbstractFractalRenderer#createJuliaRenderingStrategy()
*/
@Override
protected RenderingStrategy getJuliaRenderingStrategy() {
return juliaRenderingStrategy;
}
/**
* @author Andrea Medeghini
*/
public static class Movetable {
/**
*
*/
public Data[] data;
/**
* @param width
*/
public Movetable(final int width) {
data = new Data[width + 1];
for (int i = 0; i <= width; i++) {
data[i] = new Data();
}
}
/**
* @see java.lang.Object#finalize()
*/
public void finalize() throws Throwable {
data = null;
super.finalize();
}
/**
* @author Andrea Medeghini
*/
public class Data {
int length;
int from;
int to;
/**
* @see java.lang.Object#toString()
*/
public String toString() {
return "<from = " + from + ", to = " + to + ", length = " + length + ">";
}
}
}
/**
* @author Andrea Medeghini
*/
public static class Filltable {
/**
*
*/
public Data[] data;
/**
* @param width
*/
public Filltable(final int width) {
data = new Data[width + 1];
for (int i = 0; i <= width; i++) {
data[i] = new Data();
}
}
/**
* @see java.lang.Object#finalize()
*/
public void finalize() throws Throwable {
data = null;
super.finalize();
}
/**
* @author Andrea Medeghini
*/
public class Data {
int length;
int from;
int to;
/**
* @see java.lang.Object#toString()
*/
public String toString() {
return "<from = " + from + ", to = " + to + ", length = " + length + ">";
}
}
}
/**
* @author Andrea Medeghini
*/
public static class Dynamic {
/**
*
*/
public int[] delta;
/**
*
*/
public Data[] oldBest;
/**
*
*/
public Data[] newBest;
/**
*
*/
public Data[] calData;
/**
*
*/
public Data[] conData;
/**
* @param size
*/
public Dynamic(final int size) {
delta = new int[size + 1];
oldBest = new Data[size];
newBest = new Data[size];
calData = new Data[size];
conData = new Data[size << BestXaosMandelbrotRenderer.DSIZE];
for (int i = 0; i < size; i++) {
calData[i] = new Data();
}
for (int i = 0; i < (size << BestXaosMandelbrotRenderer.DSIZE); i++) {
conData[i] = new Data();
}
}
/**
* @see java.lang.Object#finalize()
*/
public void finalize() throws Throwable {
oldBest = null;
newBest = null;
calData = null;
conData = null;
super.finalize();
}
/**
*
*/
public void swap() {
final Dynamic.Data[] tmp_best = newBest;
newBest = oldBest;
oldBest = tmp_best;
}
/**
* @author Andrea Medeghini
*/
public class Data {
Data previous;
int pos;
int price;
/**
* @see java.lang.Object#toString()
*/
public String toString() {
return "<price = " + price + ", pos = " + pos + ">";
}
}
}
/**
* @author Andrea Medeghini
*/
public static class Realloc {
/**
*
*/
public boolean isCached;
/**
*
*/
public boolean refreshed;
/**
*
*/
public boolean recalculate;
/**
*
*/
public boolean changeDirty;
/**
*
*/
public boolean dirty;
/**
*
*/
public boolean line;
/**
*
*/
public int pos;
/**
*
*/
public int plus;
/**
*
*/
public int symTo;
/**
*
*/
public int symRef;
/**
*
*/
public double changePosition;
/**
*
*/
public double position;
/**
*
*/
public double priority;
/**
* @param line
*/
public Realloc(final boolean line) {
this.line = line;
}
/**
* @see java.lang.Object#toString()
*/
public String toString() {
return "<pos = " + pos + ", symref = " + symRef + ", symto = " + symTo + ", plus = " + plus + ", dirty = " + dirty + ", recalculate = " + recalculate + ", line = " + line + ", priority = " + priority + ", position = " + position + ", iscached = " + isCached + ">";
}
}
/**
* @author Andrea Medeghini
*/
public static class RendererData {
/**
*
*/
public BufferedImage newBuffer;
/**
*
*/
public BufferedImage oldBuffer;
/**
*
*/
public double[] newCacheZR;
/**
*
*/
public double[] newCacheZI;
/**
*
*/
public double[] newCacheTR;
/**
*
*/
public double[] newCacheTI;
/**
*
*/
public int[] newCacheTime;
/**
*
*/
public double[] oldCacheZR;
/**
*
*/
public double[] oldCacheZI;
/**
*
*/
public double[] oldCacheTR;
/**
*
*/
public double[] oldCacheTI;
/**
*
*/
public int[] oldCacheTime;
/**
*
*/
public int[] newRGB;
/**
*
*/
public int[] oldRGB;
/**
*
*/
public double[] positionX;
/**
*
*/
public double[] positionY;
/**
*
*/
public Realloc[] reallocX;
/**
*
*/
public Realloc[] reallocY;
/**
*
*/
public Dynamic dynamicx;
/**
*
*/
public Dynamic dynamicy;
/**
*
*/
public Movetable moveTable;
/**
*
*/
public Filltable fillTable;
/**
*
*/
public Realloc[] queue;
/**
*
*/
public double x0 = 0;
/**
*
*/
public double y0 = 0;
/**
*
*/
public long newTime;
/**
*
*/
public long oldTime;
/**
*
*/
public final int[] position = new int[BestXaosMandelbrotRenderer.STEPS];
/**
*
*/
public final int[] offset = new int[BestXaosMandelbrotRenderer.STEPS];
/**
* @see java.lang.Object#finalize()
*/
public void finalize() throws Throwable {
free();
super.finalize();
}
/**
*
*/
public void free() {
positionX = null;
positionY = null;
reallocX = null;
reallocY = null;
dynamicx = null;
dynamicy = null;
moveTable = null;
fillTable = null;
queue = null;
newCacheZR = null;
newCacheZI = null;
newCacheTR = null;
newCacheTI = null;
newCacheTime = null;
oldCacheZR = null;
oldCacheZI = null;
oldCacheTR = null;
oldCacheTI = null;
oldCacheTime = null;
if (newBuffer != null) {
newBuffer.flush();
}
newBuffer = null;
newRGB = null;
if (oldBuffer != null) {
oldBuffer.flush();
}
oldBuffer = null;
oldRGB = null;
}
/**
* @param width
* @param height
*/
public void reallocate(final int width, final int height) {
positionX = new double[width];
positionY = new double[height];
reallocX = new Realloc[width];
reallocY = new Realloc[height];
dynamicx = new Dynamic(width);
dynamicy = new Dynamic(height);
moveTable = new Movetable(width);
fillTable = new Filltable(width);
queue = new Realloc[reallocX.length + reallocY.length];
for (int i = 0; i < width; i++) {
reallocX[i] = new Realloc(false);
reallocX[i].pos = i;
positionX[i] = 0;
}
for (int i = 0; i < height; i++) {
reallocY[i] = new Realloc(true);
reallocY[i].pos = i;
positionY[i] = 0;
}
newBuffer = new BufferedImage(width, height, Surface.DEFAULT_TYPE);
newRGB = ((DataBufferInt) newBuffer.getRaster().getDataBuffer()).getData();
oldBuffer = new BufferedImage(width, height, Surface.DEFAULT_TYPE);
oldRGB = ((DataBufferInt) oldBuffer.getRaster().getDataBuffer()).getData();
newCacheZR = new double[width * height];
newCacheZI = new double[width * height];
newCacheTR = new double[width * height];
newCacheTI = new double[width * height];
newCacheTime = new int[width * height];
oldCacheZR = new double[width * height];
oldCacheZI = new double[width * height];
oldCacheTR = new double[width * height];
oldCacheTI = new double[width * height];
oldCacheTime = new int[width * height];
}
/**
*
*/
public void swap() {
final int[] tmpRGB = oldRGB;
final BufferedImage tmpBuffer = oldBuffer;
oldRGB = newRGB;
oldBuffer = newBuffer;
newRGB = tmpRGB;
newBuffer = tmpBuffer;
final double[] tmpCacheZR = oldCacheZR;
final double[] tmpCacheZI = oldCacheZI;
final double[] tmpCacheTR = oldCacheTR;
final double[] tmpCacheTI = oldCacheTI;
final int[] tmpCacheTime = oldCacheTime;
oldCacheZR = newCacheZR;
oldCacheZI = newCacheZI;
oldCacheTR = newCacheTR;
oldCacheTI = newCacheTI;
oldCacheTime = newCacheTime;
newCacheZR = tmpCacheZR;
newCacheZI = tmpCacheZI;
newCacheTR = tmpCacheTR;
newCacheTI = tmpCacheTI;
newCacheTime = tmpCacheTime;
}
}
private class MandelbrotRenderingStrategy implements RenderingStrategy {
/**
* @see net.sf.jame.mandelbrot.renderer.AbstractMandelbrotRenderer.RenderingStrategy#isVerticalSymetrySupported()
*/
public boolean isVerticalSymetrySupported() {
for (int i = 0; i < fractalRuntime.getOutcolouringFormulaCount(); i++) {
final OutcolouringFormulaRuntimeElement outcolouringFormula = fractalRuntime.getOutcolouringFormula(i);
if ((outcolouringFormula.getFormulaRuntime() != null) && !outcolouringFormula.getFormulaRuntime().isVerticalSymetryAllowed()) {
return false;
}
}
for (int i = 0; i < fractalRuntime.getIncolouringFormulaCount(); i++) {
final IncolouringFormulaRuntimeElement incolouringFormula = fractalRuntime.getIncolouringFormula(i);
if ((incolouringFormula.getFormulaRuntime() != null) && !incolouringFormula.getFormulaRuntime().isVerticalSymetryAllowed()) {
return false;
}
}
return true;
}
/**
* @see net.sf.jame.mandelbrot.renderer.AbstractMandelbrotRenderer.RenderingStrategy#isHorizontalSymetrySupported()
*/
public boolean isHorizontalSymetrySupported() {
for (int i = 0; i < fractalRuntime.getOutcolouringFormulaCount(); i++) {
final OutcolouringFormulaRuntimeElement outcolouringFormula = fractalRuntime.getOutcolouringFormula(i);
if ((outcolouringFormula.getFormulaRuntime() != null) && !outcolouringFormula.getFormulaRuntime().isHorizontalSymetryAllowed()) {
return false;
}
}
for (int i = 0; i < fractalRuntime.getIncolouringFormulaCount(); i++) {
final IncolouringFormulaRuntimeElement incolouringFormula = fractalRuntime.getIncolouringFormula(i);
if ((incolouringFormula.getFormulaRuntime() != null) && !incolouringFormula.getFormulaRuntime().isHorizontalSymetryAllowed()) {
return false;
}
}
return true;
}
/**
* @see net.sf.jame.mandelbrot.renderer.AbstractMandelbrotRenderer.RenderingStrategy#renderPoint(net.sf.jame.mandelbrot.renderer.RenderedPoint)
*/
public int renderPoint(final RenderedPoint p, final Complex px, final Complex pw) {
if ((fractalRuntime.getRenderingFormula().getFormulaRuntime() != null) && (fractalRuntime.getTransformingFormula().getFormulaRuntime() != null)) {
fractalRuntime.getTransformingFormula().getFormulaRuntime().renderPoint(pw);
p.xr = px.r;
p.xi = px.i;
p.wr = pw.r;
p.wi = pw.i;
p.dr = 0;
p.di = 0;
p.tr = 0;
p.ti = 0;
return BestXaosMandelbrotRenderer.this.renderPoint(p);
}
return 0;
}
/**
* @see net.sf.jame.mandelbrot.renderer.AbstractMandelbrotRenderer.RenderingStrategy#updateParameters()
*/
public void updateParameters() {
if (fractalRuntime.getRenderingFormula().getFormulaRuntime() != null) {
renderedData.x0 = fractalRuntime.getRenderingFormula().getFormulaRuntime().getInitialPoint().r;
renderedData.y0 = fractalRuntime.getRenderingFormula().getFormulaRuntime().getInitialPoint().i;
}
else {
renderedData.x0 = 0;
renderedData.y0 = 0;
}
}
}
private class JuliaRenderingStrategy implements RenderingStrategy {
/**
* @see net.sf.jame.mandelbrot.renderer.AbstractMandelbrotRenderer.RenderingStrategy#isHorizontalSymetrySupported()
*/
public boolean isHorizontalSymetrySupported() {
return false;
}
/**
* @see net.sf.jame.mandelbrot.renderer.AbstractMandelbrotRenderer.RenderingStrategy#isVerticalSymetrySupported()
*/
public boolean isVerticalSymetrySupported() {
return false;
}
/**
* @see net.sf.jame.mandelbrot.renderer.AbstractMandelbrotRenderer.RenderingStrategy#renderPoint(net.sf.jame.mandelbrot.renderer.RenderedPoint)
*/
public int renderPoint(final RenderedPoint p, final Complex px, final Complex pw) {
if ((fractalRuntime.getRenderingFormula().getFormulaRuntime() != null) && (fractalRuntime.getTransformingFormula().getFormulaRuntime() != null)) {
fractalRuntime.getTransformingFormula().getFormulaRuntime().renderPoint(px);
p.xr = pw.r;
p.xi = pw.i;
p.wr = px.r;
p.wi = px.i;
p.dr = 0;
p.di = 0;
p.tr = 0;
p.ti = 0;
return BestXaosMandelbrotRenderer.this.renderPoint(p);
}
return 0;
}
/**
* @see net.sf.jame.mandelbrot.renderer.AbstractMandelbrotRenderer.RenderingStrategy#updateParameters()
*/
public void updateParameters() {
renderedData.x0 = oldConstant.getX();
renderedData.y0 = oldConstant.getY();
}
}
private class MandelbrotWorker2 extends RenderWorker {
/**
*
*/
public MandelbrotWorker2() {
super(factory);
}
/**
*
*/
@Override
protected void execute() {
prepareColumns();
}
}
// private class PrepareLinesWorker extends RenderWorker {
// /**
// *
// */
// public PrepareLinesWorker() {
// super(factory);
// }
//
// /**
// * @param runnable
// * @return
// */
// @Override
// protected Thread createThread(final Runnable runnable) {
// Thread thread = super.createThread(runnable);
// thread.setName("PrepareLinesWorker");
// return thread;
// }
//
// /**
// *
// */
// @Override
// protected void execute() {
// prepareLines();
// }
// }
//
// private class PrepareColumnsWorker extends RenderWorker {
// /**
// *
// */
// public PrepareColumnsWorker() {
// super(factory);
// }
//
// /**
// * @param runnable
// * @return
// */
// @Override
// protected Thread createThread(final Runnable runnable) {
// Thread thread = super.createThread(runnable);
// thread.setName("PrepareColumnsWorker");
// return thread;
// }
//
// /**
// *
// */
// @Override
// protected void execute() {
// prepareColumns();
// }
// }
}