用 C# 绘制谢尔宾斯基垫片

谢尔宾斯基垫片是一个三角形,分解成多个小三角形,如右图所示。有几种方法可以生成这种垫片。这里展示的方法是其中一种比较令人惊讶的方法。

程序从三个点开始(图中圆圈所示)。“当前位置”从其中一个点开始。为了生成后续点,程序会随机选择一个点,并从当前位置移动到该点的一半。重复多次后,垫圈就会神奇地开始出现。

示例程序使用以下代码来绘制分形。

// Add 1000 points to the gasket.
private void tmrDraw_Tick(object sender, EventArgs e)
{
    // Draw points.
    Random rand = new Random();
    using (Graphics gr = this.CreateGraphics())
    {
        // Draw the corners.
        foreach (PointF pt in Corners)
        {
            gr.FillEllipse(Brushes.White, pt.X - 2, pt.Y - 2, 4, 4);
            gr.DrawEllipse(Pens.Blue, pt.X - 2, pt.Y - 2, 4, 4);
        }

        // Draw 1000 points.
        for (int i = 1; i <= 1000; i++)
        {
            int j = rand.Next(0, 3);
            LastPoint = new PointF(
                (LastPoint.X + Corners[j].X) / 2,
                (LastPoint.Y + Corners[j].Y) / 2);
            gr.DrawLine(Pens.Red, LastPoint.X, LastPoint.Y,
                LastPoint.X + 1, LastPoint.Y + 1);
        }
    }
}

每次tmrDraw计时器计时,代码都会绘制 1,000 个点。程序使用计时器,以便程序可以刷新其绘图。它每次绘制 1,000 个点以提高性能。

对于这 1,000 个点中的每一个,代码都会选择一个随机点,并将变量LastPoint从其当前位置移动到选定点的一半。代码用一条小线标记该点(因为这比绘制小圆圈更快,也比绘制单个像素更容易。)

要重新启动垫圈,请调整大小或隐藏并恢复表格。

绘制谢尔宾斯基垫片(无论如何作为奇异吸引子)的常用方法是从 3 个角开始。要生成一个点,请随机选择一个角,然后移动到当前位置和所选角之间的一半。

此示例可让您在运行时选择角点。左键单击表单以选择至少 2 个点。然后右键单击以启动程序运行。该程序使用以下代码绘制修改后的垫圈

// Draw 1,000 points.
private void tmrDraw_Tick(object sender, EventArgs e)
{
    // Draw points.
    Random rand = new Random();
    using (Graphics gr = this.CreateGraphics())
    {
        // Draw the corners.
        foreach (PointF pt in Corners)
        {
            gr.FillEllipse(Brushes.White, pt.X - RADIUS,
                pt.Y - RADIUS, 2 * RADIUS, 2 * RADIUS);
            gr.DrawEllipse(Pens.Blue, pt.X - RADIUS,
                pt.Y - RADIUS, 2 * RADIUS, 2 * RADIUS);
        }

        // Draw 1000 points.
        for (int i = 1; i <= 1000; i++)
        {
            int j = rand.Next(0, Corners.Count);
            LastPoint = new Point(
                (LastPoint.X + Corners[j].X) / 2,
                (LastPoint.Y + Corners[j].Y) / 2);
            gr.DrawLine(Pens.Blue, LastPoint.X, LastPoint.Y,
                LastPoint.X + 1, LastPoint.Y + 1);
        }
    }
}

要获得一些有趣的结果,请尝试:

  • 使用构成矩形的四个角。
  • 使用不等边三角形。
  • 使用三角形并在靠近中间的同一位置添加 4 或 5 个“角”。
  • 尝试具有重复角的其他排列。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

坐井观老天

您的鼓励是我分享的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值