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 * spherical invert ( v2.17)
10 * from M3D. Formula by Luca GN 2011, updated May 2012.
11 * @reference
12 * http://www.fractalforums.com/mandelbulb-3d/custom-formulas-and-transforms-release-t17106/
13 */
14
15 #include "all_fractal_definitions.h"
16
cFractalTransfSphericalInvV2()17 cFractalTransfSphericalInvV2::cFractalTransfSphericalInvV2() : cAbstractFractal()
18 {
19 nameInComboBox = "T>Spherical Invert V2";
20 internalName = "transf_spherical_inv_v2";
21 internalID = fractal::transfSphericalInvV2;
22 DEType = analyticDEType;
23 DEFunctionType = withoutDEFunction;
24 cpixelAddition = cpixelDisabledByDefault;
25 defaultBailout = 100.0;
26 DEAnalyticFunction = analyticFunctionNone;
27 coloringFunction = coloringFunctionDefault;
28 }
29
FormulaCode(CVector4 & z,const sFractal * fractal,sExtendedAux & aux)30 void cFractalTransfSphericalInvV2::FormulaCode(
31 CVector4 &z, const sFractal *fractal, sExtendedAux &aux)
32 {
33 double rr = 0.0;
34 // unconditional mode
35 if (fractal->transformCommon.functionEnabledCz)
36 {
37 if (aux.i >= fractal->transformCommon.startIterationsD
38 && aux.i < fractal->transformCommon.stopIterationsD1)
39 {
40 z += fractal->transformCommon.offset000;
41 rr = z.Dot(z);
42 z *= fractal->transformCommon.maxR2d1 / rr;
43 z += fractal->transformCommon.additionConstant000 - fractal->transformCommon.offset000;
44 // double r = sqrt(rr);
45 aux.DE = (fractal->transformCommon.maxR2d1) / rr;
46 }
47 }
48
49 // conditional modes
50 if (fractal->transformCommon.functionEnabledCxFalse
51 && aux.i >= fractal->transformCommon.startIterationsC
52 && aux.i < fractal->transformCommon.stopIterationsC)
53 {
54 rr = z.Dot(z);
55 double mode = rr;
56 z += fractal->mandelbox.offset;
57
58 if (rr < fractal->mandelbox.foldingSphericalFixed)
59 {
60 mode = 0.0;
61 if (fractal->transformCommon.functionEnabledFalse) // Mode 1 minR0
62 {
63 if (rr < fractal->transformCommon.minR0) mode = fractal->transformCommon.minR0;
64 }
65 if (fractal->transformCommon.functionEnabledxFalse) // Mode 2
66 {
67 if (rr < fractal->transformCommon.minR0) mode = 2.0 * fractal->transformCommon.minR0 - rr;
68 }
69 mode = 1.0 / mode;
70 z *= mode;
71 aux.DE *= fabs(mode);
72 }
73 z -= fractal->mandelbox.offset;
74 }
75
76 // other modes
77 if (fractal->transformCommon.functionEnabledCyFalse
78 && aux.i >= fractal->transformCommon.startIterationsB
79 && aux.i < fractal->transformCommon.stopIterationsB)
80 {
81 rr = z.Dot(z);
82 double mode = rr;
83 if (rr < fractal->transformCommon.scaleE1) // < maxRR
84 {
85 double lengthAB = fractal->transformCommon.scaleE1 - fractal->transformCommon.offsetC0;
86
87 if (fractal->transformCommon.functionEnabledyFalse) // Mode 3a, linear addition 0.0 at Max,
88 {
89 if (rr < fractal->transformCommon.offsetC0)
90 mode += rr * (fractal->transformCommon.offset0 / fractal->transformCommon.offsetC0);
91 else
92 mode +=
93 (fractal->transformCommon.scaleE1 - rr) * fractal->transformCommon.offset0 / lengthAB;
94 }
95
96 if (fractal->transformCommon.functionEnabledzFalse) // Mode 3b
97 {
98
99 if (rr > fractal->transformCommon.offsetC0)
100 mode += fractal->transformCommon.offsetB0 * (fractal->transformCommon.scaleE1 - rr);
101 else
102 mode += fractal->transformCommon.offsetA0 * (fractal->transformCommon.offsetC0 - rr)
103 + fractal->transformCommon.offsetB0 * lengthAB;
104 }
105
106 if (fractal->transformCommon.functionEnabledwFalse) // Mode 3c, basic parabolic curve
107 {
108
109 double halfLen = fractal->transformCommon.scaleE1 / 2.0;
110 double slope = 2.0 / fractal->transformCommon.scaleE1;
111 double factor = slope / fractal->transformCommon.scaleE1;
112 double parab = 0.0;
113
114 if (rr < halfLen)
115 {
116 parab = rr * rr * factor * fractal->transformCommon.scaleG1;
117 mode += rr * slope * fractal->transformCommon.scaleF1 - parab;
118 }
119 else
120 {
121 double temp = fractal->transformCommon.scaleE1 - rr;
122 parab = temp * temp * factor * fractal->transformCommon.scaleG1;
123 mode += temp * slope * fractal->transformCommon.scaleF1 - parab;
124 }
125 }
126
127 /*if (fractal->transformCommon.functionEnabledwFalse) // Mode 3d
128 {
129 mode = rr + fractal->transformCommon.offset0 * (fractal->mandelbox.foldingSphericalFixed -
130 rr);
131 if (rr < fractal->transformCommon.minR0)
132 mode -= rr * (fractal->transformCommon.offset0
133 * (fractal->mandelbox.foldingSphericalFixed - fractal->transformCommon.minR0))
134 / fractal->transformCommon.minR0;
135 }*/
136 mode = 1.0 / mode;
137 z *= mode;
138 aux.DE *= fabs(mode);
139 }
140 }
141
142 if (fractal->analyticDE.enabledFalse)
143 {
144 aux.DE = aux.DE * fractal->analyticDE.scale1 + fractal->analyticDE.offset0;
145 }
146 }
147