You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

119 lines
3.2 KiB
Java

package deepZoom.fractals;
import deepZoom.renderer.PointInfo;
/**
* @author Zom-B
* @since 1.0
* @date 2009/07/09
*/
public class Mandel extends Fractal {
private static final double PRIODICITY_EPS = 1e-17;
@Override
public void initFrame() {
}
@Override
public void calcPoint(PointInfo pointInfo) {
double zx;
double zy;
double xx;
double yy;
double bailout = parameters.getBailout();
long maxiter = parameters.getMaxiter();
// Calculate viewport.
double px = pointInfo.px.hi;
double py = pointInfo.py.hi;
// Main bulb check.
zx = 4 * (px * px + py * py);
xx = 2 * px;
zy = zx + 4 * xx;
if (zy < -3.75) {
pointInfo.inside = true;
pointInfo.lastIter = maxiter;
pointInfo.lastZX.hi = px;
pointInfo.lastZY.hi = py;
return;
}
// Cardoid check.
zy = zx - xx + 0.25;
xx = xx + zy - 0.5;
xx *= xx;
if (zy > xx) {
pointInfo.inside = true;
pointInfo.lastIter = maxiter;
pointInfo.lastZX.hi = px;
pointInfo.lastZY.hi = py;
return;
}
zx = px;
zy = py;
// Initial maximum period to detect.
int check = 3;
// Maximum period doubles every iterations:
int whenupdate = 10;
// Period history registers.
double hx = 0;
double hy = 0;
// long int because maxiter goes above 2**31 bits
for (long i = 1; i <= 50000; i++) {
// Precalculate squares.
xx = zx * zx;
yy = zy * zy;
// Check bailout.
if (xx + yy > bailout) {
pointInfo.inside = false;
pointInfo.lastIter = i;
pointInfo.lastZX.hi = zx;
pointInfo.lastZY.hi = zy;
return;
}
// Iterate
zy = 2 * zx * zy + py;
zx = xx - yy + px;
// Periodicity check.
double d = zx - hx;
if (d > 0.0 ? d < Mandel.PRIODICITY_EPS : d > -Mandel.PRIODICITY_EPS) {
d = zy - hy;
if (d > 0.0 ? d < Mandel.PRIODICITY_EPS : d > -Mandel.PRIODICITY_EPS) {
// Period found.
pointInfo.inside = true;
pointInfo.lastIter = i; // & check
pointInfo.lastZX.hi = zx;
pointInfo.lastZY.hi = zy;
return;
}
}
if ((i & check) == 0) {
if (--whenupdate == 0) {
whenupdate = 10;
check <<= 1;
check++;
}
// period = 0;
hx = zx;
hy = zy;
}
}
// Maxiter reached.
pointInfo.inside = true;
pointInfo.lastIter = maxiter;
pointInfo.lastZX.hi = zx;
pointInfo.lastZY.hi = zy;
return;
}
}