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.
151 lines
4.2 KiB
Java
151 lines
4.2 KiB
Java
package deepZoom.fractals;
|
|
|
|
import deepZoom.renderer.PointInfo;
|
|
|
|
import digisoft.custom.util.geom.DoubleDouble;
|
|
|
|
/**
|
|
* @author Zom-B
|
|
* @since 1.0
|
|
* @date 2009/07/09
|
|
*/
|
|
public class MandelPrecision extends Fractal {
|
|
|
|
private static final double PRIODICITY_EPS = 1e-17;
|
|
|
|
@Override
|
|
public void initFrame() {
|
|
}
|
|
|
|
@Override
|
|
public void calcPoint(PointInfo pointInfo) {
|
|
DoubleDouble zx = new DoubleDouble();
|
|
DoubleDouble zy = new DoubleDouble();
|
|
DoubleDouble xx = new DoubleDouble();
|
|
DoubleDouble yy = new DoubleDouble();
|
|
DoubleDouble temp = new DoubleDouble();
|
|
|
|
double bailout = parameters.getBailout();
|
|
long maxiter = parameters.getMaxiter();
|
|
|
|
// Calculate viewport.
|
|
// DoubleDouble px = this.viewport.getPX(x, y);
|
|
// DoubleDouble py = this.viewport.getPY(x, y);
|
|
DoubleDouble px = pointInfo.px;
|
|
DoubleDouble py = pointInfo.py;
|
|
|
|
// Main bulb check.
|
|
// zx = 4 * (px * px + py * py);
|
|
zy.set(py);
|
|
zy.sqrSelf();
|
|
zx.set(px);
|
|
zx.sqrSelf();
|
|
zx.addSelf(zy);
|
|
zx.mulSelf(4);
|
|
// temp = 2 * px
|
|
xx.set(px);
|
|
xx.mulSelf(2);
|
|
// zy = zx + 4 * temp
|
|
zy.set(xx);
|
|
zy.mulSelf(4);
|
|
zy.addSelf(zx);
|
|
if (zy.hi < -3.75) {
|
|
pointInfo.inside = true;
|
|
pointInfo.lastIter = maxiter;
|
|
pointInfo.lastZX = px;
|
|
pointInfo.lastZY = py;
|
|
return;
|
|
}
|
|
|
|
// Cardoid check.
|
|
// zy = zx - temp + 0.25;
|
|
zy.set(zx);
|
|
zy.subSelf(xx);
|
|
zy.addSelf(0.25);
|
|
// temp = (temp + zy - 0.5)**2;
|
|
xx.addSelf(zy);
|
|
xx.addSelf(-0.5);
|
|
xx.sqrSelf();
|
|
// if (zy > temp)
|
|
if (zy.hi > xx.hi) {
|
|
pointInfo.inside = true;
|
|
pointInfo.lastIter = maxiter;
|
|
pointInfo.lastZX = px;
|
|
pointInfo.lastZY = py;
|
|
return;
|
|
}
|
|
|
|
zx.set(px);
|
|
zy.set(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.set(zx);
|
|
xx.sqrSelf();
|
|
yy.set(zy);
|
|
yy.sqrSelf();
|
|
|
|
// Check bailout.
|
|
temp.set(xx);
|
|
temp.addSelf(yy);
|
|
if (temp.hi > bailout) {
|
|
pointInfo.inside = false;
|
|
pointInfo.lastIter = i;
|
|
pointInfo.lastZX = zx;
|
|
pointInfo.lastZY = zy;
|
|
return;
|
|
}
|
|
|
|
// Iterate
|
|
// y' = y * x * 2 + cy
|
|
zy.mulSelf(zx);
|
|
zy.addSelf(zy);
|
|
zy.addSelf(py);
|
|
// x' = xx - yy + px
|
|
xx.subSelf(yy);
|
|
zx.set(xx);
|
|
zx.addSelf(px);
|
|
|
|
// Periodicity check.
|
|
double d = zx.hi - hx;
|
|
if (d > 0.0 ? d < MandelPrecision.PRIODICITY_EPS : d > -MandelPrecision.PRIODICITY_EPS) {
|
|
d = zy.hi - hy;
|
|
if (d > 0.0 ? d < MandelPrecision.PRIODICITY_EPS : d > -MandelPrecision.PRIODICITY_EPS) {
|
|
// Period found.
|
|
|
|
pointInfo.inside = true;
|
|
pointInfo.lastIter = i; // & check
|
|
pointInfo.lastZX = zx;
|
|
pointInfo.lastZY = zy;
|
|
return;
|
|
}
|
|
}
|
|
if ((i & check) == 0) {
|
|
if (--whenupdate == 0) {
|
|
whenupdate = 10;
|
|
check <<= 1;
|
|
check++;
|
|
}
|
|
// period = 0;
|
|
hx = zx.hi;
|
|
hy = zy.hi;
|
|
}
|
|
}
|
|
|
|
// Maxiter reached.
|
|
pointInfo.inside = true;
|
|
pointInfo.lastIter = maxiter;
|
|
pointInfo.lastZX = zx;
|
|
pointInfo.lastZY = zy;
|
|
return;
|
|
}
|
|
} |