zoukankan      html  css  js  c++  java
  • Why数学图像生成工具

          该软件能够以给定的数学公式及算法生成各种绚烂的数学图像.软件中有两种生成图像的方法:

         (1)通过一种我自定义的脚本语言生成:

          软件中定义一套简单易学的脚本语言,用于描述数学表达式.使用时需要先要将数学表达式写成该脚本的形式,解析脚本代码以生成相应的图像.

         (2)使用软件中内置的算法:

          软件中含有近百种数学图像生成的算法,如Mandelbrot,JuliaSets之类的分形算法。

          软件的开发语言是C++,开发环境是VS2008,渲染使用的是D3D9。关于数学图形图像的QQ交流群: 367752815

    软件下载地址:

    1.0版本 http://files.cnblogs.com/WhyEngine/WhyMathImageViewer_1_0.zip

    1.1版本 http://files.cnblogs.com/WhyEngine/WhyMathImage_1_1.zip

    [一]基本功能

          首先介绍下该软件的基本功能,这是一款与图像有关的软件,所以图像加载显示功能是必需的,软件支持的图像格式有:png,jpg,dds,bmp,tga,ppm。用户可以将文件直接拖入窗体内以打开图像,也可以通过菜单项或快捷方式Ctrl+F选择文件加载。下图为软件界面:

    在窗体的两边有UI界面,用户可以按快捷键U来开关UI界面。

    (1.1)图像颜色通道

          先看下左则的UI,打开图像后,可以通过UI选择RGBA的各个通道以显示图像,或通过快捷键R,G,B,A,I来选择通道模式:

    R通道图像:

    G通道图像:

    B通道图像:

    反色图像:

    (1.2)图像滤波方式

    有两种图像滤波方式:(1)线性采样(2)点采样。通过下图可以看出二者的区别:

    (1.3)图像大小设置:

          鼠标滚轮用于控制图像的缩放。图像缩放时,是以鼠标所指的位置当做中心进行缩放的。

          鼠标右键拖动可以控制图像的位置。

          如下图为缩小并拖动后的图像:

    还有两个按钮,其快捷键为F,O。分别表示使图像最合适的大小显示,和使图像以原始大小显示。

    最后键盘F11用于控制界面的全屏切换。

    [二]通过脚本生成图像

         之前我写过一套数学图形可视化的工具,可以将数学表达式以图形的形式显示出来.这两套软件使用的脚本解析方式是一样的,即两个软件使用相同的脚本解析模块.关于详细语法介绍请看:数学图形可视化工具的脚本语法.我已经将该脚本解析模块的代码开源.这里脚本的后缀名为txt,主要是方便用记事本打开.目前我写了几十个脚本,放置在"Why数学图像生成工具_1_0Scripts"目录下.脚本文件的加载方式与图像加载一样,即可以通过菜单项选择文件打开,又可以直接将文件拖入程序窗体内自动加载.

    (2.1)函数名

    下面是我的脚本语言中的所有函数名:

    (1)单目运算函数,形如a = log(b)

    "positive", // 取正,基本上没什么用,相当于(+a)
    "negative", // 取负
    "abs", // 求绝对值
    "floor", // 整数位
    "ceil", // 整数位+1
    "sign", // 返回-1.0或1.0
    "sgn", // 返回-1.0或0.0或1.0
    "is_zero", // 返回0.0或1.0
    "rand", // 返回一个随机的浮点数
    "rand_int", // 返回一个随机整数
    "round", // 四舍五入
    "reciprocal", // 倒数

    "sqrt", // 开根号
    "exp", //
    "log", // 求对数
    "ln", // log == ln
    "log10",
    "lg", // log10 = lg
    "log2",

    "sin", // 正弦函数
    "cos", // 余弦函数
    "asin", // 反正弦函数
    "acos", // 反余弦函数
    "arcsin", // 反正弦函数
    "arccos", // 反余弦函数

    "tan", // 正切函数
    "cot", // 余切函数
    "ctg", // 余切函数
    "atan", // 反正切函数
    "acot", // 反余切函数
    "actg", // 反余切函数
    "arctan", // 反正切函数
    "arccot", // 反余切函数
    "arcctg", // 反余切函数

    "sec", // 正割函数
    "csc", // 余割函数
    "asec", // 反正割函数
    "acsc", // 反余割函数
    "arcsec", // 反正割函数
    "arccsc", // 反余割函数

    "sinh", // 双曲正弦函数
    "cosh", // 双曲余弦函数
    "tanh", // 双曲正切函数
    "coth", // 双曲余切函数

    "sh", // 双曲正弦函数
    "ch", // 双曲余弦函数
    "th", // 双曲正切函数
    "cth", // 双曲余切函数

    "sech", // 双曲正割(等同于sch)
    "sch", // 双曲正割
    "csch", // 双曲余割(等同于xh)
    "xh", // 双曲余割

    "factorial", // 阶乘
    "erf", // 误差函数
    "float_to_color", // 将浮点数转化为0-255的颜色数

    (2)双目运算函数,形如a = add(b, c)

    "add", 相加
    "sub", 相减
    "multiply", 相乘
    "divide", 相除

    "max", // 返回两数较大的一个
    "min", // 返回两数较小的一个
    "mod", // 求余
    "pow", // 求幂
    "log_ax", // 对数
    "pow_sign", // 用于对负数的求幂,相当于pow(abs(a), b)

    "correction_gamma",// gamma校正函数
    "correction_pow", // pow校正函数
    "correction_sin", // sin校正函数

    "atan2", // 正切
    "rand2", // 返回两数之间的一个随机浮点数
    "rand_int2", // 返回两数之间的一个随机整数

    "and_bool" // 与,返回0或1.0
    "or_bool", // 或,返回0或1.0
    "xor_bool" // 异或,返回0或1.0
    "and_byte" // 与,返回0到255.0的一个数
    "or_byte", // 或,返回0到255.0的一个数
    "xor_byte" // 异或,返回0到255.0的一个数
    "and_word" // 与,返回0到65535.0的一个数
    "or_word", // 或,返回0到65535.0的一个数
    "xor_word" // 异或,返回0到65535.0的一个数

    "greater", // 返回0或1.0
    "greater_equal", // 返回0或1.0
    "less", // 返回0或1.0
    "less_equal", // 返回0或1.0
    "equal", // 返回0或1.0

    (3)三目运算符函数 形如lerp(a, b, r)

    "lerp", // 线性插值
    "clamp", // 限定数值的范围
    "limit", // 限定数值的范围,与clamp一样
    "in_range", // 数值是否范围内,返回0或1.0
    "gray", // 颜色的灰度化
    "add3", // 相加
    "min3", // 三个之中取最小
    "max3", // 三个之中取最大
    "average3", // 三数平均值
    "if", // 如果第一个数不为0则取第二个数,否则取第三个数
    "if_else", // 与if等价

    (4)函数四目运算符 形如average4(a, b, c, d)

    "add4", // 相加
    "min4", // 四个之中取最小
    "max4", // 四个之中取最大
    "average4", // 四数平均值

    (5)函数数组运算符(输入实数数组,输出一个浮点数,如求最大值,最小值,数组加和等)

    "array_add", // 相加
    "array_min", // 数组之中取最小
    "array_max", // 数组之中取最大
    "array_ave", // 数组平均值

    (6)函数数组运算符(输入实数数组,输出也是实数数组,如求数组左移,数组右移,前向累加等)

    "array_move_right",// 数组右移
    "array_move_left", // 数组左移
    "array_cumulate", // 数组累加
    "array_difference",// 数组差,b[n] = a[n + params] - a[n]

    (7)函数数组运算符(输入两个浮点数,输出实数数组)
    "array_lerp", // 将数组中的数值变为等差数列
    "array_rand", // 将数组中的数值变为随机浮点数
    "array_rand_int", // 将数组中的数值变为随机整数
    "array_set_all_values",// 将数组设置为统一值

    (8)函数数组运算符(输入实数数组和一个浮点数,输出一个浮点数)
    "array_get_value" // 获取数组的某一个值

    (2.2)脚本编辑

    按下键盘F5或通过菜单选项可以打开脚本编辑对话框:

    这个对话框与数学图形可视化的工具的基本上完全一样.

          有一点需要注意的是:脚本中的数据都是以浮点数进行处理的.最后脚本中的r,g,b,a分别表示图像中的红色,绿色,蓝色,透明度这四个通道.并且其数值应该是0到1.0之间.而不像常规图像处理中用整数表示的0到255之间.当脚本中的数值为1.0时,相当于常规图像中的255.

    (2.3)图像实例

    先给大家举个脚本生成图像的简单例子:

    # 确定图像大小为512*512
    pixels = W:512 H:512
    
    # 创建数组u为X轴方向
    u = from 0 to (2*PI) W
    
    # 创建数组v为Y轴方向
    v = from (-PI*0.5) to (PI*0.5) H
    
    x = cos(v)*sin(u)
    y = sin(v)
    z = cos(v)*cos(u)
    
    # rgb分别表示图像中对应像素的红色,绿色,蓝色通道
    r = (x+1.0)/2
    g = (y+1.0)/2
    b = (z+1.0)/2

    其生成的图像如下:

     其实这个脚本代码与数学图形可视化的工具是可以通用的,看下它的3D图形:

    再举个复杂点的图像例子:

    pixels = W:1024 H:1024
    
    x = from 0 to 1023 W
    y = from 0 to 1023 H
    
    r = and_byte((x+y), y)
    g = and_byte((255 + x - y), x)
    b = and_byte((255 - x - y), y)
    b = and_byte(b, x)
    
    r = r/255
    g = g/255
    b = b/255

    然后是一幅让人眼花的图像,但生成它的数学公式很简单.

    pixels = W:1024 H:1024
    
    x = from 0 to (16*PI) W
    y = from 0 to (16*PI) H
    
    r = sin(x+y)
    g = sin(x-y)
    b = sin(x*y)
    
    r = r*0.5 + 0.5
    g = g*0.5 + 0.5
    b = b*0.5 + 0.5

    下面是两幅使用sin和tan函数而生成的图像

    [三]数学图像生成算法

          不得不承认我的脚本功能还不够强大,只能实现些比较基础的图像,像循环迭代这样的算法目前还没办法实现.为了弥补这一不足,我将一些数学图像生成算法内置到该软件中.

    (3.1)Tweetable Mathematical Art

          网上有很多通过算法生成数学图像,尤其是与分形学相关的方面.我收集了近百种数学图像生成的算法,都写入该软件中.其中大部份算法来自:http://codegolf.stackexchange.com/questions/35569/tweetable-mathematical-art.它是Kyle McCormick 在 StackExchange 上发起了一个叫做 Tweetable Mathematical Art 的比赛,参赛者需要用三条代码来生成一张图片。具体地说,参赛者需要用 C++ 语言编写 RD 、 GR 、 BL 三个函数,每个函数都不能超过 140 个字符。每个函数都会接到 i 和 j 两个整型参数(0 ≤ i, j ≤ 1023),然后需要返回一个 0 到 255 之间的整数,表示位于 (i, j) 的像素点的颜色值。参赛者编写的代码会被插进下面这段程序当中,最终会生成一个大小为 1024×1024 的图片。

    // NOTE: compile with g++ filename.cpp -std=c++11
     
    #include <iostream>
    #include <cmath>
    #include <cstdlib>
    #define DIM 1024
    #define DM1 (DIM-1)
    #define _sq(x) ((x)*(x)) // square
    #define _cb(x) abs((x)*(x)*(x)) // absolute value of cube
    #define _cr(x) (unsigned char)(pow((x),1.0/3.0)) // cube root
     
    unsigned char GR(int,int);
    unsigned char BL(int,int);
     
    unsigned char RD(int i,int j){
       // YOUR CODE HERE
    }
    unsigned char GR(int i,int j){
       // YOUR CODE HERE
    }
    unsigned char BL(int i,int j){
       // YOUR CODE HERE
    }
     
    void pixel_write(int,int);
    FILE *fp;
    int main(){
        fp = fopen("MathPic.ppm","wb");
        fprintf(fp, "P6
    %d %d
    255
    ", DIM, DIM);
        for(int j=0;j<DIM;j++)
            for(int i=0;i<DIM;i++)
                pixel_write(i,j);
        fclose(fp);
        return 0;
    }
    void pixel_write(int i, int j){
        static unsigned char color[3];
        color[0] = RD(i,j)&255;
        color[1] = GR(i,j)&255;
        color[2] = BL(i,j)&255;
        fwrite(color, 1, 3, fp);
    }

          这代码写得很棒,给我一种重剑无锋,大道至简的感觉.参赛者只要将自己的代码写入这三个函数即可生成一幅图像文件:

    unsigned char RD(int i,int j){
       // YOUR CODE HERE
    }
    unsigned char GR(int i,int j){
       // YOUR CODE HERE
    }
    unsigned char BL(int i,int j){
       // YOUR CODE HERE
    }

          由于它要求每个函数都不能超过140个字符,所以很多参赛者在其代码中大量使用宏来过份地简化,因而其可读性差了点.而我花了几天时间基本上将其所有代码翻写了一遍.

    (3.2)图像内置算法基类

    我的代码中为每一种图像生成算法创建一个类对象,所有算法类继承自同一个基类:

    #ifndef _IPixelEquation_H_
    #define _IPixelEquation_H_
    
    // --------------------------------------------------------------------------------------
    
    #include <cmath>
    #include <cstdlib>
    #include <cstring>
    #include <cfloat>
    
    // --------------------------------------------------------------------------------------
    
    #define PI                      3.14159265f
    #define EPSILON                 0.000001f
    #define PARAMS_COUNT            4
    #define RADIAN_VS_DEGREE        57.2957795130824f               // 180 / PI
    #define DEGREE_VS_RADIAN        0.01745329251994f               // PI / 180
    
    // 通过R,G,B生成一整数表示颜色
    #define MAKE_RGB(r,g,b)         ( (b) | ((g) << 8) | ((r) << 16) | 0xff000000 )
    
    // 通过R,G,B,A生成一整数表示颜色
    #define MAKE_ARGB(a,r,g,b)      ( (b) | ((g) << 8) | ((r) << 16) | ((a) << 24) )
    
    #define FLOAT_1_TO_BYTE(x)      ( (x) < 0.0f ? 0 : (((x) > 1.0f) ? 255 : (unsigned int)((x) * 255)) )
    #define FLOAT_255_TO_BYTE(x)    ( (x) < 0.0f ? 0 : (((x) > 255.0f) ? 255 : (unsigned int)(x)) )
    #define BYTE_TO_FLOAT_1(x)      ( (x) * 0.00392156862745f )           // x / 255
    
    #define _sq(x)                  ((x)*(x))           // square
    #define _cb(x)                  fabsf((x)*(x)*(x))  // absolute value of cube
    #define _cr(x)                  powf((x),1.0f/3.0f) // cube root
    
    // --------------------------------------------------------------------------------------
    
    class IPixelEquation
    {
    public:
        IPixelEquation()
        {
            m_width = 1024;
            m_height = 1024;
    
            memset(m_params, 0, sizeof(m_params));
        }
    
        unsigned int            GetWidth() const
        {
            return m_width;
        }
    
        unsigned int            GetHeight() const
        {
            return m_height;
        }
    
        // 设置参数值
        virtual void            SetParamValue(unsigned int index, float v)
        {
            if (index < PARAMS_COUNT)
            {
                m_params[index] = v;
            }
        }
    
        // 获取参数值
        float                   GetParamValue(unsigned int index) const
        {
            if (index < PARAMS_COUNT)
            {
                return m_params[index];
            }
            else
            {
                return 0.0f;
            }
        }
    
        // 返回参数表示的意义
        virtual const char*     GetParamName(unsigned int index) const
        {
            return 0;
        }
    
        // 参数的取值范围属性
        virtual void            GetParamProperties(unsigned int index, float& _min, float& _max, float& _step)
        {
            _min = -1.0f;
            _max = 1.0f;
            _step = 0.001f;
        }
    
        // 恢复默认参数
        virtual void            ResetDefaultParams() {}
    
        // 返回数学图像名
        virtual const char*     GetName() const = 0;
    
        // 计算图像像素颜色
        virtual unsigned int    CalculatePixel(unsigned int x, unsigned int y) = 0;
    
    protected:
        unsigned int m_width;
        unsigned int m_height;
    
        float m_params[PARAMS_COUNT];   // 参数设置
    };

         每一个算法类中需要实现各自的unsigned int CalculatePixel(unsigned int x, unsigned int y)函数,以计算图像像素颜色.下面代码中每一行就表示一个数学图像算法类,我目前共写了81个:

     1 #include "PixelEquationPixelZero.h"
     2 #include "PixelEquationPixelRGB.h"
     3 #include "PixelEquationPixelNewtonFractal.h"
     4 #include "PixelEquationPixelColorPoint.h"
     5 #include "PixelEquationPixelOilPainting.h"
     6 #include "PixelEquationPixelMandelbrotMartin.h"
     7 #include "PixelEquationPixelMandelbrotKasten.h"
     8 #include "PixelEquationPixelMandelbrotLehman.h"
     9 #include "PixelEquationPixelLaserLight.h"
    10 #include "PixelEquationPixelLatticeCloth.h"
    11 #include "PixelEquationPixelIceFrost.h"
    12 #include "PixelEquationPixelFeigenbaumLogistic.h"
    13 #include "PixelEquationPixelCrossTarget.h"
    14 #include "PixelEquationPixelAndAddOr.h"
    15 #include "PixelEquationPixelReflectedWaves.h"
    16 #include "PixelEquationPixelColorful.h"
    17 #include "PixelEquationPixelDiabolical.h"
    18 #include "PixelEquationPixelConstructionPapers.h"
    19 #include "PixelEquationPixelCrossOnHill.h"
    20 #include "PixelEquationPixelActionPainting.h"
    21 #include "PixelEquationPixelStarryNight.h"
    22 #include "PixelEquationPixelHilbertColor.h"
    23 #include "PixelEquationPixelSharpEdges.h"
    24 #include "PixelEquationPixelRaycasterSphere.h"
    25 #include "PixelEquationPixelPalette.h"
    26 #include "PixelEquationPixelBeHappy.h"
    27 #include "PixelEquationPixelCellularAutomata.h"
    28 #include "PixelEquationPixelSchwefel.h"
    29 #include "PixelEquationPixelSierpinskiCarpets1.h"
    30 #include "PixelEquationPixelSierpinskiCarpets2.h"
    31 #include "PixelEquationPixelSierpinskiCarpets3.h"
    32 #include "PixelEquationPixelSierpinskiTriangle.h"
    33 #include "PixelEquationPixelWavyChessboard.h"
    34 #include "PixelEquationPixelBelousovZhabotinsky.h"
    35 #include "PixelEquationPixelStripes.h"
    36 #include "PixelEquationPixelSineStripes.h"
    37 #include "PixelEquationPixelNonlinearStripes.h"
    38 #include "PixelEquationPixelWaveStripes.h"
    39 #include "PixelEquationPixelBlurStripes.h"
    40 #include "PixelEquationPixelZebraStripes.h"
    41 #include "PixelEquationPixelMistakeStripes.h"
    42 #include "PixelEquationPixelStackOverflow.h"
    43 #include "PixelEquationPixelPlaidTrip.h"
    44 #include "PixelEquationPixelCameron1.h"
    45 #include "PixelEquationPixelCameron2.h"
    46 #include "PixelEquationPixelTablecloths.h"
    47 #include "PixelEquationPixelSwirlyPointy1.h"
    48 #include "PixelEquationPixelSwirlyPointy2.h"
    49 #include "PixelEquationPixelJuliaSets1.h"
    50 #include "PixelEquationPixelJuliaSets2.h"
    51 #include "PixelEquationPixelFaubiguy.h"
    52 #include "PixelEquationPixelSierpinskiPentagon.h"
    53 #include "PixelEquationPixelBuddhabrot.h"
    54 #include "PixelEquationPixelSheetMusic.h"
    55 #include "PixelEquationPixelVoronoiDiagrams.h"
    56 #include "PixelEquationPixelLyapunovFractal1.h"
    57 #include "PixelEquationPixelLyapunovFractal2.h"
    58 #include "PixelEquationPixelUnicorns.h"
    59 #include "PixelEquationPixelColouredVinyl.h"
    60 #include "PixelEquationPixelVinyl.h"
    61 #include "PixelEquationPixelSpiral.h"
    62 #include "PixelEquationPixelJoukowsky.h"
    63 #include "PixelEquationPixelXOR.h"
    64 #include "PixelEquationPixelSierpinskiSplash.h"
    65 #include "PixelEquationPixelGroovy.h"
    66 #include "PixelEquationPixelCool.h"
    67 #include "PixelEquationPixelGameScreen.h"
    68 #include "PixelEquationPixelUmberFerrule.h"
    69 #include "PixelEquationPixelPlanetaryPainter.h"
    70 #include "PixelEquationPixelPowAnd.h"
    71 #include "PixelEquationPixelHilbertRed.h"
    72 #include "PixelEquationPixelRaycasterSprite.h"
    73 #include "PixelEquationPixelPowFTW.h"
    74 #include "PixelEquationPixelBinaryFlash.h"
    75 #include "PixelEquationPixelTriangularLimbo.h"
    76 #include "PixelEquationPixelAmericanFlag.h"
    77 #include "PixelEquationPixelPurple.h"
    78 #include "PixelEquationPixelChristmasStars.h"
    79 #include "PixelEquationPixelSpotlight.h"
    80 #include "PixelEquationPixelMagnifierBall.h"
    81 #include "PixelEquationPixelWhat.h"

    (3.3)图像内置算法举例

          在窗体右侧的UI界面中,有一个选择列表,可以选择内置的算法以生成图像.

          如果你在自定义类的CalculatePixel函数中什么也不做,将会生成一个全黑色的图像.

    class CPixelZero : public IPixelEquation
    {
    public:
        const char*     GetName() const
        {
            return "Black";
        }
    
        unsigned int    CalculatePixel(unsigned int x, unsigned int y)
        {
            return 0;
        }
    };

          如下为生成一个彩色三角形集的图像算法:

    class CPixelColorful : public IPixelEquation
    {
    public:
        const char*     GetName() const
        {
            return "Colorful Triangle";
        }
    
        unsigned int    CalculatePixel(unsigned int i, unsigned int j)
        {
            unsigned int r = (i+j)/4%256;
            unsigned int g = (i+2*j)/4%256;
            unsigned int b = (2*i+j)/4%256;
            return MAKE_RGB(r,g,b);
        }
    };

          下面是一个比较艺术的图像:

     1 /*
     2 unsigned char RD(int i,int j){
     3 #define r(n)(rand()%n)
     4 static char c[1024][1024];return!c[i][j]?c[i][j]=!r(999)?r(256):RD((i+r(2))%1024,(j+r(2))%1024):c[i][j];
     5 }
     6 
     7 unsigned char GR(int i,int j){
     8 static char c[1024][1024];return!c[i][j]?c[i][j]=!r(999)?r(256):GR((i+r(2))%1024,(j+r(2))%1024):c[i][j];
     9 }
    10 
    11 unsigned char BL(int i,int j){
    12 static char c[1024][1024];return!c[i][j]?c[i][j]=!r(999)?r(256):BL((i+r(2))%1024,(j+r(2))%1024):c[i][j];
    13 }
    14 }
    15 */
    16 
    17 // --------------------------------------------------------------------------------------
    18 
    19 #define r(n)(rand()%n)
    20 
    21 unsigned int    CPixelOilPainting::CalculateRed(unsigned int i, unsigned int j)
    22 {
    23     static char c[1024][1024];
    24     return !c[i][j]?c[i][j]=!r(999)?r(256):CalculateRed((i+r(2))%1024,(j+r(2))%1024):c[i][j];
    25 }
    26 
    27 unsigned int    CPixelOilPainting::CalculateGreen(unsigned int i, unsigned int j)
    28 {
    29     static char c[1024][1024];
    30     return !c[i][j]?c[i][j]=!r(999)?r(256):CalculateGreen((i+r(2))%1024,(j+r(2))%1024):c[i][j];
    31 }
    32 
    33 unsigned int    CPixelOilPainting::CalculateBlue(unsigned int i, unsigned int j)
    34 {
    35     static char c[1024][1024];
    36     return !c[i][j]?c[i][j]=!r(999)?r(256):CalculateBlue((i+r(2))%1024,(j+r(2))%1024):c[i][j];
    37 }
    38 
    39 unsigned int    CPixelOilPainting::CalculatePixel(unsigned int x, unsigned int y)
    40 {
    41     unsigned int r = CalculateRed(x, y);
    42     unsigned int g = CalculateGreen(x, y);
    43     unsigned int b = CalculateBlue(x, y);
    44     r &= 0xff;
    45     g &= 0xff;
    46     b &= 0xff;
    47     return MAKE_RGB(r,g,b);
    48 }
    View Code

          再发一个复杂点的JuliaSets分形图:

     1 // --------------------------------------------------------------------------------------
     2 
     3 #include "PixelJuliaSets1.h"
     4 
     5 // --------------------------------------------------------------------------------------
     6 
     7 /*
     8 unsigned short red_fn(int i, int j){
     9 #define D(x) (x-DIM/2.)/(DIM/2.)
    10 float x=D(i),y=D(j),X,Y,n=0;while(n++<200&&(X=x*x)+(Y=y*y)<4){x=X-Y+.36237;y=2*x*y+.32;}return log(n)*256;}
    11 
    12 unsigned short green_fn(int i, int j){
    13 float x=D(i),y=D(j),X,Y,n=0;while(n++<200&&(x*x+y*y)<4){X=x;Y=y;x=X*X-Y*Y+-.7;y=2*X*Y+.27015;}return log(n)*128;}
    14 
    15 unsigned short blue_fn(int i, int j){
    16 float x=D(i),y=D(j),X,Y,n=0;while(n++<600&&(x*x+y*y)<4){X=x;Y=y;x=X*X-Y*Y+.36237;y=2*X*Y+.32;}return log(n)*128;}
    17 */
    18 
    19 // --------------------------------------------------------------------------------------
    20 
    21 #define DIM 1024
    22 #define D(x) (x-512.0f)/512.0f
    23 
    24 float    CPixelJuliaSets1::CalculateRed(float i, float j)
    25 {
    26     float x=D(i),y=D(j);
    27     float X=x*x;
    28     float Y=y*y;
    29     int n=0;
    30     while(n<200 && (X+Y<4))
    31     {
    32         x=X-Y+0.36237f;
    33         y=2*x*y+0.32f;
    34 
    35         X=x*x;
    36         Y=y*y;
    37 
    38         n++;
    39     }
    40     
    41     return logf((float)n)*256.0f;
    42 }
    43 
    44 float    CPixelJuliaSets1::CalculateGreen(float i, float j)
    45 {    
    46     float x=D(i),y=D(j);
    47     float X;
    48     float Y;
    49     int n=0;
    50     while(n<200 && (x*x+y*y)<4)
    51     {
    52         X=x;
    53         Y=y;
    54 
    55         x=X*X-Y*Y-0.7f;
    56         y=2*X*Y+0.27015f;
    57 
    58         n++;
    59     }
    60 
    61     return logf((float)n)*128.0f;
    62 }
    63 
    64 float    CPixelJuliaSets1::CalculateBlue(float i, float j)
    65 {
    66     float x=D(i),y=D(j);
    67     float X;
    68     float Y;
    69     int n=0;
    70     while(n<600&&(x*x+y*y)<4)
    71     {
    72         X=x;
    73         Y=y;
    74 
    75         x=X*X-Y*Y+0.36237f;
    76         y=2*X*Y+0.32f;
    77 
    78         n++;
    79     }
    80     
    81     return logf((float)n)*128.0f;
    82 }
    83 
    84 unsigned int    CPixelJuliaSets1::CalculatePixel(unsigned int x, unsigned int y)
    85 {
    86     float i = (float)x;
    87     float j = (float)y;
    88 
    89     unsigned int r = (unsigned int)CalculateRed(i, j);
    90     unsigned int g = (unsigned int)CalculateGreen(i, j);
    91     unsigned int b = (unsigned int)CalculateBlue(i, j);
    92 
    93     r &= 0xff;
    94     g &= 0xff;
    95     b &= 0xff;
    96 
    97     return MAKE_RGB(r,g,b);
    98 }
    View Code

          有些图像生成算法时间复杂度很高,会很耗时,有的图像需要十几分钟才能生成.用的时候要有心理准备.

    PS:如果该文章能集齐100个赞,我便公布源码.

  • 相关阅读:
    自定义百度地图链接
    Spring中获取request、response对象的方法
    Windows中使用TortoiseGit提交项目到GitLab配置
    IDEA热部署
    SpringBoot+thymeleaf+mybatis+shiro
    lombok——简化Java代码
    SpringBoot部署到tomcat
    深度学习--深入理解Batch Normalization
    MCMC(一)蒙特卡罗法
    Java反射机制详解
  • 原文地址:https://www.cnblogs.com/WhyEngine/p/4034302.html
Copyright © 2011-2022 走看看