Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
544 changes: 197 additions & 347 deletions libid/engine/PertEngine.cpp

Large diffs are not rendered by default.

46 changes: 41 additions & 5 deletions libid/engine/calcfrac.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#include "engine/tesseral.h"
#include "engine/wait_until.h"
#include "engine/work_list.h"
#include "engine/perturbation.h"
#include "fractals/fractalp.h"
#include "fractals/frothy_basin.h"
#include "fractals/lyapunov.h"
Expand Down Expand Up @@ -881,6 +882,10 @@ static void perform_work_list()
bool (*sv_per_image)() = nullptr; // once-per-image setup
int alt = find_alternate_math(g_fractal_type, g_bf_math);

if (g_use_perturbation) // setup per-image perturbation
{
mandel_perturbation_setup();
}
if (alt > -1)
{
sv_orbit_calc = g_cur_fractal_specific->orbit_calc;
Expand Down Expand Up @@ -1149,10 +1154,10 @@ static void perform_work_list()
case 'g':
// TODO: fix this
// horrible cludge preventing crash when coming back from perturbation and math = bignum/bigflt
if (g_calc_status != CalcStatus::COMPLETED)
{
// if (g_calc_status != CalcStatus::COMPLETED)
// {
solid_guess();
}
// }
break;

case 'd':
Expand Down Expand Up @@ -1431,6 +1436,24 @@ int standard_fractal() // per pixel 1/2/b/g, called with row & col set
}
g_overflow = false; // reset integer math overflow flag

if (g_use_perturbation)
{
// int temp_color = get_color(g_col, g_row);
perturbation_per_pixel(); // initialize the pert calculations
// if (perturbation_per_pixel() == -2) // initialize the calculations -2 means not glitched
// {
// g_color_iter = temp_color; // we have done this pixel in an earlier pass and it's not glitched//
// g_color = std::abs((int) g_color_iter);
// g_pixel_is_complete = true;
// return g_color;
// }
}
else
{
g_cur_fractal_specific->per_pixel(); // initialize the calculations
}


g_cur_fractal_specific->per_pixel(); // initialize the calculations

attracted = false;
Expand Down Expand Up @@ -1531,9 +1554,22 @@ int standard_fractal() // per pixel 1/2/b/g, called with row & col set
}

// the usual case
else if ((g_cur_fractal_specific->orbit_calc() && g_inside_color != STAR_TRAIL) || g_overflow)
else
{
break;
if (g_use_perturbation)
{
if ((perturbation_per_orbit() && g_inside_color != STAR_TRAIL) || g_overflow)
{
break;
}
}
else
{
if ((g_cur_fractal_specific->orbit_calc() && g_inside_color != STAR_TRAIL) || g_overflow)
{
break;
}
}
}
if (g_show_orbit)
{
Expand Down
29 changes: 2 additions & 27 deletions libid/engine/fractalb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "engine/calcfrac.h"
#include "engine/fractals.h"
#include "engine/id_data.h"
#include "engine/perturbation.h"
#include "engine/type_has_param.h"
#include "fractals/divide_brot.h"
#include "fractals/fractalp.h"
Expand Down Expand Up @@ -356,15 +357,6 @@ bool mandel_bn_setup()
}
}

if (g_std_calc_mode == 'p' && bit_set(g_cur_fractal_specific->flags, FractalFlags::PERTURB))
{
mandel_perturbation_setup();
// TODO: figure out crash if we don't do this
g_std_calc_mode ='g';
g_calc_status = CalcStatus::COMPLETED;
return true;
}

g_c_exponent = (int) g_params[2];
switch (g_fractal_type)
{
Expand Down Expand Up @@ -475,10 +467,6 @@ bool mandel_bf_setup()
{
case FractalType::MANDEL:
case FractalType::BURNING_SHIP:
if (g_std_calc_mode == 'p' && bit_set(g_cur_fractal_specific->flags, FractalFlags::PERTURB))
{
return mandel_perturbation_setup();
}
break;

case FractalType::JULIA:
Expand All @@ -487,19 +475,6 @@ bool mandel_bf_setup()
break;

case FractalType::MANDEL_Z_POWER:
if (g_std_calc_mode == 'p' && bit_set(g_cur_fractal_specific->flags, FractalFlags::PERTURB))
{
// only allow integer values of real part
if (const int degree = (int) g_params[2]; degree > 2)
{
return mandel_z_power_perturbation_setup();
}
else if (degree == 2)
{
return mandel_perturbation_setup();
}
}

init_big_pi();
if ((double) g_c_exponent == g_params[2] && (g_c_exponent & 1)) // odd exponents
{
Expand Down Expand Up @@ -536,7 +511,7 @@ bool mandel_bf_setup()

int mandel_bn_per_pixel()
{
if (g_std_calc_mode == 'p' && bit_set(g_cur_fractal_specific->flags, FractalFlags::PERTURB))
if (g_use_perturbation && bit_set(g_cur_fractal_specific->flags, FractalFlags::PERTURB))
{
return true;
}
Expand Down
47 changes: 47 additions & 0 deletions libid/engine/perturbation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "engine/PertEngine.h"
#include "engine/convert_center_mag.h"
#include "engine/id_data.h"
#include "fractals/fractalp.h"
#include "math/biginit.h"

#include <config/port.h>
Expand All @@ -16,6 +17,11 @@

static PertEngine s_pert_engine;

PerturbationMode g_perturbation{PerturbationMode::AUTO};
double g_perturbation_tolerance{1e-6};
bool g_use_perturbation{}; // select perturbation code
int g_number_referrences{}; // number of references used

bool perturbation()
{
BigStackSaver saved;
Expand Down Expand Up @@ -59,3 +65,44 @@ bool perturbation()
g_calc_status = CalcStatus::COMPLETED;
return false;
}

int perturbation_per_pixel()
{
int result = s_pert_engine.perturbation_per_pixel(g_col, g_row, g_magnitude_limit);
return result;
}

int perturbation_per_orbit()
{
int status = s_pert_engine.calculate_orbit(g_col, g_row, g_color_iter);
return status;
}

int get_number_references()
{
return s_pert_engine.get_number_references();
}

bool is_perturbation()
{
if (bit_set(g_cur_fractal_specific->flags, FractalFlags::PERTURB))
{
if (g_perturbation == PerturbationMode::AUTO && g_bf_math != BFMathType::NONE)
{
g_use_perturbation = true;
}
else if (g_perturbation == PerturbationMode::YES)
{
g_use_perturbation = true;
}
else
{
g_use_perturbation = false;
}
}
else
{
g_use_perturbation = false;
}
return g_use_perturbation;
}
29 changes: 3 additions & 26 deletions libid/fractals/frasetup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,6 @@
// Mandelbrot Routine
bool mandel_setup()
{
if (g_std_calc_mode == 'p' && bit_set(g_cur_fractal_specific->flags, FractalFlags::PERTURB))
{
return mandel_perturbation_setup();
}
// use the main processing loop
g_calc_type = standard_fractal;
return true;
Expand All @@ -48,13 +44,7 @@ standalone_setup()

bool mandel_perturbation_setup()
{
return perturbation();
}

bool mandel_z_power_perturbation_setup()
{
constexpr int MAX_POWER{28};
g_c_exponent = std::min(std::max(g_c_exponent, 2), MAX_POWER);
g_calc_type = standard_fractal;
return perturbation();
}

Expand Down Expand Up @@ -91,10 +81,7 @@ mandel_fp_setup()
calcmandfp() can currently handle invert, any rqlim, potflag
zmag, epsilon cross, and all the current outside options
*/
if (g_std_calc_mode == 'p' && bit_set(g_cur_fractal_specific->flags, FractalFlags::PERTURB))
{
return mandel_perturbation_setup();
}

if (g_debug_flag != DebugFlags::FORCE_STANDARD_FRACTAL
&& !g_distance_estimator
&& g_decomp[0] == 0
Expand All @@ -104,6 +91,7 @@ mandel_fp_setup()
&& g_use_init_orbit != InitOrbitMode::VALUE
&& (g_sound_flag & SOUNDFLAG_ORBIT_MASK) < SOUNDFLAG_X
&& !g_using_jiim
&& !g_use_perturbation
&& g_bailout_test == Bailout::MOD
&& (g_orbit_save_flags & OSF_MIDI) == 0)
{
Expand All @@ -118,17 +106,6 @@ mandel_fp_setup()
break;

case FractalType::MANDEL_Z_POWER:
if (g_std_calc_mode == 'p' && bit_set(g_cur_fractal_specific->flags, FractalFlags::PERTURB))
{
if (g_c_exponent == 2)
{
return mandel_perturbation_setup();
}
if (g_c_exponent > 2)
{
return mandel_z_power_perturbation_setup();
}
}
if ((double)g_c_exponent == g_params[2] && (g_c_exponent & 1)) // odd exponents
{
g_symmetry = SymmetryType::XY_AXIS_NO_PARAM;
Expand Down
15 changes: 9 additions & 6 deletions libid/include/engine/PertEngine.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,12 @@ class PertEngine
public:
void initialize_frame(const BFComplex &center_bf, const std::complex<double> &center, double zoom_radius);
int calculate_one_frame();
int perturbation_per_pixel(int x, int y, double bailout);
int calculate_orbit(int x, int y, long iteration);
int get_number_references();

private:
int calculate_point(const Point &pt, double magnified_radius, int window_radius);
int calculate_reference(int x, int y);
void reference_zoom_point(const BFComplex &center, int max_iteration);
void reference_zoom_point(const std::complex<double> &center, int max_iteration);
void cleanup();
Expand All @@ -26,15 +29,15 @@ class PertEngine
std::vector<double> m_perturbation_tolerance_check;
double m_delta_real{};
double m_delta_imag{};
std::vector<Point> m_points_remaining;
std::vector<Point> m_glitch_points;
long m_glitch_point_count{};
long m_remaining_point_count{};
BFComplex m_center_bf{};
std::complex<double> m_center{};
double m_zoom_radius{};
bool m_calculate_glitches{true};
double m_percent_glitch_tolerance{0.1}; // What percentage of the image is okay to be glitched.
int m_reference_points{};
int m_saved_stack{};
std::complex<double> m_c{};
BFComplex m_c_bf{};

std::complex<double> m_delta_sub_0{};
std::complex<double> m_delta_sub_n{};
};
25 changes: 25 additions & 0 deletions libid/include/engine/perturbation.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,28 @@
#pragma once

bool perturbation();
extern bool mandel_perturbation_setup();
extern bool is_perturbation();
extern int perturbation_per_pixel();
extern int perturbation_per_orbit();
//extern bool is_pixel_finished(int x, int y);
//extern long get_glitch_point_count();
//extern int calculate_reference();
//extern void cleanup_perturbation();
extern int get_number_references();

extern bool g_use_perturbation; // select perturbation code

extern int g_row;
extern int g_col;
extern long g_color_iter;
extern double g_magnitude_limit;

enum class PerturbationMode
{
AUTO = 0, // the default
YES = 1,
NO = 2
};
extern PerturbationMode g_perturbation;
extern double g_perturbation_tolerance;
Loading
Loading