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 * Quaternion Fold Transform
10 * @reference http://www.fractalforums.com/3d-fractal-generation/true-3d-mandlebrot-type-fractal/
11 */
12
13 #include "all_fractal_definitions.h"
14
cFractalTransfQuaternionFold()15 cFractalTransfQuaternionFold::cFractalTransfQuaternionFold() : cAbstractFractal()
16 {
17 nameInComboBox = "T>Quaternion Fold";
18 internalName = "transf_quaternion_fold";
19 internalID = fractal::transfQuaternionFold;
20 DEType = analyticDEType;
21 DEFunctionType = logarithmicDEFunction;
22 cpixelAddition = cpixelDisabledByDefault;
23 defaultBailout = 100.0;
24 DEAnalyticFunction = analyticFunctionNone;
25 coloringFunction = coloringFunctionDefault;
26 }
27
FormulaCode(CVector4 & z,const sFractal * fractal,sExtendedAux & aux)28 void cFractalTransfQuaternionFold::FormulaCode(
29 CVector4 &z, const sFractal *fractal, sExtendedAux &aux)
30 {
31 CVector4 c = aux.const_c;
32 // quat fold
33 z = CVector4(z.x * z.x - z.y * z.y - z.z * z.z, z.x * z.y, z.x * z.z, z.w);
34
35 // quat scale and DE fudge
36
37 if (fractal->transformCommon.functionEnabledFalse)
38 {
39 z *= fractal->transformCommon.constantMultiplier122;
40 aux.DE *= 2.0;
41 }
42
43 // offset
44 z += fractal->transformCommon.additionConstant000;
45
46 // addCpixel
47 if (fractal->transformCommon.addCpixelEnabledFalse)
48 {
49 CVector4 tempC = c;
50 if (fractal->transformCommon.alternateEnabledFalse) // alternate
51 {
52 tempC = aux.c;
53 switch (fractal->mandelbulbMulti.orderOfXYZC)
54 {
55 case multi_OrderOfXYZ_xyz:
56 default: tempC = CVector4(tempC.x, tempC.y, tempC.z, tempC.w); break;
57 case multi_OrderOfXYZ_xzy: tempC = CVector4(tempC.x, tempC.z, tempC.y, tempC.w); break;
58 case multi_OrderOfXYZ_yxz: tempC = CVector4(tempC.y, tempC.x, tempC.z, tempC.w); break;
59 case multi_OrderOfXYZ_yzx: tempC = CVector4(tempC.y, tempC.z, tempC.x, tempC.w); break;
60 case multi_OrderOfXYZ_zxy: tempC = CVector4(tempC.z, tempC.x, tempC.y, tempC.w); break;
61 case multi_OrderOfXYZ_zyx: tempC = CVector4(tempC.z, tempC.y, tempC.x, tempC.w); break;
62 }
63 aux.c = tempC;
64 }
65 else
66 {
67 switch (fractal->mandelbulbMulti.orderOfXYZC)
68 {
69 case multi_OrderOfXYZ_xyz:
70 default: tempC = CVector4(c.x, c.y, c.z, c.w); break;
71 case multi_OrderOfXYZ_xzy: tempC = CVector4(c.x, c.z, c.y, c.w); break;
72 case multi_OrderOfXYZ_yxz: tempC = CVector4(c.y, c.x, c.z, c.w); break;
73 case multi_OrderOfXYZ_yzx: tempC = CVector4(c.y, c.z, c.x, c.w); break;
74 case multi_OrderOfXYZ_zxy: tempC = CVector4(c.z, c.x, c.y, c.w); break;
75 case multi_OrderOfXYZ_zyx: tempC = CVector4(c.z, c.y, c.x, c.w); break;
76 }
77 }
78 z += tempC * fractal->transformCommon.constantMultiplierC111;
79 }
80
81 // tweaking DE
82 aux.DE = aux.DE * aux.r * fractal->analyticDE.scale1 + fractal->analyticDE.offset0;
83 }
84