Sierpinski 三角形 - 通过示例介绍 Silverlight






4.28/5 (13投票s)
2007年5月20日
4分钟阅读

107924

330
通过示例介绍 Silverlight。
引言
"在对的时间、对的光线下,一切都非凡。"
— Aaron Rose
什么是 Silverlight?
"Silverlight 是一个跨浏览器、跨平台的插件,用于在 Web 上交付下一代基于 Microsoft .NET 的媒体体验和丰富的交互式应用程序。"
— http://silverlight.net/
本项目旨在提供一些基础指导,教你如何创建你的第一个 Silverlight 应用程序。主题是数学中最著名的分形之一:Sierpinski 三角。这将使读者熟悉 Silverlight 应用程序创建的基础知识,以及在文件中以及通过 C# 以编程方式处理 XAML 对象的基础知识。
我总是建议在学习新的开发平台时构建一个类似“Hello World”的应用程序。Sierpinski 三角具有足够的趣味性来吸引初学者,而又不会因为不必要的复杂性而使问题混淆。
必备组件
要创建 Silverlight 应用程序,您需要一台机器,我推荐使用虚拟机,并将其设置为满足以下 Silverlight 先决条件
-
运行时
要开始使用 Silverlight,请下载 Silverlight 1.1 Alpha 版本以使用 .NET 语言。
-
Microsoft Silverlight 1.1 Alpha [下载]
查看使用 .NET Microsoft 创建的 Silverlight 应用程序所需的运行时
-
开发人员工具
下载 Visual Studio 开发人员工具以开始开发 Silverlight 应用程序
-
Microsoft Visual Studio 代号“Orcas”Beta 1 [下载]
下一代开发工具
-
Microsoft Silverlight Tools Alpha for Visual Studio 代号“Orcas”Beta 1 [下载]
使用 .NET 创建 Silverlight 应用程序的插件
-
设计工具
下载 Expression 设计工具以开始设计 Silverlight 应用程序
-
Expression Blend 2 五月预览版 [下载]
用于创建 Silverlight 用户交互的专业设计工具
-
软件开发工具包
有关文档、示例和插件,请下载 SDK。
-
Microsoft Silverlight 1.1 Alpha 软件开发工具包 (SDK) [下载]
下载此 SDK 以创建针对 Silverlight 1.1 Alpha 的 Silverlight Web 体验。SDK 包含文档和示例。
背景
Wikipedia.org 文章:Sierpinski 三角(分形)[查看]
"Sierpinski 三角,也称为 Sierpinski 垫,是一种分形,以 Wac?aw Sierpi?ski 的名字命名,他于 1915 年对其进行了描述。最初被构建为一条曲线,这是自相似集合的基本示例之一。"
Sierpinski 三角演示了以下功能
- 如何处理多边形和点
- 如何使用画笔和颜色
- 如何处理背景和图像
- 如何使用计时器
使用代码
使用 Silverlight 在很大程度上意味着您最终将不得不处理 XAML。像 Sierpinki 三角这样的简单分形是学习 XAML 基础知识的绝佳机会,而又不至于过于复杂而需要先学习 XAML 的所有知识。
主要方法
drawSierpinskiTriangle()
这是应用程序的主要工作内容。Sierpinski 三角的定义之一是它是自相似的。换句话说,它是递归的理想候选。
基本上,我们采用具有白色边框、随机彩色内部的三角形集合,并将它们以重复的递归模式放置在画布上。
private void drawSierpinskiTriangle(int[] x, int[] y, int d)
{
// check to see if triangles are getting too small to render
if (d <= dMin)
{
// make a white color brush to draw our triangle borders with
m_brushStroke = new SolidColorBrush();
m_brushStroke.Color = Colors.White;
// make a random color brush to fill our triangles with
m_brushFill = new SolidColorBrush();
m_brushFill.Color = Color.FromRgb(
(byte)m_random.Next(255),
(byte)m_random.Next(255),
(byte)m_random.Next(255));
// add the Polygon Element
Polygon polygon = new Polygon();
polygon.Stroke = m_brushStroke;
polygon.Fill = m_brushFill;
polygon.StrokeThickness = .5;
// create a set of points
Point Point1 = new Point(x[0], y[0]);
Point Point2 = new Point(x[1], y[1]);
Point Point3 = new Point(x[2], y[2]);
// load our polygon with our calculated points
Point[] pointCollection = new Point[3];
pointCollection[0] = Point1;
pointCollection[1] = Point2;
pointCollection[2] = Point3;
polygon.Points = pointCollection;
// find out canvas to draw on
Canvas m_parentCanvas = (Canvas)this.FindName("parentCanvas");
m_parentCanvas.Children.Add(polygon); // bottom of the recursion
}
else
{
// centers of the sides:
int xMc = (x[0] + x[1]) / 2, yMc = (y[0] + y[1]) / 2;
int xMb = (x[0] + x[2]) / 2, yMb = (y[0] + y[2]) / 2;
int xMa = (x[1] + x[2]) / 2, yMa = (y[1] + y[2]) / 2;
int[] xNew1 = { x[0], xMc, xMb };
int[] yNew1 = { y[0], yMc, yMb };
drawSierpinskiTriangle(xNew1, yNew1, d / 2); // recursion
int[] xNew2 = { x[1], xMc, xMa };
int[] yNew2 = { y[1], yMc, yMa };
drawSierpinskiTriangle(xNew2, yNew2, d / 2); // recursion
int[] xNew3 = { x[2], xMb, xMa };
int[] yNew3 = { y[2], yMb, yMa };
drawSierpinskiTriangle(xNew3, yNew3, d / 2); // recursion
}
}
Page_Loaded()
此方法处理分形变量的所有初始化。它启动递归,并启动一个计时器,该计时器将在分形绘制完成后处理三角形背景颜色的随机化。
public void Page_Loaded(object o, EventArgs e) {
// Required to initialize variables
InitializeComponent();
int d = 512; // basis (width of the triangle)
int x0 = 0; // distance from the left
int y0 = 0; // distance from the top
int h = (int)(d * Math.Sqrt(3) / 2); // height
// so: suitable for an equilateral triangle
int xA = x0, yA = y0 + h; // (bottom-left)
int xB = x0 + d, yB = y0 + h; // (bottom-right)
int xC = x0 + d / 2, yC = y0; // equilateral triangle (top-center)
int[] x = { xA, xB, xC };
int[] y = { yA, yB, yC };
drawSierpinskiTriangle(x, y, d / 2); // start recursion
// timer tick will handle animating triangle background colors
System.Windows.Browser.HtmlTimer timer =
new System.Windows.Browser.HtmlTimer();
timer.Interval = 50;
timer.Enabled = true;
timer.Tick += new EventHandler(timer_Tick);
}
timer_Tick()
一旦分形递归完成,该事件将由计时器触发。它的任务是创建一个新的随机颜色画笔,然后选择一个随机三角形并用新颜色填充其内部。这完全是一个装饰效果,只是为了给演示增加一点色彩,字面意义上的。
void timer_Tick(object sender, EventArgs e)
{
m_brushFill = new SolidColorBrush();
m_brushFill.Color = Color.FromRgb(
(byte)m_random.Next(255),
(byte)m_random.Next(255),
(byte)m_random.Next(255));
Canvas m_parentCanvas = (Canvas)this.FindName("parentCanvas");
int childIndex = m_random.Next(m_parentCanvas.Children.Count);
if(childIndex > 2)
((Polygon)m_parentCanvas.Children[childIndex]).Fill = m_brushFill;
}
提示与技巧
Browser.HtmlTimer
我发现 Silverlight 1.1 中有一个 HtmlTimer
类。该类未记录且被标记为过时。
Visual Studio 在编译后显示警告:'System.Windows.Browser.HtmlTimer
' 已过时:'这不是高分辨率计时器,不适用于短间隔动画。下一版本将提供新的计时器类型。
关注点
您可能会注意到的一个问题是,我们一直在重新创建画笔对象,并且从不重复使用它们。这是因为至少在 Silverlight 1.1 Alpha 中,您只能将一个画笔用于一个对象。如果您尝试再次重复使用它,将会引发异常。
请务必使用 System.Windows.Browser.HtmlTimer
检查计时器代码,目前这是实现绘制动画最简单的方法。
资源
历史
- 2007.05.20 - 上传了原始文章