可以将算术表达式作为参数传递给一个函数来描述其中的逻辑

Can an arithmetic expression be passed as argument to a function to describe the logic therein?

本文关键字:函数 一个 描述 表达式 参数传递      更新时间:2023-10-16

我正在努力可视化mandelbrot集以及其他一些分形,并且有很多重复的代码,但没有代码重复使用。

我使用的功能之一如下:

/**
 * 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
}

这遵循mandelbrot集:

z_(n+1) = z_n^2 + c

,但请查看燃烧船集的相关代码:

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
}

所有的代码保存为星条行是相同的。现在,我有针对MandelbrotBurningShip的单独类别,而其他一些类别是一行。

有没有办法定义此表达式并传递给广义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语句只有一个类,但没有概括。

由于您仅限于C 03,因此您可以相对痛苦地使用功能指针。

Complex mandlebrotCompute(Complex z, Complex c) {
  return z*z + c;
}
void calculateSet(int x, int y, Complex c, Complex (*func)(Complex, Complex)) {
    Complex z = c.clone();
    int n = 0;
    for (; n < maxDepth; n++) {
        if (z.dis() > 4) { break; }
        z = func(z, c);
    }
}

使用如下:

Complex foo;
calculateSet(1, 2, foo, mandlebrotCompute);

它可能有助于使代码清洁器在功能指针中使用Typedef。

您可以制作一个模板,并以函数作为模板参数。
我相信这是提供最内在机遇的方法。

typedef Complex (*Function)(const Complex&, const Complex&);
template<Function fn>
class Set
{
    // ...
    void calculateSet(int x, int y, Complex c) {
        Complex z = c;
        int n = 0;
        for (; n < maxDepth; n++) {
            if (z.dis() > 4) { break; }
                z = fn(z, c)
            }
        // some code...
    }
}
Complex mandelbrot_fn(const Complex& z, const Complex& c)
{
    return z^2 + c;
}
Complex burning_fn(const Complex& z, const Complex& c)
{
    return abs(z)^2 + c;
}

Set<mandelbrot_fn> mandelbrot;
Set<burning_fn> burning_ship;

这就是我猜是lambdas。

template<typename Lam>
class Set
{
private:
  Lam lam;
public:
  Set (Lam&& lam) : lam(lam) {}
  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 = lam(z, c);
    }
  }
};

您可以这样使用此类:

auto mandelbrot = Set([](Complex z, Complex c) -> Complex {
  return (z*z) + c;
});

auto burningShip = Set([](Complex z, Complex c) -> Complex {
  return abs((z*z)) + c;
});
mandelbrot.calculateSet(...);
burningShip .calculateSet(...);
相关文章: