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  * MandelbulbAbsPower2Iteration
10  * @reference /http://www.fractalforums.com/gallery-b177/buffalo-fractals
11  */
12 
13 #include "all_fractal_definitions.h"
14 
cFractalMandelbulbAbsPower2()15 cFractalMandelbulbAbsPower2::cFractalMandelbulbAbsPower2() : cAbstractFractal()
16 {
17 	nameInComboBox = "Mandelbulb - Abs Power 2";
18 	internalName = "mandelbulb_abs_power2";
19 	internalID = fractal::mandelbulbAbsPower2;
20 	DEType = analyticDEType;
21 	DEFunctionType = logarithmicDEFunction;
22 	cpixelAddition = cpixelEnabledByDefault;
23 	defaultBailout = 10.0;
24 	DEAnalyticFunction = analyticFunctionLogarithmic;
25 	coloringFunction = coloringFunctionDefault;
26 }
27 
FormulaCode(CVector4 & z,const sFractal * fractal,sExtendedAux & aux)28 void cFractalMandelbulbAbsPower2::FormulaCode(
29 	CVector4 &z, const sFractal *fractal, sExtendedAux &aux)
30 {
31 	CVector4 c = aux.const_c;
32 
33 	// pre rotation
34 	if (fractal->transformCommon.rotationEnabled && aux.i >= fractal->transformCommon.startIterationsR
35 			&& aux.i < fractal->transformCommon.stopIterationsR)
36 	{
37 		z = fractal->transformCommon.rotationMatrix.RotateVector(z);
38 	}
39 	// pre-offset
40 	if (fractal->transformCommon.functionEnabledDFalse
41 			&& aux.i >= fractal->transformCommon.startIterationsD
42 			&& aux.i < fractal->transformCommon.stopIterationsD)
43 	{
44 		z += fractal->transformCommon.offsetA000;
45 	}
46 
47 	aux.DE = aux.DE * 2.0 * aux.r;
48 
49 	// pre abs. abs(z.x) and abs(z.y) effect newy. abs(z.z) effects newz
50 	if (fractal->buffalo.preabsx) z.x = fabs(z.x);
51 	if (fractal->buffalo.preabsy) z.y = fabs(z.y);
52 	if (fractal->buffalo.preabsz) z.z = fabs(z.z);
53 
54 	CVector4 zz = z * z;
55 	CVector4 newZ = z;
56 	double temp = 1.0 - zz.z / (zz.x + zz.y);
57 	newZ.x = (zz.x - zz.y) * temp;
58 	newZ.y = 2.0 * z.x * z.y * temp;
59 	newZ.z = (fractal->buffalo.posz ? 2.0 : -2.0) * z.z * sqrt(zz.x + zz.y);
60 	z = newZ;
61 
62 	z.x = fractal->buffalo.absx ? fabs(z.x) : z.x;
63 	z.y = fractal->buffalo.absy ? fabs(z.y) : z.y;
64 	z.z = fractal->buffalo.absz ? fabs(z.z) : z.z;
65 
66 	// offset
67 	if (fractal->transformCommon.functionEnabledM
68 			&& aux.i >= fractal->transformCommon.startIterationsM
69 			&& aux.i < fractal->transformCommon.stopIterationsM)
70 	{
71 		z += fractal->transformCommon.offset000;
72 	}
73 	// rotation
74 	if (fractal->transformCommon.functionEnabled && aux.i >= fractal->transformCommon.startIterationsS
75 			&& aux.i < fractal->transformCommon.stopIterationsS)
76 	{
77 		z = fractal->mandelbox.mainRot.RotateVector(z);
78 	}
79 
80 	// addCpixel
81 	if (fractal->transformCommon.addCpixelEnabledFalse
82 			&& aux.i >= fractal->transformCommon.startIterationsE
83 			&& aux.i < fractal->transformCommon.stopIterationsE)
84 	{
85 		CVector4 tempC = c;
86 		if (fractal->transformCommon.alternateEnabledFalse) // alternate
87 		{
88 			tempC = aux.c;
89 			switch (fractal->mandelbulbMulti.orderOfXYZ)
90 			{
91 				case multi_OrderOfXYZ_xyz:
92 				default: tempC = CVector4(tempC.x, tempC.y, tempC.z, tempC.w); break;
93 				case multi_OrderOfXYZ_xzy: tempC = CVector4(tempC.x, tempC.z, tempC.y, tempC.w); break;
94 				case multi_OrderOfXYZ_yxz: tempC = CVector4(tempC.y, tempC.x, tempC.z, tempC.w); break;
95 				case multi_OrderOfXYZ_yzx: tempC = CVector4(tempC.y, tempC.z, tempC.x, tempC.w); break;
96 				case multi_OrderOfXYZ_zxy: tempC = CVector4(tempC.z, tempC.x, tempC.y, tempC.w); break;
97 				case multi_OrderOfXYZ_zyx: tempC = CVector4(tempC.z, tempC.y, tempC.x, tempC.w); break;
98 			}
99 			aux.c = tempC;
100 		}
101 		else
102 		{
103 			switch (fractal->mandelbulbMulti.orderOfXYZ)
104 			{
105 				case multi_OrderOfXYZ_xyz:
106 				default: tempC = CVector4(c.x, c.y, c.z, c.w); break;
107 				case multi_OrderOfXYZ_xzy: tempC = CVector4(c.x, c.z, c.y, c.w); break;
108 				case multi_OrderOfXYZ_yxz: tempC = CVector4(c.y, c.x, c.z, c.w); break;
109 				case multi_OrderOfXYZ_yzx: tempC = CVector4(c.y, c.z, c.x, c.w); break;
110 				case multi_OrderOfXYZ_zxy: tempC = CVector4(c.z, c.x, c.y, c.w); break;
111 				case multi_OrderOfXYZ_zyx: tempC = CVector4(c.z, c.y, c.x, c.w); break;
112 			}
113 		}
114 		z += tempC * fractal->transformCommon.constantMultiplier111;
115 	}
116 
117 	// final abs
118 	if (fractal->transformCommon.functionEnabledPFalse
119 			&& aux.i >= fractal->transformCommon.startIterationsH
120 			&& aux.i < fractal->transformCommon.stopIterationsH)
121 	{
122 		if (fractal->transformCommon.functionEnabledCxFalse) z.x = fabs(z.x);
123 		if (fractal->transformCommon.functionEnabledCyFalse) z.y = fabs(z.y);
124 		if (fractal->transformCommon.functionEnabledCzFalse) z.z = fabs(z.z);
125 	}
126 
127 	// Analytic DE tweak
128 	if (fractal->analyticDE.enabledFalse)
129 		aux.DE = aux.DE * fractal->analyticDE.scale1 + fractal->analyticDE.offset0;
130 }
131