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






2.67/5 (4投票s)
如何构建和可视化 IFS 系统。
引言
迭代函数系统 (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