Я работаю над визуализацией множества Мандельброта, а также нескольких других фракталов, и в них много дублированного кода, но повторное использование кода отсутствует.
Одна из функций, которые я использую ниже:
/**
* determines whether a pixel lies in the set
* @params x, y - x and y coordinates on R/I axes
* @param c - a complex number
*/
void calculateSet(int x, int y, Complex c) {
Complex z = c.clone();
int n = 0;
for (; n < maxDepth; n++) {
if (z.dis() > 4) { break; }
z = z^2 + c;
}
// some code using n to color the set
}
Это следует за множеством Мандельброта:
z_(n+1) = z_n^2 + c
Но посмотрите соответствующий код для набора Burning Ship:
void calculateSet(int x, int y, Complex c) {
Complex z = c.clone();
int n = 0;
for (; n < maxDepth; n++) {
if (z.dis() > 4) { break; }
z = abs(z)^2 + c; // ***
}
// follows z_(n+1) = abs(z_1)^2 + c
}
Весь код, за исключением помеченной звездочкой, идентичен. Сейчас у меня есть отдельные классы для Mandelbrot
, BurningShip
и несколько других, с той лишь разницей, что одна строка.
Есть ли способ определить это выражение и перейти к обобщенному Set
классу?
Какой-то псевдокод:
class Set {
// ...
Set(Type expression) {
// ...
// x, y, c initialized
// ...
calculateSet(x, y, c, expression);
}
void calculateSet(int x, int y, Complex c, Type e) {
Complex z = c.clone();
int n = 0;
for (; n < maxDepth; n++) {
if (z.dis() > 4) { break; }
z = e;
}
}
};
И я могу просто использовать Set
, чтобы описать любой набор, который я хочу?
Set mandelbrot = Set(Type("z^2 + c"));
Set burningship = Set(Type("abs(z)^2 + c"));
// etc
Я мог бы использовать if/else
операторы, чтобы иметь только один класс, но он не обобщен.