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  * TransfDifsCylinderV2Iteration  fragmentarium code, mdifs by knighty (jan 2012)
10  * and http://www.iquilezles.org/www/articles/distfunctions/distfunctions.htm
11  */
12 
13 #include "all_fractal_definitions.h"
14 
cFractalTransfDIFSCylinderV2()15 cFractalTransfDIFSCylinderV2::cFractalTransfDIFSCylinderV2() : cAbstractFractal()
16 {
17 	nameInComboBox = "T>DIFS Cylinder V2";
18 	internalName = "transf_difs_cylinder_v2";
19 	internalID = fractal::transfDIFSCylinderV2;
20 	DEType = analyticDEType;
21 	DEFunctionType = customDEFunction;
22 	cpixelAddition = cpixelDisabledByDefault;
23 	defaultBailout = 100.0;
24 	DEAnalyticFunction = analyticFunctionCustomDE;
25 	coloringFunction = coloringFunctionDefault;
26 }
27 
FormulaCode(CVector4 & z,const sFractal * fractal,sExtendedAux & aux)28 void cFractalTransfDIFSCylinderV2::FormulaCode(
29 	CVector4 &z, const sFractal *fractal, sExtendedAux &aux)
30 {
31 	if (fractal->transformCommon.functionEnabledAFalse)
32 	{
33 		if (fractal->transformCommon.functionEnabledAxFalse) z.x = fabs(z.x);
34 		if (fractal->transformCommon.functionEnabledAyFalse) z.y = fabs(z.y);
35 		if (fractal->transformCommon.functionEnabledAzFalse) z.z = fabs(z.z);
36 	}
37 	z += fractal->transformCommon.offset000;
38 
39 	if (fractal->transformCommon.rotationEnabledFalse
40 			&& aux.i >= fractal->transformCommon.startIterationsR
41 			&& aux.i < fractal->transformCommon.stopIterationsR1)
42 	{
43 		z = fractal->transformCommon.rotationMatrix.RotateVector(z);
44 	}
45 
46 	CVector4 zc = z;
47 
48 	double temp;
49 	// swap axis
50 	if (fractal->transformCommon.functionEnabledSwFalse) swap(zc.x, zc.z);
51 
52 	double cylR = zc.x * zc.x;
53 	double absH = fabs(zc.z);
54 	double lengthCyl = zc.z;
55 
56 	cylR = sqrt(cylR + zc.y * zc.y);
57 	double cylH = absH - fractal->transformCommon.offsetA1;
58 
59 	// no absz
60 	if (fractal->transformCommon.functionEnabledMFalse
61 			&& aux.i >= fractal->transformCommon.startIterationsM
62 			&& aux.i < fractal->transformCommon.stopIterationsM)
63 	{
64 		absH = lengthCyl;
65 	}
66 
67 	// abs sqrd
68 	if (fractal->transformCommon.functionEnabledTFalse
69 			&& aux.i >= fractal->transformCommon.startIterationsT
70 			&& aux.i < fractal->transformCommon.stopIterationsT)
71 	{
72 		absH *= absH;
73 	}
74 
75 	double cylRm = cylR - fractal->transformCommon.radius1;
76 	if (fractal->transformCommon.functionEnabledFalse)
77 		cylRm = fabs(cylRm ) - fractal->transformCommon.offset0;
78 
79 	cylRm += fractal->transformCommon.scale0 * absH;
80 	zc.z = absH;
81 
82 	// tops
83 	if (fractal->transformCommon.functionEnabledNFalse
84 			&& aux.i >= fractal->transformCommon.startIterationsN
85 			&& aux.i < fractal->transformCommon.stopIterationsN)
86 	{
87 		temp = cylR;
88 	}
89 	else
90 	{
91 		temp = cylRm;
92 	}
93 	temp = max(temp, 0.0);
94 	double cylHm = max(cylH, 0.0);
95 	double cylD = sqrt(temp * temp + cylHm * cylHm);
96 
97 	// rings
98 	if (fractal->transformCommon.functionEnabledOFalse
99 			&& aux.i >= fractal->transformCommon.startIterationsO
100 			&& aux.i < fractal->transformCommon.stopIterationsO)
101 	{
102 		cylD = sqrt(cylRm * cylRm + cylH * cylH);
103 	}
104 	cylD = min(max(cylRm, cylH) - fractal->transformCommon.offsetR0, 0.0) + cylD;
105 
106 	aux.dist = min(aux.dist, cylD / (aux.DE + 1.0));
107 
108 	if (fractal->transformCommon.functionEnabledZcFalse
109 			&& aux.i >= fractal->transformCommon.startIterationsZc
110 			&& aux.i < fractal->transformCommon.stopIterationsZc)
111 				z = zc;
112 }
113