/*
* Copyright 2013 Uwe Krueger.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.mandelsoft.mand.meth;
import com.mandelsoft.mand.MandIter;
import com.mandelsoft.mand.MandelSpec;
import com.mandelsoft.mand.PixelIterator;
import com.mandelsoft.mand.PixelIteratorFactory;
import com.mandelsoft.mand.tools.Mand;
import java.math.BigDecimal;
import com.mandelsoft.mand.util.MandArith;
/**
*
* @author Uwe Krueger
*/
public class MandelbrotPixelIteratorFactory extends MandArith
implements PixelIteratorFactory {
static private BigDecimal br=new BigDecimal(5.e-16);
public PixelIterator createPixelIterator(MandelSpec mi)
{
BigDecimal x0=mi.getXMin();
BigDecimal y0=mi.getYMax();
BigDecimal dx=mi.getDX();
BigDecimal dy=mi.getDY();
int rx=mi.getRX();
int ry=mi.getRY();
return createPixelIterator(x0,y0,dx,dy,rx,ry,
mi.getLimitIt());
}
static public PixelIterator createPixelIterator(BigDecimal x0,
BigDecimal y0,
BigDecimal dx,
BigDecimal dy,
int rx,
int ry,
int limit)
{
if (div(dx,rx).compareTo(br)>0 && div(dy,ry).compareTo(br)>0) {
System.out.println("double iteration mode");
return new DoubleMandIterator(x0,y0,dx,dy,rx,ry,limit);
}
if (MandIter.useDLL) {
System.out.println("long double iteration mode");
return new LongDoubleMandIterator(x0,y0,dx,dy,rx,ry,limit);
}
System.out.println("big decimal iteration mode");
return new BigDecimalMandIterator(x0,y0,dx,dy,rx,ry,limit);
}
/////////////////////////////////////////////////////////////////////////
// double iterator
/////////////////////////////////////////////////////////////////////////
private static class DoubleMandIterator extends AbstractDoublePixelIterator {
public DoubleMandIterator(BigDecimal x0,
BigDecimal y0,
BigDecimal dx,
BigDecimal dy,
int rx,
int ry,
int limit)
{
super(x0,y0,dx,dy,rx,ry,limit);
}
public int iter()
{
return iter(0.0, 0.0, cx, cy, bound, limit);
}
private static int iter(double x, double y, double px, double py,
double bound, int limit)
{
double x2=x*x;
double y2=y*y;
int it=0;
while (x2+y2<bound&&++it<=limit) {
double xn=x2-y2+px;
double yn=2*x*y+py;
x=xn;
x2=x*x;
y=yn;
y2=y*y;
}
return it;
}
}
/////////////////////////////////////////////////////////////////////////
// long double iterator
/////////////////////////////////////////////////////////////////////////
private static class LongDoubleMandIterator extends AbstractBigDecimalPixelIterator {
protected String bound;
protected String scx;
protected String scy;
public LongDoubleMandIterator(BigDecimal x0,
BigDecimal y0,
BigDecimal dx,
BigDecimal dy,
int rx,
int ry,
int limit)
{
super(x0,y0,dx,dy,rx,ry,limit);
bound=new BigDecimal(Mand.BOUND).toString();
System.out.println("prec: "+precision);
}
@Override
public void setX(int x)
{
super.setX(x);
scx=cx.toString();
}
@Override
public void setY(int y)
{
super.setY(y);
scy=cy.toString();
}
public int iter()
{
return MandIter.iterP("0.0", "0.0", scx, scy, bound, limit, precision);
}
}
/////////////////////////////////////////////////////////////////////////
// big decimal iterator
/////////////////////////////////////////////////////////////////////////
private static class BigDecimalMandIterator extends AbstractBigDecimalPixelIterator {
private int cnt;
private BigDecimal bound;
public BigDecimalMandIterator(BigDecimal x0,
BigDecimal y0,
BigDecimal dx,
BigDecimal dy,
int rx,
int ry,
int limit)
{
super(x0,y0,dx,dy,rx,ry,limit);
bound=new BigDecimal(Mand.BOUND);
}
public int iter()
{
cnt++;
if (cnt%100==0) {
System.out.print(".");
System.out.flush();
}
return iter(BigDecimal.ZERO, BigDecimal.ZERO, cx, cy,
bound, limit);
}
static public int iter(BigDecimal sx, BigDecimal sy,
BigDecimal cx, BigDecimal cy,
BigDecimal bound, int limit)
{
BigDecimal x=sx;
BigDecimal y=sy;
BigDecimal x2=mul(x, x);
BigDecimal y2=mul(y, y);
int it=0;
while (add(x2, y2).compareTo(bound)<0&&++it<=limit) {
BigDecimal xn=add(sub(x2, y2), cx);
BigDecimal yn=add(mul(mul(b2, x), y), cy);
x=xn;
x2=mul(x, x);
y=yn;
y2=mul(y, y);
}
return it;
}
}
}