最近被几(公)张(司)图(任)片(务)给美(吓)哭了,于是决定来研究研究茱莉亚(Julia)集合。Julia集合本质上是对级数的敛散性的描述,仅仅只说数字,想必大家早都看睡着了,因此当敛散性和计算机图像二者结合到一块儿的时候就非常非常美了。话不多说,先上几张图:
想要问问你美不美~,这些图片都是靠openCV实现的,那么接下来就来分析分析如何画出这么美丽的图片。
首先,你得了解基本的数学知识——敛散性。敛散性分为收敛和发散。收敛指的是一个级数最后的求和结果趋于一个常数,发散是指一个级数最后的求和结果趋于无穷大或无穷小。
茱莉亚即便是根据敛散性画出来的,首先我们任取一个复数变量z,让这个复数不断的按照某个公式迭代,最后会产生一个新的复数,这个新的复数的模如果趋于无穷大/无穷小,则我们认为该复数在这种情况下是发散的,反之收敛。是不是还是没搞懂?正常,不用怕。换一种通俗易懂的语言,我们以复平面中的任一点坐迭代,如果最后的值是收敛的,我们把这一块涂成蓝色,如果值是发散的,我们则涂成黑色。说到这里,是不是有点熟悉了?没错,你看到的上面三张图就是这样形成的。所有蓝色部分全是表示收敛点,所有黑色部分全部表示发散点。
那么,茱莉亚集合究竟是个什么样的迭代公式呢?公式就是:
Zn = Zn-1 * Zn-1 + C0
这里Z是变量,C0是一个常量(复数),之所以上面有三种不同的形状就是因为改变了C0的值。说到这里,想必应该很清楚是怎么回事了吧?在画茱莉亚集合的时候,我们肯定要先构建一个复数类,同时可以重写以下相关的操作符(这里如果不知道什么是重写操作符可以看一下我以前的博客)。话不多说,先上代码:
class ComplexNum {
private:
float real;
float imag;
public:
ComplexNum(float a, float b);
ComplexNum& operator+(const ComplexNum& c); //重写加法
ComplexNum& operator*(const ComplexNum& c); //重写乘法
float module(); //求复数的模
};
以上是定义复数类的声明文件(.h文件)。
#include "Complex.h"
#include<math.h>
ComplexNum::ComplexNum(float a, float b) : real(a), imag(b) {
}
ComplexNum& ComplexNum