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 * BoxBulb power 2 V3 with scaling of z axis
10 * This formula contains aux.color and aux.actualScaleA
11 */
12
13 #include "all_fractal_definitions.h"
14
cFractalBoxFoldBulbPow2V3()15 cFractalBoxFoldBulbPow2V3::cFractalBoxFoldBulbPow2V3() : cAbstractFractal()
16 {
17 nameInComboBox = "Box Fold Bulb Pow 2 V3";
18 internalName = "box_fold_bulb_pow2_v3";
19 internalID = fractal::boxFoldBulbPow2V3;
20 DEType = analyticDEType;
21 DEFunctionType = logarithmicDEFunction;
22 cpixelAddition = cpixelEnabledByDefault;
23 defaultBailout = 100.0;
24 DEAnalyticFunction = analyticFunctionLogarithmic;
25 coloringFunction = coloringFunctionDefault;
26 }
27
FormulaCode(CVector4 & z,const sFractal * fractal,sExtendedAux & aux)28 void cFractalBoxFoldBulbPow2V3::FormulaCode(CVector4 &z, const sFractal *fractal, sExtendedAux &aux)
29 {
30 // sphere inversion
31 if (fractal->transformCommon.sphereInversionEnabledFalse
32 && aux.i >= fractal->transformCommon.startIterations
33 && aux.i < fractal->transformCommon.stopIterations1)
34 {
35 double rr = 1.0;
36 z += fractal->transformCommon.offset000;
37 rr = z.Dot(z);
38 z *= fractal->transformCommon.scaleG1 / rr;
39 aux.DE *= (fractal->transformCommon.scaleG1 / rr);
40 z += fractal->transformCommon.additionConstant000 - fractal->transformCommon.offset000;
41 z *= fractal->transformCommon.scaleA1;
42 aux.DE *= fractal->transformCommon.scaleA1;
43 }
44
45 // CVector4 c = aux.const_c;
46 double colorAdd = 0.0;
47 double rrCol = 0.0;
48 CVector4 zCol = z;
49 CVector4 oldZ = z;
50
51 // tglad fold
52 if (aux.i >= fractal->transformCommon.startIterationsB
53 && aux.i < fractal->transformCommon.stopIterationsB)
54 {
55 z.x = fabs(z.x + fractal->transformCommon.additionConstant111.x)
56 - fabs(z.x - fractal->transformCommon.additionConstant111.x) - z.x;
57 z.y = fabs(z.y + fractal->transformCommon.additionConstant111.y)
58 - fabs(z.y - fractal->transformCommon.additionConstant111.y) - z.y;
59 z.z = fabs(z.z + fractal->transformCommon.additionConstant111.z)
60 - fabs(z.z - fractal->transformCommon.additionConstant111.z) - z.z;
61 zCol = z;
62 }
63
64 // spherical fold
65 if (aux.i >= fractal->transformCommon.startIterationsS
66 && aux.i < fractal->transformCommon.stopIterationsS)
67 {
68 double rr = z.Dot(z);
69 rrCol = rr;
70 z += fractal->mandelbox.offset;
71
72 // if (r2 < 1e-21) r2 = 1e-21;
73 if (rr < fractal->transformCommon.minR2p25)
74 {
75 double tglad_factor1 = fractal->transformCommon.maxR2d1 / fractal->transformCommon.minR2p25;
76 z *= tglad_factor1;
77 aux.DE *= tglad_factor1;
78 }
79 else if (rr < fractal->transformCommon.maxR2d1)
80 {
81 double tglad_factor2 = fractal->transformCommon.maxR2d1 / rr;
82 z *= tglad_factor2;
83 aux.DE *= tglad_factor2;
84 }
85 z -= fractal->mandelbox.offset;
86 }
87 // scale
88 if (aux.i >= fractal->transformCommon.startIterationsC
89 && aux.i < fractal->transformCommon.stopIterationsC)
90 {
91
92 double useScale = aux.actualScaleA + fractal->transformCommon.scale;
93
94 z *= useScale;
95 aux.DE = aux.DE * fabs(useScale);
96
97 if (aux.i >= fractal->transformCommon.startIterationsX
98 && aux.i < fractal->transformCommon.stopIterationsX)
99 {
100 // update actualScale for next iteration
101 double vary = fractal->transformCommon.scaleVary0
102 * (fabs(aux.actualScaleA) - fractal->transformCommon.scaleB1);
103 if (fractal->transformCommon.functionEnabledMFalse)
104 aux.actualScaleA = -vary;
105 else
106 aux.actualScaleA = aux.actualScaleA - vary;
107 }
108 }
109
110 if (fractal->transformCommon.functionEnabledXFalse
111 && aux.i >= fractal->transformCommon.startIterationsTM
112 && aux.i < fractal->transformCommon.stopIterationsTM1)
113 {
114 double tempXZ = z.x * SQRT_2_3 - z.z * SQRT_1_3;
115 z = CVector4(
116 (tempXZ - z.y) * SQRT_1_2, (tempXZ + z.y) * SQRT_1_2, z.x * SQRT_1_3 + z.z * SQRT_2_3, z.w);
117 CVector4 temp = z;
118 double tempL = temp.Length();
119 z = fabs(z) * fractal->transformCommon.scale3D333;
120 // if (tempL < 1e-21) tempL = 1e-21;
121 double avgScale = z.Length() / tempL;
122 aux.DE = aux.DE * avgScale;
123 z = (fabs(z + fractal->transformCommon.additionConstantA111)
124 - fabs(z - fractal->transformCommon.additionConstantA111) - z);
125 tempXZ = (z.y + z.x) * SQRT_1_2;
126 z = CVector4(z.z * SQRT_1_3 + tempXZ * SQRT_2_3, (z.y - z.x) * SQRT_1_2,
127 z.z * SQRT_2_3 - tempXZ * SQRT_1_3, z.w);
128 }
129
130 // octo
131 if (fractal->transformCommon.functionEnabledDFalse
132 && aux.i >= fractal->transformCommon.startIterationsD
133 && aux.i < fractal->transformCommon.stopIterationsD)
134
135 {
136 if (z.x + z.y < 0.0) z = CVector4(-z.y, -z.x, z.z, z.w);
137
138 if (z.x + z.z < 0.0) // z.xz = -z.zx;
139 z = CVector4(-z.z, z.y, -z.x, z.w);
140
141 if (z.x - z.y < 0.0) // z.xy = z.yx;
142 z = CVector4(z.y, z.x, z.z, z.w);
143
144 if (z.x - z.z < 0.0) // z.xz = z.zx;
145 z = CVector4(z.z, z.y, z.x, z.w);
146
147 z.x = fabs(z.x);
148 z = z * fractal->transformCommon.scaleA2
149 - fractal->transformCommon.offset100 * (fractal->transformCommon.scaleA2 - 1.0);
150 aux.DE *= fabs(fractal->transformCommon.scaleA2);
151 }
152
153 if (fractal->transformCommon.functionEnabledRFalse
154 && aux.i >= fractal->transformCommon.startIterationsR
155 && aux.i < fractal->transformCommon.stopIterationsR)
156 z = fractal->transformCommon.rotationMatrix.RotateVector(z);
157
158 if (fractal->transformCommon.functionEnabledFFalse
159 && aux.i >= fractal->transformCommon.startIterationsM
160 && aux.i < fractal->transformCommon.stopIterationsM)
161 { // fabs() and menger fold
162 z = fabs(z + fractal->transformCommon.additionConstantA000);
163 if (z.x - z.y < 0.0) swap(z.y, z.x);
164 if (z.x - z.z < 0.0) swap(z.z, z.x);
165 if (z.y - z.z < 0.0) swap(z.z, z.y);
166 // menger scales and offsets
167 z *= fractal->transformCommon.scale3;
168 z.x -= 2.0 * fractal->transformCommon.constantMultiplier111.x;
169 z.y -= 2.0 * fractal->transformCommon.constantMultiplier111.y;
170 if (fractal->transformCommon.functionEnabled)
171 {
172 if (z.z > 1.0) z.z -= 2.0 * fractal->transformCommon.constantMultiplier111.z;
173 }
174 else
175 {
176 z.z -= 2.0 * fractal->transformCommon.constantMultiplier111.z;
177 }
178 aux.DE *= fractal->transformCommon.scale3;
179 }
180
181 if (aux.i >= fractal->transformCommon.startIterationsA
182 && aux.i < fractal->transformCommon.stopIterationsA)
183 {
184 aux.r = z.Length();
185
186 if (fractal->analyticDE.enabledFalse)
187 {
188 aux.DE = aux.r * aux.DE * 10.0 * fractal->analyticDE.scale1
189 * sqrt(fractal->foldingIntPow.zFactor * fractal->foldingIntPow.zFactor + 2.0
190 + fractal->analyticDE.offset2)
191 + fractal->analyticDE.offset1;
192 }
193 else
194 {
195 aux.DE = aux.r * aux.DE * 16.0 * fractal->analyticDE.scale1
196 * sqrt(fractal->foldingIntPow.zFactor * fractal->foldingIntPow.zFactor + 2.0
197 + fractal->analyticDE.offset2)
198 / SQRT_3
199 + fractal->analyticDE.offset1;
200 }
201
202 z *= 2.0;
203 double x2 = z.x * z.x;
204 double y2 = z.y * z.y;
205 double z2 = z.z * z.z;
206 double temp = 1.0 - z2 / (x2 + y2);
207 CVector4 zTemp;
208 zTemp.x = (x2 - y2) * temp;
209 zTemp.y = 2.0 * z.x * z.y * temp;
210 zTemp.z = -2.0 * z.z * sqrt(x2 + y2);
211 zTemp.w = z.w;
212 z = zTemp;
213 z.z *= fractal->foldingIntPow.zFactor;
214 }
215 if (fractal->foldColor.auxColorEnabledFalse)
216 {
217 if (zCol.x != oldZ.x)
218 colorAdd += fractal->mandelbox.color.factor.x
219 * (fabs(zCol.x) - fractal->transformCommon.additionConstant111.x);
220 if (zCol.y != oldZ.y)
221 colorAdd += fractal->mandelbox.color.factor.y
222 * (fabs(zCol.y) - fractal->transformCommon.additionConstant111.y);
223 if (zCol.z != oldZ.z)
224 colorAdd += fractal->mandelbox.color.factor.z
225 * (fabs(zCol.z) - fractal->transformCommon.additionConstant111.z);
226
227 if (rrCol < fractal->transformCommon.maxR2d1)
228 {
229 if (rrCol < fractal->transformCommon.minR2p25)
230 colorAdd += fractal->mandelbox.color.factorSp1 * (fractal->transformCommon.minR2p25 - rrCol)
231 + fractal->mandelbox.color.factorSp2
232 * (fractal->transformCommon.maxR2d1 - fractal->transformCommon.minR2p25);
233 else
234 colorAdd += fractal->mandelbox.color.factorSp2 * (fractal->transformCommon.maxR2d1 - rrCol);
235 }
236
237 aux.color += colorAdd;
238 }
239 }
240