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 * Testing
10 *
11 * https://www.shadertoy.com/view/3ddSDs
12 * Based upon: https://www.shadertoy.com/view/XdlSD4
13 */
14
15 #include "all_fractal_definitions.h"
16
cFractalTesting()17 cFractalTesting::cFractalTesting() : cAbstractFractal()
18 {
19 nameInComboBox = "Testing";
20 internalName = "testing";
21 internalID = fractal::testing;
22 DEType = analyticDEType;
23 DEFunctionType = customDEFunction;
24 cpixelAddition = cpixelDisabledByDefault;
25 defaultBailout = 100.0;
26 DEAnalyticFunction = analyticFunctionCustomDE;
27 coloringFunction = coloringFunctionDefault;
28 }
29
FormulaCode(CVector4 & z,const sFractal * fractal,sExtendedAux & aux)30 void cFractalTesting::FormulaCode(CVector4 &z, const sFractal *fractal, sExtendedAux &aux)
31 {
32 if (fractal->transformCommon.functionEnabledM)
33 {
34
35 z.x = fabs(z.x + fractal->transformCommon.additionConstant111.x)
36 - fabs(z.x - fractal->transformCommon.additionConstant111.x) - z.x;
37 z.y = fabs(z.y + fractal->transformCommon.additionConstant111.y)
38 - fabs(z.y - fractal->transformCommon.additionConstant111.y) - z.y;
39 if (fractal->transformCommon.functionEnabled)
40 {
41 z.z = fabs(z.z + fractal->transformCommon.additionConstant111.z)
42 - fabs(z.z - fractal->transformCommon.additionConstant111.z) - z.z;
43 }
44
45 double rr = z.Dot(z);
46 if (rr < fractal->transformCommon.minR2p25)
47 {
48 z *= fractal->transformCommon.maxMinR2factor;
49 aux.DE *= fractal->transformCommon.maxMinR2factor;
50 }
51 else if (rr < fractal->transformCommon.maxR2d1)
52 {
53 z *= fractal->transformCommon.maxR2d1 / rr;
54 aux.DE *= fractal->transformCommon.maxR2d1 / rr;
55 }
56
57 // scale
58 double useScale = 1.0;
59 useScale = aux.actualScaleA + fractal->transformCommon.scale2;
60 z *= useScale;
61 aux.DE = aux.DE * fabs(useScale) + 1.0;
62
63 if (fractal->transformCommon.functionEnabledKFalse
64 && aux.i >= fractal->transformCommon.startIterationsK
65 && aux.i < fractal->transformCommon.stopIterationsK)
66 {
67 // update actualScaleA for next iteration
68 double vary = fractal->transformCommon.scaleVary0
69 * (fabs(aux.actualScaleA) - fractal->transformCommon.scaleC1);
70 aux.actualScaleA -= vary;
71 }
72
73
74 //z *= fractal->transformCommon.scale2;
75 //aux.DE = aux.DE * fabs(fractal->transformCommon.scale2) + 1.0;
76 }
77
78 // menger
79 if (fractal->transformCommon.functionEnabledNFalse)
80 {
81 z = fabs(z + fractal->transformCommon.offsetA000);
82
83 if (z.x - z.y < 0.0) swap(z.x, z.y);
84 if (z.x - z.z < 0.0) swap(z.x, z.z);
85 if (z.y - z.z < 0.0) swap(z.y, z.z);
86
87 z *= fractal->transformCommon.scale3; // 3
88
89 z.x -= 2.0;
90 z.y -= 2.0;
91 if (z.z > 1.0) z.z -= 2.0;
92
93 aux.DE *= fractal->transformCommon.scale3; // 3
94 }
95
96 // bulb
97 if (fractal->transformCommon.functionEnabledOFalse)
98 {
99 // if (aux.r < 1e-21) aux.r = 1e-21;
100 const double th0 = asin(z.z / aux.r) + fractal->bulb.betaAngleOffset;
101 const double ph0 = atan2(z.y, z.x) + fractal->bulb.alphaAngleOffset;
102 double rp = pow(aux.r, fractal->bulb.power - 1.0);
103 const double th = th0 * fractal->bulb.power;
104 const double ph = ph0 * fractal->bulb.power;
105 const double cth = cos(th);
106 aux.DE = (rp * aux.DE) * fractal->bulb.power + 1.0;
107 rp *= aux.r;
108 z.x = cth * cos(ph) * rp;
109 z.y = cth * sin(ph) * rp;
110 z.z = sin(th) * rp;
111 }
112 // rotation
113 if (fractal->transformCommon.functionEnabledRFalse)
114 {
115 z = fractal->transformCommon.rotationMatrix.RotateVector(z);
116 }
117 z += fractal->transformCommon.offset000;
118
119 z += aux.c * fractal->transformCommon.constantMultiplier111;
120
121
122
123 // THE FOLLOWING CAN BE A TRANSFORM
124
125 CVector4 zc = z;
126 // cylinder
127 double cylinder;
128 double cylR = sqrt(zc.x * zc.x + zc.y * zc.y) - fractal->transformCommon.radius1;
129 double cylH = fabs(zc.z) - fractal->transformCommon.offsetA1;
130 cylR = max(cylR, 0.0);
131 cylH = max(cylH, 0.0);
132 double cylD = sqrt(cylR * cylR + cylH * cylH);
133 cylinder = min(max(cylR, cylH), 0.0) + cylD;
134
135 // box
136 CVector4 boxSize = fractal->transformCommon.offset111;
137 zc = fabs(zc) - boxSize;
138 zc.x = max(zc.x, 0.0);
139 zc.y = max(zc.y, 0.0);
140 zc.z = max(zc.z, 0.0);
141 double box = zc.Length();
142 zc = z;
143
144 // ellipsoid
145 CVector4 rads4 = fractal->transformCommon.offsetA111;
146 CVector3 rads3 = CVector3(rads4.x, rads4.y, rads4.z);
147 CVector3 rV = CVector3(zc.x, zc.y, zc.z);
148 rV /= rads3;
149 CVector3 rrV = rV;
150 rrV /= rads3;
151 double rd = rV.Length();
152 double rrd = rrV.Length();
153 double ellipsoid = rd * (rd - 1.0) / rrd;
154
155 // sphere
156 double sphere = zc.Length() - fractal->transformCommon.offset3;
157
158 // torus
159 double torus = sqrt(z.x * z.x + z.z * z.z) - fractal->transformCommon.offset4;
160 torus = sqrt(torus * torus + z.y * z.y) - fractal->transformCommon.offset1;
161
162 if (fractal->transformCommon.functionEnabledxFalse) torus = cylinder;
163 if (fractal->transformCommon.functionEnabledyFalse) sphere = box;
164 if (fractal->transformCommon.functionEnabledzFalse) sphere = ellipsoid;
165
166 // THE FOLLOWING CAN BE A TRANSFORM
167 int count = fractal->transformCommon.int3;
168 int tempC = fractal->transformCommon.int3X;
169 double r;
170
171 if (!fractal->transformCommon.functionEnabledSwFalse)
172 {
173 r = (aux.i < count) ? torus : sphere;
174 }
175 else
176 {
177 r = (aux.i < count) ? sphere : torus;
178 }
179
180 aux.DE = aux.DE + fractal->analyticDE.offset0;
181
182 double dd = r;
183 if (fractal->transformCommon.functionEnabledAx)
184 {
185 dd = dd / aux.DE; // same as an uncondtional aux.dist
186 }
187 if (fractal->transformCommon.functionEnabledBFalse)
188 {
189 double rxy = sqrt(z.x * z.x + z.y * z.y);
190 double m = max(rxy - fractal->transformCommon.offsetT1, fabs(rxy * z.z) / dd);
191 dd = m / aux.DE;
192 }
193 if (fractal->transformCommon.functionEnabledCFalse)
194 {
195 dd = 0.5 * dd * log(dd) / aux.DE; // = using linear and increasining detail level
196 }
197
198 if (aux.i < tempC || dd < aux.colorHybrid)
199 {
200 aux.colorHybrid = dd;
201 }
202
203 aux.dist = aux.colorHybrid;
204 }
205