1 /**
2  * Mandelbulber v2, a 3D fractal generator  _%}}i*<.         ______
3  * Copyright (C) 2020 Mandelbulber Team   _>]|=||i=i<,      / ____/ __    __
4  *                                        \><||i|=>>%)     / /   __/ /___/ /_
5  * This file is part of Mandelbulber.     )<=i=]=|=i<>    / /__ /_  __/_  __/
6  * The project is licensed under GPLv3,   -<>>=|><|||`    \____/ /_/   /_/
7  * see also COPYING file in this folder.    ~+{i%+++
8  *
9  * Based on Amazing Surf Mod 1 from Mandelbulber3D, a formula proposed by Kali,
10  * with features added by DarkBeam
11  * @reference
12  * http://www.fractalforums.com/mandelbulb-3d/custom-formulas-and-transforms-release-t17106/
13  * This formula contains aux.color and aux.actualScale
14  */
15 
16 #include "all_fractal_definitions.h"
17 
cFractalAmazingSurfMod1()18 cFractalAmazingSurfMod1::cFractalAmazingSurfMod1() : cAbstractFractal()
19 {
20 	nameInComboBox = "Amazing Surf - Mod 1";
21 	internalName = "amazing_surf_mod1";
22 	internalID = fractal::amazingSurfMod1;
23 	DEType = analyticDEType;
24 	DEFunctionType = linearDEFunction;
25 	cpixelAddition = cpixelEnabledByDefault;
26 	defaultBailout = 100.0;
27 	DEAnalyticFunction = analyticFunctionLinear;
28 	coloringFunction = coloringFunctionABox;
29 }
30 
FormulaCode(CVector4 & z,const sFractal * fractal,sExtendedAux & aux)31 void cFractalAmazingSurfMod1::FormulaCode(CVector4 &z, const sFractal *fractal, sExtendedAux &aux)
32 {
33 	double colorAdd = 0.0;
34 	aux.actualScale =
35 		fractal->mandelbox.scale + fractal->mandelboxVary4D.scaleVary * (fabs(aux.actualScale) - 1.0);
36 	CVector4 oldZ = z;
37 	if (fractal->transformCommon.functionEnabledAx)
38 	{
39 		z.x = fabs(z.x + fractal->transformCommon.additionConstant111.x)
40 					- fabs(z.x - fractal->transformCommon.additionConstant111.x) - z.x;
41 		z.y = fabs(z.y + fractal->transformCommon.additionConstant111.y)
42 					- fabs(z.y - fractal->transformCommon.additionConstant111.y) - z.y;
43 		if (z.x != oldZ.x) colorAdd += fractal->mandelbox.color.factor.x;
44 		if (z.y != oldZ.y) colorAdd += fractal->mandelbox.color.factor.y;
45 	}
46 
47 	// z = fold - fabs( fabs(z) - fold)
48 	if (fractal->transformCommon.functionEnabledAyFalse)
49 	{
50 		z.x = fractal->transformCommon.additionConstant111.x
51 					- fabs(fabs(z.x) - fractal->transformCommon.additionConstant111.x);
52 		z.y = fractal->transformCommon.additionConstant111.y
53 					- fabs(fabs(z.y) - fractal->transformCommon.additionConstant111.y);
54 		if (z.x != oldZ.x) colorAdd += fractal->mandelbox.color.factor.x;
55 		if (z.y != oldZ.y) colorAdd += fractal->mandelbox.color.factor.y;
56 	}
57 
58 	if (fractal->transformCommon.functionEnabledAzFalse)
59 	{
60 		z.x = fabs(z.x + fractal->transformCommon.additionConstant111.x);
61 		z.y = fabs(z.y + fractal->transformCommon.additionConstant111.y);
62 		if (z.x != oldZ.x) colorAdd += fractal->mandelbox.color.factor.x;
63 		if (z.y != oldZ.y) colorAdd += fractal->mandelbox.color.factor.y;
64 	}
65 
66 	// if z > limit) z =  Value -z,   else if z < limit) z = - Value - z,
67 	if (fractal->transformCommon.functionEnabledxFalse)
68 	{
69 		if (fabs(z.x) > fractal->transformCommon.additionConstant111.x)
70 		{
71 			z.x = sign(z.x) * fractal->mandelbox.foldingValue - z.x;
72 		}
73 		if (fabs(z.y) > fractal->transformCommon.additionConstant111.y)
74 		{
75 			z.y = sign(z.y) * fractal->mandelbox.foldingValue - z.y;
76 		}
77 		if (z.x != oldZ.x) colorAdd += fractal->mandelbox.color.factor.x;
78 		if (z.y != oldZ.y) colorAdd += fractal->mandelbox.color.factor.y;
79 	}
80 
81 	// z = fold2 - fabs( fabs(z + fold) - fold2) - fabs(fold)
82 	if (fractal->transformCommon.functionEnabledyFalse)
83 	{
84 		z.x = fractal->transformCommon.offset2
85 					- fabs(fabs(z.x + fractal->transformCommon.additionConstant111.x)
86 								 - fractal->transformCommon.offset2)
87 					- fractal->transformCommon.additionConstant111.x;
88 		z.y = fractal->transformCommon.offset2
89 					- fabs(fabs(z.y + fractal->transformCommon.additionConstant111.y)
90 								 - fractal->transformCommon.offset2)
91 					- fractal->transformCommon.additionConstant111.y;
92 		if (z.x != oldZ.x) colorAdd += fractal->mandelbox.color.factor.x;
93 		if (z.y != oldZ.y) colorAdd += fractal->mandelbox.color.factor.y;
94 	}
95 
96 	z += fractal->transformCommon.additionConstant000;
97 
98 	double r2;
99 	r2 = z.Dot(z);
100 	if (fractal->transformCommon.functionEnabledFalse) // force cylinder fold
101 		r2 -= z.z * z.z;
102 
103 	// if (r2 < 1e-21)
104 	//	r2 = 1e-21;
105 
106 	double sqrtMinR = fractal->transformCommon.sqtR;
107 	if (r2 < sqrtMinR)
108 	{
109 		z *= fractal->transformCommon.mboxFactor1;
110 		aux.DE *= fractal->transformCommon.mboxFactor1;
111 		colorAdd += fractal->mandelbox.color.factorSp1;
112 	}
113 	else if (r2 < 1.0)
114 	{
115 		z *= 1.0 / r2;
116 		aux.DE *= 1.0 / r2;
117 		colorAdd += fractal->mandelbox.color.factorSp2;
118 	}
119 
120 	z *= aux.actualScale * fractal->transformCommon.scale1
121 			 + 1.0 * (1.0 - fractal->transformCommon.scale1);
122 	aux.DE = aux.DE * fabs(aux.actualScale) + 1.0;
123 
124 	z = fractal->transformCommon.rotationMatrix.RotateVector(z);
125 
126 	aux.color += colorAdd;
127 }
128