zoukankan      html  css  js  c++  java
  • 混沌分形之填充集

          通过分形来生成图像,有一个特点是:不想生成什么样的图像就写出相应的算法,而是生成出来的图像像什么,那算法就是什么。总之,当你在写这个算法时或设置相关参数时,你几乎无法猜测出你要生成的图像是什么样子。而生成图像的时间又比较久,无法实时地调整参数。所以我这使用了填充集的方式,先计算少量的顶点,以显示出图像的大致轮廓。确定好参数后再进行图像生成。所谓填充集,就是随机生成顶点位置,当满足要求时顶点保留,否则剔除。这里将填充集的方式来生成Julia集,曼德勃罗集和牛顿迭代集.

    (1)Julia集

    // 填充Julia集
    // http://www.douban.com/note/230496472/
    class JuliaSet2 : public FractalEquation
    {
    public:
        JuliaSet2()
        {
            m_StartX = 0.0f;
            m_StartY = 0.0f;
            m_StartZ = 0.0f;
    
            m_ParamA = 0.11f;
            m_ParamB = 0.615f;
    
            m_nIterateCount = 80;
        }
    
        void IterateValue(float x, float y, float z, float& outX, float& outY, float& outZ) const
        {
            x = outX = yf_rand_real(-1.0f, 1.0f);
            y = outY = yf_rand_real(-1.0f, 1.0f);
    
            float lengthSqr;
            float temp;
            int count = 0;
            do
            {
                temp = x * x - y * y + m_ParamA;
                y = 2 * x * y + m_ParamB;
                x = temp;
    
                lengthSqr = x * x + y * y;
                count++;
            }
            while ((lengthSqr < 4.0f) && (count < m_nIterateCount));
    
            if (lengthSqr > 4.0f)
            {
                outX = 0.0f;
                outY = 0.0f;
            }
    
            outZ = z;
        }
    
        bool IsValidParamA() const {return true;}
        bool IsValidParamB() const {return true;}
    
    private:
        int m_nIterateCount;
    };

    (2)曼德勃罗集

    // 曼德勃罗集
    // http://www.cnblogs.com/Ninputer/archive/2009/11/24/1609364.html
    class MandelbrotSet : public FractalEquation
    {
    public:
        MandelbrotSet()
        {
            m_StartX = 0.0f;
            m_StartY = 0.0f;
            m_StartZ = 0.0f;
    
            m_ParamA = -1.5f;
            m_ParamB = 1.0f;
            m_ParamC = -1.0f;
            m_ParamD = 1.0f;
    
            m_nIterateCount = 100;
        }
    
        void IterateValue(float x, float y, float z, float& outX, float& outY, float& outZ) const
        {
            float cr = m_ParamA + (m_ParamB - m_ParamA)*((float)rand()/RAND_MAX);
            float ci = m_ParamC + (m_ParamD - m_ParamC)*((float)rand()/RAND_MAX);
    
            outX = 0.0f;
            outY = 0.0f;
    
            float lengthSqr;
            float temp;
            int count = 0;
            do
            {
                temp = outX * outX - outY * outY + cr;
                outY = 2 * outX * outY + ci;
                outX = temp;
    
                lengthSqr = outX * outX + outY * outY;
                count++;
            }
            while ((lengthSqr < 4.0f) && (count < m_nIterateCount));
    
            if (lengthSqr < 4.0f)
            {
                outX = cr;
                outY = ci;
            }
            else
            {
                outX = 0.0f;
                outY = 0.0f;
            }
    
            outZ = z;
        }
    
        bool IsValidParamA() const {return true;}
        bool IsValidParamB() const {return true;}
        bool IsValidParamC() const {return true;}
        bool IsValidParamD() const {return true;}
    
    private:
        int m_nIterateCount;
    };

    (3)牛顿迭代集

    // 牛顿迭代
    // http://www.douban.com/note/230496472/
    class NewtonIterate : public FractalEquation
    {
    public:
        NewtonIterate()
        {
            m_StartX = 0.0f;
            m_StartY = 0.0f;
            m_StartZ = 0.0f;
    
            m_ParamA = 1.0f;
    
            m_nIterateCount = 64;
        }
    
        void IterateValue(float x, float y, float z, float& outX, float& outY, float& outZ) const
        {
            x = outX = yf_rand_real(-m_ParamA, m_ParamA);
            y = outY = yf_rand_real(-m_ParamA, m_ParamA);
    
            float xx, yy, d, tmp;
    
            for (int i = 0; i < m_nIterateCount; i++)
            {
                xx = x*x;
                yy = y*y;
                d = 3.0f*((xx - yy)*(xx - yy) + 4.0f*xx*yy);
                if (fabsf(d) < EPSILON)
                {
                    d = d > 0.0f ? EPSILON : -EPSILON;
                }
                tmp = x;
                x = 0.666667f*x + (xx - yy)/d;
                y = 0.666667f*y - 2.0f*tmp*y/d;
            }
    
            if (x < 0.0f)
            {
                outX = 0.0f;
                outY = 0.0f;
            }
    
            outZ = z;
        }
    
        bool IsValidParamA() const {return true;}
    
    private:
        int m_nIterateCount;
    };

    (4)

    关于基类FractalEquation的定义见:混沌与分形

    再发几幅图像:

     

    ——

  • 相关阅读:
    顺序栈的模拟
    Maven安装教程详解
    C# CRC
    Oracle知识分类之常见规范
    Oracle知识分类之异常
    el-tree树结构的数据封装
    sessionStorage和localStorage
    el-form 中为el-input 添加正则校验 以及el-input正则限制
    动态组件与父子传值的灵活应用 ref控制子组件 props,emit传值
    el-tree树组件的封装 (运用递归对接口返回当前菜单数据为对象处理)
  • 原文地址:https://www.cnblogs.com/WhyEngine/p/4069145.html
Copyright © 2011-2022 走看看