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

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

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.28/5 (13投票s)

2007年5月20日

4分钟阅读

viewsIcon

107924

downloadIcon

330

通过示例介绍 Silverlight。

Screenshot - sierpinskitriangle.gif

在线演示

引言

"在对的时间、对的光线下,一切都非凡。"
— 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 - 上传了原始文章
© . All rights reserved.