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  * Adds Cpixel constant to z vector, scator algebra
10  * based on Manuel's math
11  * @reference
12  * https://luz.izt.uam.mx/drupal/en/fractals/hun
13  * @author Manuel Fernandez-Guasti
14  */
15 
16 #include "all_fractal_definitions.h"
17 
cFractalTransfAddCpixelScator()18 cFractalTransfAddCpixelScator::cFractalTransfAddCpixelScator() : cAbstractFractal()
19 {
20 	nameInComboBox = "T>Add Cpixel - Scator";
21 	internalName = "transf_add_cpixel_scator";
22 	internalID = fractal::transfAddCpixelScator;
23 	DEType = analyticDEType;
24 	DEFunctionType = withoutDEFunction;
25 	cpixelAddition = cpixelDisabledByDefault;
26 	defaultBailout = 100.0;
27 	DEAnalyticFunction = analyticFunctionNone;
28 	coloringFunction = coloringFunctionDefault;
29 }
30 
FormulaCode(CVector4 & z,const sFractal * fractal,sExtendedAux & aux)31 void cFractalTransfAddCpixelScator::FormulaCode(
32 	CVector4 &z, const sFractal *fractal, sExtendedAux &aux)
33 {
34 	CVector4 oldZ = z;
35 	CVector4 tempC = aux.const_c;
36 	if (fractal->transformCommon.functionEnabledSwFalse) swap(tempC.x, tempC.z);
37 
38 	CVector4 cc = tempC * tempC;
39 	CVector4 newC = tempC;
40 	double limitA = fractal->transformCommon.scale0;
41 
42 	if (fractal->transformCommon.functionEnabledRFalse)
43 	{
44 		cc = fabs(tempC);
45 	}
46 
47 	// scator algebra
48 	if (cc.x < limitA)
49 	{
50 		double temp = 1.0 / cc.x - 1.0;
51 		cc.x = temp;
52 	}
53 
54 	if (!fractal->transformCommon.functionEnabledFalse)
55 	{																	// real
56 		newC.x += (cc.y * cc.z) / cc.x; // all pos
57 		newC.y *= (1.0 + cc.z / cc.x);
58 		newC.z *= (1.0 + cc.y / cc.x);
59 		newC *= fractal->transformCommon.constantMultiplier111;
60 		if (fractal->transformCommon.functionEnabledSwFalse) swap(newC.x, newC.z);
61 
62 		if (!fractal->transformCommon.functionEnabledSFalse)
63 		{
64 			z += newC;
65 		}
66 		else
67 		{
68 			z.x += sign(z.x) * newC.x;
69 			z.y += sign(z.y) * newC.y;
70 			z.z += sign(z.z) * newC.z;
71 		}
72 	}
73 	else
74 	{																	// imaginary
75 		newC.x += (cc.y * cc.z) / cc.x; // pos
76 		newC.y *= (1.0 - cc.z / cc.x);	// pos  neg
77 		newC.z *= (1.0 - cc.y / cc.x);	// pos  neg
78 		newC *= fractal->transformCommon.constantMultiplier111;
79 		if (fractal->transformCommon.functionEnabledy) newC.y = fabs(newC.y);
80 		if (fractal->transformCommon.functionEnabledz) newC.z = fabs(newC.z);
81 
82 		if (fractal->transformCommon.functionEnabledSwFalse) swap(newC.x, newC.z);
83 
84 		// add Cpixel
85 		if (!fractal->transformCommon.functionEnabledSFalse)
86 		{
87 			z += newC;
88 		}
89 		else
90 		{
91 			z.x += sign(z.x) * newC.x;
92 			z.y += sign(z.y) * newC.y;
93 			z.z += sign(z.z) * newC.z;
94 		}
95 	}
96 	// DE calculations
97 	if (fractal->analyticDE.enabledFalse)
98 	{
99 		double vecDE = z.Length() / oldZ.Length();
100 		aux.DE = aux.DE * vecDE * fractal->analyticDE.scale1 + fractal->analyticDE.offset1;
101 	}
102 }
103