| | |
 |
| Release 4.0 |
|
|
ChaosPro Formula Database |
| | | | Name | FractInt.ccl | | Path | /Compiler/Compatibility/ | | Type | Coloring | | Size | 17 KB | | Owner | Martin Pfingstl | | Last Modified: | 10 Feb 2011 | | | |
|
comment {
These formulas should imitate FractInt's coloring
options for the different fractal types.
If you encounter problems, please let me know.
Not all FractInt options work.
Enjoy,
Martin Pfingstl
}
FractInt_Inside {
real z_min,zmodulo;
shared int iEpsilonCross;
int min_iter,current_iter;
parameter int iInside;
parameter int iColorIndex;
// bTruncate must be true in order to mimic FractInt 256-color behaviour
parameter bool bTruncate;
parameter real iEpsCrossDistance;
bool bSearchPeriodicity;
int startSearch,perLength;
int periodicityColor;
complex periodicityZ;
real eps;
parameter real perValue;
real delxx,delxx2,delyy,delyy2,ddelmin;
shared int iPotential;
shared real potMaxCol;
shared int iLogmap;
shared real coloriter;
double calclog(double idx)
{
real lf,range;
int iMaxiter;
iMaxiter=maxiter+1;
if (iLogmap>0)
{
if (idx>iMaxiter) {
idx=iMaxiter;
}
// FractInt "new style" logarithmic scaling...
// iLogmapSetting=1 ==> Standard logmap, >1 ==> Standard logmap, but starting at iteration count "iLogmapSetting"
if (iLogmap>1)
{
lf = iLogmap;
}
else
{
lf = 0;
}
if (lf>=iMaxiter)
{
lf = iMaxiter-1;
}
if (lf>0)
{
range = 254 / log(iMaxiter- lf);
}
else
{
range = 255 / log(iMaxiter);
}
if (idx<=lf)
{
idx = 1;
}
else if ( (idx - lf) / log(idx - lf) <= range)
{
if (lf>0)
{
idx = idx - lf + 1;
}
else
{
idx = idx - lf;
}
}
else
{
idx = range * log(idx - lf)+1;
}
}
else if (iLogmap == -1)
{
if (idx>iMaxiter) {
idx=iMaxiter;
}
if (idx==0)
{
idx = 1;
}
else
{
idx = (255 / log(iMaxiter)) * log(idx)+1;
}
}
else if (iLogmap<=-2)
{
if (idx>iMaxiter) {
idx=iMaxiter;
}
lf = -iLogmap;
if (lf >= iMaxiter)
{
lf = iMaxiter- 1;
}
range = 254 / sqrt(iMaxiter- lf);
if (idx <= lf)
{
idx = 1;
}
else if ((idx - lf) <= sqr(range))
{
idx = idx - lf + 0;
}
else
{
idx = 1 + range * sqrt(idx - lf);
}
}
return(idx);
}
void init(void)
{
iEpsilonCross=0;
if (iInside=="bof61")
{
min_iter=0;
}
else if (iInside=="epsiloncross")
{
iEpsilonCross=0; // 0 means, nothing has been done...
}
else if (iInside=="periodicity")
{
bSearchPeriodicity=true;
current_iter=1;
// Calcfrac.c, l 1526
startSearch=maxiter*4/5;
// calcfrac.c, l 1596
perLength=16;
periodicityColor=maxiter;
periodicityZ=(0,0);
delxx = (real(corner_rightbottom) - real(corner_lefttop)) / (width-1);
delyy = (imag(corner_lefttop) - imag(corner_rightbottom)) / (height-1);
delxx2 = (real(corner_lefttop) - real(corner_lefttop)) / (height-1);
delyy2 = (imag(corner_rightbottom) - imag(corner_rightbottom)) / (width-1);
ddelmin = abs(delxx);
if (abs(delxx2) > ddelmin)
{
ddelmin = abs(delxx2);
}
if (abs(delyy) > abs(delyy2))
{
if (abs(delyy) < ddelmin)
{
ddelmin = abs(delyy);
}
}
else if (abs(delyy2) < ddelmin)
{
ddelmin = abs(delyy2);
}
// calcfrac.c, l 616 0.0005
eps=ddelmin * exp(-log(2) * abs(perValue));
}
z_min=100000;
}
void loop(void)
{
if (iInside=="bof60") // bof60
{
zmodulo=|z|;
if (zmodulo<z_min)
{
z_min=zmodulo;
}
}
else if (iInside=="bof61") // bof61
{
zmodulo=|z|;
if (zmodulo<z_min)
{
z_min=zmodulo;
min_iter=numiter+2;
}
}
else if (iInside=="epsiloncross") // epsilon cross
{
if (iEpsilonCross==0)
{
if (abs(real(z))<iEpsCrossDistance)
{
iEpsilonCross=2;
}
if (abs(imag(z))<iEpsCrossDistance)
{
iEpsilonCross=6;
}
}
}
else if (iInside=="periodicity") // epsilon cross
{
// no periodicity found, but iteration reached?
if (bSearchPeriodicity && current_iter>=startSearch)
{
// ok, now lets search for periodicity
if (current_iter>startSearch && current_iter<startSearch+perLength)
{
// now did we find a cycle?
if (abs(real(periodicityZ-z))<eps && abs(imag(periodicityZ-z))<eps)
{
bSearchPeriodicity=false;
periodicityColor=current_iter-startSearch;
}
}
else
{
periodicityZ=z;
perLength=perLength+perLength+1;
startSearch=current_iter;
}
}
current_iter=current_iter+1;
}
}
void final(void)
{
alpha=0;
if (iInside=="<nnn>")
{
if (iColorIndex==-1)
{
index=maxiter;
}
else
{
index=iColorIndex;
}
}
else if (iInside=="maxiter")
{
index=maxiter+1;
}
else if (iInside=="zmag")
{
index = |z|*floor((maxiter+1) / 2)+1;
}
else if (iInside=="bof60")
{
index = sqrt(z_min) * 75;
}
else if (iInside=="bof61")
{
index=min_iter;
}
else if (iInside=="epsiloncross")
{
index = iEpsilonCross;
if (index==0)
{
index=maxiter;
}
}
else if (iInside=="periodicity")
{
if (periodicityColor>255) {
index = 255;
}
else {
index = periodicityColor;
}
}
if (iPotential==1)
{
if (iInside!="<nnn>")
{
index=potMaxCol;
}
if (bTruncate)
{
index=trunc(index);
}
}
if (iInside!="<nnn>")
{
index=calclog(index);
}
if (coloriter!=0)
{
index=coloriter;
}
if (bTruncate)
{
index=trunc(index);
}
alpha=0;
index=((index)%252)/252;
}
void description(void)
{
this.title="Inside";
this.helpfile="http://www.chaospro.de/";
bTruncate.caption="Truncate";
bTruncate.hint="If set, the resulting color index gets truncated to the nearest color index. Otherwise (i.e. normal behaviour of ChaosPro) the two neighboured colors would be interpolated.";
bTruncate.default=true;
iInside.caption="Inside Coloring";
iInside.hint="This option specifies the algorithm to use for inside coloring";
iInside.enum="<nnn>\nmaxiter\nzmag\nbof60\nbof61\nepsiloncross\nperiodicity";
iInside.default=0;
iColorIndex.caption="Color Index";
iColorIndex.hint="Specifies the color to use. -1 means 'maxiter'. Parameter is used only if Inside-Coloring is set to <nnn>";
iColorIndex.default=1.0;
iColorIndex.min=-1.0;
iColorIndex.max=255.0;
iColorIndex.visible=iInside=="<nnn>";
iEpsCrossDistance.caption="Distance";
iEpsCrossDistance.hint="Valid only for epsilon cross coloring: Specifies the distance from the axis";
iEpsCrossDistance.default=0.01;
iEpsCrossDistance.min=0.0000000000000000001;
iEpsCrossDistance.max=100000;
iEpsCrossDistance.visible=iInside=="epsiloncross";
perValue.caption="Periodicity Bailin";
perValue.default=1.0;
perValue.min=1.0;
perValue.hint="Defines the bailin value for periodicity";
perValue.visible=iInside=="periodicity";
}
}
FractInt_Decomp(OUTSIDE) {
real lowestIter,range;
real z_angle;
parameter int iDecomp;
parameter int iLogmapSetting;
parameter bool bTruncate;
void final(void)
{
z_angle = atan2(z);
if (z_angle<0)
{
z_angle = z_angle + 2*pi;
}
if (iDecomp<256)
{
index = 1;
}
else
{
index = 0;
}
if (bTruncate)
{
index = index + (z_angle * (iDecomp - index)) / (2 * pi);
}
else
{
index = index + trunc((z_angle * iDecomp) / (2 * pi));
}
if (iLogmapSetting != 0 && index > maxiter)
{
index = maxiter;
}
if (iLogmapSetting>0)
{
// iLogmapSetting=1 ==> Standard logmap, >1 ==> Standard logmap, but starting at iteration count <iLogmapSetting>
if (iLogmapSetting>1)
{
lowestIter = iLogmapSetting;
}
else
{
lowestIter = 0;
}
// Lets initialize a helper variable for the available range (from lowestIter upto maxiter)
// In order to avoid math errors, let us restrict lowestIter to a value smaller than maxiter...
if (lowestIter>=maxiter)
{
lowestIter = maxiter-1;
}
if (lowestIter>0)
{
range = 255 / log(maxiter - lowestIter);
}
else
{
range = 256 / log(maxiter);
}
if (index<=lowestIter)
{
index = 1;
}
else if ( (index - lowestIter) / log(index - lowestIter) <= range)
{
if (lowestIter>0)
{
index = index - lowestIter + 1;
}
else
{
index = index - lowestIter;
}
}
else
{
index = 1 + range * log(index - lowestIter);
}
}
else if (iLogmapSetting == -1)
{
if (index==0)
{
index = 1;
}
else
{
index = 1 + (256 / log(150)) * log(index);
}
}
else if (iLogmapSetting < -1)
{
lowestIter = -iLogmapSetting;
if (lowestIter >= maxiter)
{
lowestIter = maxiter - 1;
}
range = 256 / sqrt(maxiter - lowestIter);
if (index <= lowestIter)
{
index = 1;
}
else if ((index - lowestIter) <= sqr(range))
{
index = index - lowestIter + 1;
}
else
{
index = 1 + range * sqrt(index - lowestIter);
}
}
index = (index % 252) / 252;
}
void description(void)
{
this.title = "Decomposition";
this.helpfile="http://www.chaospro.de/";
iDecomp.caption = "Decomposition";
iDecomp.hint = "This is the Decomp Option parameter in Fractint.";
iDecomp.default = 256;
iDecomp.min = 0;
iDecomp.max = 256;
iLogmapSetting.caption = "Log Palette";
iLogmapSetting.hint = "Imitates the Log Palette value in Fractint. 0=no, 1=yes, -1=old, +n=cmprsd, -n=sqrt.";
iLogmapSetting.default = 0;
bTruncate.caption="Truncate";
bTruncate.hint="If set, the resulting color index gets truncated to the nearest color index. Otherwise (i.e. normal behaviour of ChaosPro) the two neighboured colors would be interpolated.";
bTruncate.default=true;
}
}
FractInt_Outside(OUTSIDE) {
bool bSkip;
parameter int iOutside;
parameter real iColorIndex;
parameter bool bTruncate;
parameter bool bRestrict;
parameter int iLogmapSetting;
parameter real rBiomorphSetting;
int iterations;
parameter real outsideMult;
parameter real slope;
parameter int iDecomp;
parameter bool bDecomp;
shared int iEpsilonCross;
real z_angle;
parameter int version;
shared int iPotential;
shared real potMaxCol;
shared int iLogmap;
shared real formulaBailout;
shared real rBiomorph;
shared real coloriter;
real distance;
complex prevZ;
double calclog(double idx)
{
real lf,range;
int iMaxiter;
/*if (!idx)
{
return(0);
}*/
iMaxiter=maxiter+1;
if (iLogmap>0)
{
if (idx>iMaxiter) {
idx=iMaxiter;
}
// FractInt "new style" logarithmic scaling...
// iLogmapSetting=1 ==> Standard logmap, >1 ==> Standard logmap, but starting at iteration count "iLogmapSetting"
if (iLogmap>1)
{
lf = iLogmap;
}
else
{
lf = 0;
}
if (lf>=iMaxiter)
{
lf = iMaxiter-1;
}
if (lf>0)
{
range = 254 / log(iMaxiter- lf);
}
else
{
range = 255 / log(iMaxiter);
}
if (idx<=lf)
{
// Egg should use 0...but why?
idx = 1;
}
else if ( (idx - lf) / log(idx - lf) <= range)
{
if (lf>0)
{
idx = idx - lf + 1;
}
else
{
idx = idx - lf;
}
}
else
{
idx = range * log(idx - lf)+1;
}
}
else if (iLogmap == -1)
{
if (idx>iMaxiter) {
idx=iMaxiter;
}
if (idx==0)
{
idx = 1;
}
else
{
idx = (255 / log(iMaxiter)) * log(idx)+1;
}
}
else if (iLogmap<=-2)
{
if (idx>iMaxiter) {
idx=iMaxiter;
}
lf = -iLogmap;
if (lf >= iMaxiter)
{
lf = iMaxiter- 1;
}
range = 254 / sqrt(iMaxiter- lf);
if (idx <= lf)
{
idx = 1;
}
else if ((idx - lf) <= sqr(range))
{
idx = idx - lf + 0;
}
else
{
idx = 1 + range * sqrt(idx - lf);
}
}
return(idx);
}
double potential(double mag,double PotMaxCol,double PotSlope)
{
double pot;
int l_pot;
// NYUF009 will iterations+3
// NYUF008 will iterations+3
// AtomicGlow will iterations+3
pot = iterations+3;
if (pot <= 0 || mag <= 1.0) {
pot = 0.0;
}
else {
pot = log(mag)/(2^pot);
}
if (pot > 0.0) {
pot = sqrt(pot);
pot = PotMaxCol - pot*PotSlope - 1.0;
}
else {
pot = PotMaxCol - 1.0;
}
if (pot < 1.0) {
pot = 1.0;
}
return(pot);
}
void init_once(void)
{
iPotential=0;
iLogmap=iLogmapSetting;
rBiomorph=rBiomorphSetting;
if (iOutside=="potential")
{
iPotential=1;
potMaxCol=outsideMult;
}
formulaBailout=-1;
}
void init(void)
{
distance=0;
prevZ=z;
if (formulaBailout<0) {
formulaBailout=100;
}
}
void loop(void)
{
if (iOutside=="tdis")
{
distance=distance+cabs(z-prevZ);
prevZ=z;
}
}
void final(void)
{
if (bDecomp && iOutside!="potential")
{
z_angle = atan2(z);
if (z_angle<0) {
z_angle = z_angle + 2*pi;
}
if (iDecomp<256) {
index = 1;
}
else {
index = 0;
}
if (bTruncate) {
index = index + trunc((z_angle * iDecomp) / (2 * pi));
}
else {
index = index + (z_angle * (iDecomp - index)) / (2 * pi);
}
if (iLogmapSetting != 0 && index > maxiter)
{
index = maxiter;
}
}
else
{
bSkip= (iOutside==1);
alpha=numiter%2;
index=1+numiter;
// iOutside: 0 ==> <nnn>
// 1 ==> iter^
// 2 ==> real
// 3 ==> imag
// 4 ==> mult
// 5 ==> mult
// 6 ==> summ
// 7 ==> atan
if (iOutside=="real")
{
if (bTruncate)
{
index=index+7+trunc(real(z));
}
else
{
index=index+7+real(z);
}
}
else if (iOutside=="imag")
{
if (bTruncate)
{
index=index+7+trunc(imag(z));
}
else
{
index=index+7+imag(z);
}
}
else if (iOutside=="mult")
{
if (bTruncate)
{
index=trunc(index*real(z)/imag(z));
}
else
{
index=index*real(z)/imag(z);
}
}
else if (iOutside=="summ")
{
if (bTruncate)
{
index=index+trunc(real(z)+imag(z));
}
else
{
index=index+real(z)+imag(z);
}
}
else if (iOutside=="atan")
{
if (bTruncate)
{
index=trunc(abs(atan2(z)*180/pi));
}
else
{
index=abs(atan2(z)*180/pi);
}
}
else if (iOutside=="potential")
{
iterations=numiter;
index=abs(potential(|z|,outsideMult,slope));
if (bTruncate)
{
index=trunc(index);
}
}
else if (iOutside=="tdis")
{
index=distance;
if (bTruncate)
{
index=trunc(index);
}
}
if (rBiomorphSetting>=0 && ( abs(real(z))<=sqrt(formulaBailout) || abs(imag(z))<=sqrt(formulaBailout) ) )
{
index = rBiomorphSetting;
bSkip = false;
}
if (iOutside!="potential")
{
if (index<=0 || index>maxiter)
{
if (version<1961)
{
index = 0;
}
else
{
index = 1;
}
}
}
}
if (iOutside==0 && !bDecomp)
{
index=iColorIndex;
}
else
{
index=calclog(index);
}
if (coloriter!=0)
{
index=coloriter;
}
// epscross also affects outside colorings!
if (iEpsilonCross>0) {
index=iEpsilonCross;
bSkip=false;
}
if (bSkip)
{
index = (1 + (index - 1)%252) / 252;
}
else
{
index = (index % 252) / 252;
}
}
void description(void)
{
this.title="Outside";
this.helpfile="http://www.chaospro.de/";
iOutside.caption="Outside Coloring";
iOutside.hint="This option specifies the algorithm to use for outside coloring";
iOutside.enum="<nnn>\niter\nreal\nimag\nmult\nsumm\natan\npotential\ntdis";
iOutside.default=1;
outsideMult.caption="Max Color";
outsideMult.default=1.0;
outsideMult.visible=(iOutside==7);
slope.caption="Slope";
slope.default=1.0;
slope.visible=(iOutside==7);
iColorIndex.caption="Color Index";
iColorIndex.hint="Specifies the color to use. Parameter is used only if Outside-Coloring is set to <nnn>";
iColorIndex.default=1;
iColorIndex.min=0;
iColorIndex.max=255;
iColorIndex.visible=(iOutside==0);
bTruncate.caption="Truncate";
bTruncate.hint="If set, the resulting color index gets truncated to the nearest color index. Otherwise (i.e. normal behaviour of ChaosPro) the two neighboured colors would be interpolated.";
bTruncate.default=true;
bRestrict.caption="Cut Colors";
bRestrict.hint="If set, the resulting index value is restricted to 0..maxiter: If it falls outside, it is set to 0 or maxiter.";
bRestrict.default=false;
iLogmapSetting.caption = "Log Palette";
iLogmapSetting.hint = "Imitates the Log Palette value in Fractint. 0=no, 1=yes, -1=old, +n=cmprsd, -n=sqrt.";
iLogmapSetting.default = 0;
rBiomorphSetting.caption = "Biomorph Color";
rBiomorphSetting.hint = "Reconstructs the biomorph option from FractInt. -1 turns biomorph coloring off (default). A color value (0..255) turns it on using the specified color.";
rBiomorphSetting.default = -1;
rBiomorphSetting.min = -1;
rBiomorphSetting.max = 255;
version.caption="FractInt Version";
version.default=1960;
version.hint="Specifies the FractInt version.";
}
}