绘制科赫雪花

科赫雪花是一种分形图案,它的绘制规则是:从一个等边三角形开始,将每个边中间三分之一段去掉,然后在此部分向外绘制一个小等边三角形,以此类推。

下面的代码是在 Win32 API 中绘制科赫雪花的方法

// 返回 p1 p2 两点之间的点 p , pp1 : pp2 = r
POINT ratio(double r, POINT p1, POINT p2)
{
    POINT p;
    p.x = p1.x + (p2.x - p1.x) * r;
    p.y = p1.y + (p2.y - p1.y) * r;
    return p;
}

// 递归绘制线段
void drawLine(HDC hdc, POINT p1, POINT p2, int count)
{
    // 当为 0 ,就直接连接
    if (count == 0)
    {
        POINT p[2] = {p1, p2};
        Polyline(hdc, p, 2);
        return;
    }

    // 如果不是最后一次迭代,就空出中间 1/3 段
    POINT interp[2] = {ratio(1.0 / 3, p1, p2), ratio(2.0 / 3, p1, p2)};

    // 绘制这两段
    drawLine(hdc, p1, interp[0], count - 1);
    drawLine(hdc, interp[1], p2, count - 1);

    // 计算中点
    POINT c = {(p1.x + p2.x) / 2, (p1.y + p2.y) / 2};
    // 计算斜率,注意由于纵坐标向下,斜率与标准坐标下相反
    double k = 1.0 * (p2.y - p1.y) / (p1.x - p2.x);
    double d = sqrt((p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y));
    double distance = sqrt(3) * d / 6;
    double dx = distance * k / sqrt(1 + k * k);
    double dy = distance / sqrt(1 + k * k);

    // 计算新增点的位置
    int sign = (p1.x > c.x ? -1 : 1);
    c.x += sign * dx;
    c.y += sign * dy;

    // 绘制凸出部分
    drawLine(hdc, interp[0], c, count - 1);
    drawLine(hdc, c, interp[1], count - 1);
}

// 绘制三个边
void drawTriangle(HDC hdc, POINT points[], int count)
{
    drawLine(hdc, points[0], points[1], count);
    drawLine(hdc, points[1], points[2], count);
    drawLine(hdc, points[2], points[0], count);
}

// 绘图函数
void draw(HDC hdc, POINT c, int d, int count)
{
    POINT points[3] = {{c.x, c.y - d}, {c.x - d / 2 * sqrt(3), c.y + d / 2}, {c.x + d / 2 * sqrt(3), c.y + d / 2}};
    drawTriangle(hdc, points, count);
}

接着在 WM_PAINT 中添加如下代码:

// 绘制图形
int d = 100;
POINT c = {150, 150};

for (int i = 0; i < 2; i++)
{
    for (int j = 0; j < 2; j++)
    {
        draw(hdc, c, d, i * 2 + j);
        c.x += 250;
    }
    c.x = 150;
    c.y += 250;
}

此段代码绘制前 4 个科赫雪花。

 

最终的绘制结果:

绘制科赫雪花
上一篇:决策树(一)


下一篇:Python-标识符和保留字