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 * poly fold atan2
10 * @reference
11 * https://fractalforums.org/fragmentarium/17/polyfoldsym-pre-transform/2684
12 */
13
14 #include "all_fractal_definitions.h"
15
cFractalTransfPolyFoldAtan2()16 cFractalTransfPolyFoldAtan2::cFractalTransfPolyFoldAtan2() : cAbstractFractal()
17 {
18 nameInComboBox = "T>Poly Fold Atan2";
19 internalName = "transf_poly_fold_atan2";
20 internalID = fractal::transfPolyFoldAtan2;
21 DEType = analyticDEType;
22 DEFunctionType = withoutDEFunction;
23 cpixelAddition = cpixelDisabledByDefault;
24 defaultBailout = 100.0;
25 DEAnalyticFunction = analyticFunctionNone;
26 coloringFunction = coloringFunctionDefault;
27 }
28
FormulaCode(CVector4 & z,const sFractal * fractal,sExtendedAux & aux)29 void cFractalTransfPolyFoldAtan2::FormulaCode(
30 CVector4 &z, const sFractal *fractal, sExtendedAux &aux)
31 {
32 CVector4 oldZ = z;
33 // pre abs
34 if (fractal->transformCommon.functionEnabledx) z.x = fabs(z.x);
35 if (fractal->transformCommon.functionEnabledyFalse) z.y = fabs(z.y);
36 if (fractal->transformCommon.functionEnabledzFalse) z.z = fabs(z.z);
37
38 if (fractal->transformCommon.functionEnabledCx)
39 {
40 if (fractal->transformCommon.functionEnabledAxFalse && z.y < 0.0) z.x = -z.x;
41 double psi = M_PI / fractal->transformCommon.int8X;
42 psi = fabs(fmod(atan2(z.y, z.x) + psi, 2.0 * psi) - psi);
43 double len = sqrt(z.x * z.x + z.y * z.y);
44 z.x = cos(psi) * len;
45 z.y = sin(psi) * len;
46 }
47
48 if (fractal->transformCommon.functionEnabledCyFalse)
49 {
50 if (fractal->transformCommon.functionEnabledAyFalse && z.z < 0.0) z.y = -z.y;
51 double psi = M_PI / fractal->transformCommon.int8Y;
52 psi = fabs(fmod(atan2(z.z, z.y) + psi, 2.0 * psi) - psi);
53 double len = sqrt(z.y * z.y + z.z * z.z);
54 z.y = cos(psi) * len;
55 z.z = sin(psi) * len;
56 }
57
58 if (fractal->transformCommon.functionEnabledCzFalse)
59 {
60 if (fractal->transformCommon.functionEnabledAzFalse && z.x < 0.0) z.z = -z.z;
61 double psi = M_PI / fractal->transformCommon.int8Z;
62 psi = fabs(fmod(atan2(z.x, z.z) + psi, 2.0 * psi) - psi);
63 double len = sqrt(z.z * z.z + z.x * z.x);
64 z.z = cos(psi) * len;
65 z.x = sin(psi) * len;
66 }
67
68 // addition constant
69 z += fractal->transformCommon.additionConstant000;
70
71 // rotation
72 if (fractal->transformCommon.rotation2EnabledFalse)
73 {
74 z = fractal->transformCommon.rotationMatrix.RotateVector(z);
75 }
76
77 // DE tweaks
78 if (fractal->analyticDE.enabled)
79 {
80 if (!fractal->analyticDE.enabledFalse)
81 aux.DE = aux.DE * fractal->analyticDE.scale1 + fractal->analyticDE.offset0;
82 else
83 {
84 double avgScale = z.Length() / oldZ.Length();
85 aux.DE = aux.DE * avgScale * fractal->analyticDE.scale1 + fractal->analyticDE.offset0;
86 }
87 }
88 }
89