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 * spherical radial offset Curvilinear. 10 * This formula contains analytic aux.DE and aux.r-dz 11 */ 12 13 #include "all_fractal_definitions.h" 14 cFractalTransfSphericalOffsetVCL()15cFractalTransfSphericalOffsetVCL::cFractalTransfSphericalOffsetVCL() : cAbstractFractal() 16 { 17 nameInComboBox = "T>Spherical OffsetVCL"; 18 internalName = "transf_spherical_offset_vcl"; 19 internalID = fractal::transfSphericalOffsetVCL; 20 DEType = analyticDEType; 21 DEFunctionType = withoutDEFunction; 22 cpixelAddition = cpixelDisabledByDefault; 23 defaultBailout = 100.0; 24 DEAnalyticFunction = analyticFunctionNone; 25 coloringFunction = coloringFunctionDefault; 26 } 27 FormulaCode(CVector4 & z,const sFractal * fractal,sExtendedAux & aux)28void cFractalTransfSphericalOffsetVCL::FormulaCode( 29 CVector4 &z, const sFractal *fractal, sExtendedAux &aux) 30 { 31 double para = fractal->Cpara.para00; 32 double paraAdd = 0.0; 33 double paraAddP0 = 0.0; 34 // curvilinear mode 35 if (fractal->transformCommon.functionEnabled) 36 { 37 if (fractal->Cpara.enabledLinear) 38 { 39 para = fractal->Cpara.para00; // parameter value at iter 0 40 double temp0 = para; 41 double tempA = fractal->Cpara.paraA0; 42 double tempB = fractal->Cpara.paraB0; 43 double tempC = fractal->Cpara.paraC0; 44 double lengthAB = fractal->Cpara.iterB - fractal->Cpara.iterA; 45 double lengthBC = fractal->Cpara.iterC - fractal->Cpara.iterB; 46 double grade1 = (tempA - temp0) / fractal->Cpara.iterA; 47 double grade2 = (tempB - tempA) / lengthAB; 48 double grade3 = (tempC - tempB) / lengthBC; 49 50 // slopes 51 if (aux.i < fractal->Cpara.iterA) 52 { 53 para = temp0 + (aux.i * grade1); 54 } 55 if (aux.i < fractal->Cpara.iterB && aux.i >= fractal->Cpara.iterA) 56 { 57 para = tempA + (aux.i - fractal->Cpara.iterA) * grade2; 58 } 59 if (aux.i >= fractal->Cpara.iterB) 60 { 61 para = tempB + (aux.i - fractal->Cpara.iterB) * grade3; 62 } 63 64 // Curvi part on "true" 65 if (fractal->Cpara.enabledCurves) 66 { 67 double paraIt; 68 if (lengthAB > 2.0 * fractal->Cpara.iterA) // stop error, todo fix. 69 { 70 double curve1 = (grade2 - grade1) / (4.0 * fractal->Cpara.iterA); 71 double tempL = lengthAB - fractal->Cpara.iterA; 72 double curve2 = (grade3 - grade2) / (4.0 * tempL); 73 if (aux.i < 2 * fractal->Cpara.iterA) 74 { 75 paraIt = tempA - fabs(tempA - aux.i); 76 paraAdd = paraIt * paraIt * curve1; 77 } 78 if (aux.i >= 2 * fractal->Cpara.iterA && aux.i < fractal->Cpara.iterB + tempL) 79 { 80 paraIt = tempB - fabs(tempB * aux.i); 81 paraAdd = paraIt * paraIt * curve2; 82 } 83 } 84 para += paraAdd; 85 } 86 } 87 } 88 // Parabolic 89 if (fractal->Cpara.enabledParabFalse) 90 { // parabolic = paraOffset + iter *slope + (iter *iter *scale) 91 paraAddP0 = fractal->Cpara.parabOffset0 + (aux.i * fractal->Cpara.parabSlope) 92 + (aux.i * aux.i * 0.001 * fractal->Cpara.parabScale); 93 para += paraAddP0; 94 } 95 // para offset 96 para += fractal->transformCommon.offset0; 97 98 double div = 0.0; 99 // dot mode 100 if (fractal->transformCommon.functionEnabledFalse) 101 { 102 div = z.Dot(z); 103 } 104 else 105 { 106 div = z.Length(); 107 } 108 109 // using the parameter 110 z *= 1.0 + para / -div; 111 112 // post scale 113 z *= fractal->transformCommon.scale; 114 aux.DE = aux.DE * fractal->transformCommon.scale + 1.0; 115 116 // DE tweak 117 aux.DE = aux.DE * fractal->analyticDE.scale1 + fractal->analyticDE.offset0; 118 } 119