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  * Kaleidoscopic Iterated Function Systems (IFS)
10  * @reference
11  * http://www.fractalforums.com/ifs-iterated-function-systems/kaleidoscopic-(escape-time-ifs)/
12  */
13 
14 #include "all_fractal_definitions.h"
15 
cFractalKaleidoscopicIfs()16 cFractalKaleidoscopicIfs::cFractalKaleidoscopicIfs() : cAbstractFractal()
17 {
18 	nameInComboBox = "Kaleidoscopic IFS";
19 	internalName = "kaleidoscopic_ifs";
20 	internalID = fractal::kaleidoscopicIfs;
21 	DEType = analyticDEType;
22 	DEFunctionType = linearDEFunction;
23 	cpixelAddition = cpixelDisabledByDefault;
24 	defaultBailout = 100.0;
25 	DEAnalyticFunction = analyticFunctionIFS;
26 	coloringFunction = coloringFunctionIFS;
27 }
28 
FormulaCode(CVector4 & z,const sFractal * fractal,sExtendedAux & aux)29 void cFractalKaleidoscopicIfs::FormulaCode(CVector4 &z, const sFractal *fractal, sExtendedAux &aux)
30 {
31 	if (fractal->IFS.absX) z.x = fabs(z.x);
32 	if (fractal->IFS.absY) z.y = fabs(z.y);
33 	if (fractal->IFS.absZ) z.z = fabs(z.z);
34 
35 	for (int i = 0; i < IFS_VECTOR_COUNT; i++)
36 	{
37 		if (fractal->IFS.enabled[i])
38 		{
39 			z = fractal->IFS.rot[i].RotateVector(z);
40 			double length = z.Dot(fractal->IFS.direction[i]);
41 
42 			if (length < fractal->IFS.distance[i])
43 			{
44 				z -= fractal->IFS.direction[i]
45 						 * (2.0 * (length - fractal->IFS.distance[i]) * fractal->IFS.intensity[i]);
46 			}
47 		}
48 	}
49 
50 	if (fractal->IFS.rotationEnabled)
51 		z = fractal->IFS.mainRot.RotateVector(z - fractal->IFS.offset) + fractal->IFS.offset;
52 
53 	if (fractal->IFS.edgeEnabled)
54 	{
55 		if (fractal->IFS.edge.x > 0.0) z.x = fractal->IFS.edge.x - fabs(fractal->IFS.edge.x - z.x);
56 		if (fractal->IFS.edge.y > 0.0) z.y = fractal->IFS.edge.y - fabs(fractal->IFS.edge.y - z.y);
57 		if (fractal->IFS.edge.z > 0.0) z.z = fractal->IFS.edge.z - fabs(fractal->IFS.edge.z - z.z);
58 	}
59 
60 	z *= fractal->IFS.scale;
61 	if (fractal->IFS.mengerSpongeMode)
62 	{
63 		z.x -= fractal->IFS.offset.x * (fractal->IFS.scale - 1.0);
64 		z.y -= fractal->IFS.offset.y * (fractal->IFS.scale - 1.0);
65 		if (z.z > 0.5 * fractal->IFS.offset.z * (fractal->IFS.scale - 1.0))
66 			z.z -= fractal->IFS.offset.z * (fractal->IFS.scale - 1.0);
67 	}
68 	else
69 	{
70 		z -= fractal->IFS.offset * (fractal->IFS.scale - 1.0);
71 	}
72 	aux.DE *= fabs(fractal->IFS.scale);
73 }
74