65.9K
CodeProject 正在变化。 阅读更多。
Home

简单的 IFS 引擎(迭代函数系统)

starIconstarIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIcon

2.67/5 (4投票s)

2008年11月18日

CPOL
viewsIcon

30958

downloadIcon

1025

如何构建和可视化 IFS 系统。

IFSEngine_bin

引言

迭代函数系统 (IFS) 是一种构建分形的方法;由此产生的构造总是自相似的(有关 IFS 系统的更多信息,请参见维基百科)。

背景

这个应用程序是我的大学科学项目。这项工作可用于分形构建(纹理生成、地形生成等)。

使用代码

主类是 IFSEngine

public class IFSEngine: IFractalable
{

    private IFSExample ifs;
    private double scaleX = 100;
    private double scaleY = -100;

    public double ScaleY
    {
        get { return scaleY; }
        set { scaleY = value; }
    }
    private static Random random = new Random();

    public double ScaleX
    {
        get { return scaleX; }
        set { scaleX = value; }
    }

    public IFSExample IFS
    {
        get { return ifs; }
        set { ifs = value; }
    }
    private int iteration = 10000;

    public int IterationCount
    {
        get { return iteration; }
        set { iteration = value; }
    }

    public System.Drawing.Bitmap GetPicture(int width, int height)
    {
        int mx = width/2;
        int my = height/2;
        
        double x = 0.0;
        double y = 0.0;
        double t;
        Bitmap bitmap = new Bitmap(width, height);
        Graphics g = Graphics.FromImage(bitmap);

        for (int k = 0; k < iteration; k++)
        {
            double p = random.NextDouble();
            t = x;
            x = ifs.GetX(x, y, p);
            y = ifs.GetY(t, y, p);
            Int64 xx = Convert.ToInt64(mx + scaleX * x);
            Int64 yy = Convert.ToInt64(my + scaleY * y);
            if ((xx > 0) & (xx < width) & (yy > 0) & (yy < height))
            {
                bitmap.SetPixel((int)xx, (int)yy, 
                   Color.FromArgb(Convert.ToInt16(p * 200 + 20), 
                   Convert.ToInt16(p * 200 + 20), 
                   Convert.ToInt16(p * 200 + 20)));
            }
        }
        return bitmap;
    }

IFractalable 是一个简单的分形类接口

public interface IFractalable
{
    Bitmap GetPicture(int x, int y);
}

IFSExample 用于 IFS 系统。该类包含 IFS 系数。

public class IFSExample
{
    private string name;

    public string Name
    {
        get { return name; }
        set { name = value; }
    }

    public static IFSExample FromIFSFile(string filename)
    {
        string text = "";
        using (StreamReader sr = new StreamReader(filename))
        {
            text = sr.ReadToEnd();
        }
        return new IFSExample(text);
    }

    public List<double[]> list = new List<double[]>();

    private void ParseString(string desc)
    {
        string fs = desc.Split(new string[1] { "Row" }, 
                    StringSplitOptions.RemoveEmptyEntries)[0];
        string name = fs.Split(':')[1].Split('\n', '\r')[0]; ;
        this.name = name;
        for (int i = 1; i < desc.Split(new string[1] { "Row" }, 
             StringSplitOptions.RemoveEmptyEntries).Length; i++)
        {
            string s = desc.Split(new string[1] { "Row" }, 
                       StringSplitOptions.RemoveEmptyEntries)[i].Split('\n','\r')[0];
            double[] koefs = new double[7];
            for (int j = 0; j < 7; j++)
            {
                koefs[j] = Convert.ToDouble(d);
            }
            list.Add(koefs);
        }
    }

    public IFSExample(string desc)
    {
        ParseString(desc);
    }

    public double GetX(double x, double y, double p)
    {
        double pp = 0;
        double[] koef = list[0];
        for (int i = 0; i < list.Count; i++)
        {
            pp += list[i][6];
            koef = list[i];
            if (p <= pp)
            {
                break;
            }
        }
        return koef[0] * x + koef[1] * y + koef[4];
    }

    public double GetY(double x, double y, double p)
    {
        double pp = 0;
        double[] koef = list[0];
        for (int i = 0; i < list.Count; i++)
        {
            pp += list[i][6];
            koef = list[i];
            if (p <= pp)
            {
                break;
            }
        }
        return koef[2] * x + koef[3] * y + koef[5];
    }
}

IFS 文件具有简单的结构

Name:<Name>
Row <c11>, <c12>,  <c13>, <c14>, <c15>, <c16>, <p1>
...
Row <cn1>, <cn2>,  <cn3>, <cn4>, <cn5>, <cn6>, <pn>

例如

Name:Leaf
Row 0.14,  0.01,  0.00, 0.51, -0.08, -1.31, 0.06
Row 0.43,  0.52, -0.45, 0.50,  1.49, -0.75, 0.37
Row 0.45, -0.49,  0.47, 0.47, -1.62, -0.74, 0.36
Row 0.49,  0.00,  0.00, 0.51,  0.02,  1.62, 0.21
© . All rights reserved.