Metapost方程

时间:2012-11-02 19:35:53

标签: metapost

在我的一门课程中,我接到了一份家庭作业,要求我们使用Metapost语言,并找到该语言中方程求解功能的用法。 在浏览了Metapost用户手册的前十几页之后,我发现只有一个原因可以解释为什么它有用并且“允许许多程序被写入 一种很有说服力的风格。“ 除了声明它使编程更“声明”(从我理解的意思是我们告诉语言该做什么而不是如何做)我想不出为什么方程求解是有用的任何其他原因。 任何人都可以帮助我吗?

1 个答案:

答案 0 :(得分:3)

以下是如何解决MetaPost中的方程式 - 以及声明式编程中的方程式 - 可能有用。

假设我们想要绘制die

pic 0

要做到这一点,我们首先定义一个宏,它将绘制骰子的一个面:一个数字为s的正方形。

def face (expr s) = image (begingroup
    pickup pencircle scaled 1pt;
    draw (0.5, 0.5) -- (0.5, 9.5) -- (9.5, 9.5) -- (9.5, 0.5) -- cycle;
    label (s, (5, 5));
endgroup) scaled 10 enddef;

现在我们可以绘制它并获得图片:

draw face ("1");

pic 1

接下来,我们需要一个上面和一个右面。为了绘制它们,我们将不得不构成一个仿射变换来扭曲它们。这可能很棘手,因为唯一容易获得的偏移原始变换是slanted a,它将点(x, y)转换为(x + ay, y)。这是我们的图片倾斜1:

draw face ("2") slanted 1;

pic 2

然后我们将(或者更确切地说,之前)必须按以下坐标之一进行缩放:

draw face ("2") yscaled 0.35 slanted 1;

pic 3

同样的方法不会立即对第三面起作用:

draw face ("3") xscaled 0.35 slanted 1;

pic 4

经过一些实验,我们找到了正确的代码:

draw face ("3") rotated 90 yscaled 0.35 slanted -1 rotated -90;

pic 5

但为什么所有单调乏味?我们确切知道我们需要什么样的转型。表达它的一种自然方式是使用基元。但如果这证明不直观,就像我们的最后一行那样,那么指定平面的哪些点可以变得更加舒适。

transform t;
(0, 0) transformed t = (0, 0);
(0, 1) transformed t = (0.35, 0.35);
(1, 0) transformed t = (1, 0);
draw face ("3") transformed t;

这基本上告诉MetaPost:有一个变换t,我们指定的三个点移动到我们指定的其他三个点。事实证明这是唯一确定平面变换的,我们得到了相同的图片:

pic 6

将所有这些放在一起(代码在帖子末尾为beginfig (7))可以让我们最终看到我们的死亡:

pic 7

在这种简单的情况下,“坐标和方程式”方法在难度上与“原始变换”方法相当。现在,想象一下我们想要立方体略微倾斜。使用相同的声明方法,仍然可以在不调用三维几何的情况下(代码在帖子末尾为beginfig (8)):

pic 8


完整的程序如下。

prologues := 3;

def face (expr s) = image (begingroup
    pickup pencircle scaled 1pt;
    draw (0.5, 0.5) -- (0.5, 9.5) -- (9.5, 9.5) -- (9.5, 0.5) -- cycle;
    label (s, (5, 5));
endgroup) scaled 10 enddef;

beginfig (1)
    draw face ("1");
endfig;

beginfig (2)
    draw face ("2") slanted 1;
endfig;

beginfig (3)
    draw face ("2") yscaled 0.35 slanted 1;
endfig;

beginfig (4)
    draw face ("3") xscaled 0.35 slanted 1;
endfig;

beginfig (5)
    draw face ("3") rotated 90 yscaled 0.35 slanted -1 rotated -90;
endfig;

beginfig (6)
    transform t;
    (0, 0) transformed t = (0, 0);
    (0, 1) transformed t = (0, 1);
    (1, 0) transformed t = (0.35, 0.35);
    draw face ("3") transformed t;
endfig;

beginfig (7)
    transform t [];

    draw face ("1");

    (0, 0) transformed t[1] = (0, 0);
    (0, 1) transformed t[1] = (0.35, 0.35);
    (1, 0) transformed t[1] = (1, 0);
    draw face ("2") transformed t[1] shifted (0, 100);

    (0, 0) transformed t[2] = (0, 0);
    (0, 1) transformed t[2] = (0, 1);
    (1, 0) transformed t[2] = (0.35, 0.35);
    draw face ("3") transformed t[2] shifted (100, 0);
endfig;

beginfig (8)
    transform t [];
    pair Ox, Oy, Oz;
    Ox = (0.86, -0.21);
    Oy = (0.21, 0.86);
    Oz = (0.29, 0.44);

    (0, 0) transformed t[1] = (0, 0);
    (1, 0) transformed t[1] = Ox;
    (0, 1) transformed t[1] = Oy;
    draw face ("4") transformed t[1];

    (0, 0) transformed t[2] = (0, 0);
    (1, 0) transformed t[2] = Ox;
    (0, 1) transformed t[2] = Oz;
    draw face ("5") transformed t[2] shifted (Oy scaled 100);

    (0, 0) transformed t[3] = (0, 0);
    (1, 0) transformed t[3] = Oz;
    (0, 1) transformed t[3] = Oy;
    draw face ("6") transformed t[3] shifted (Ox scaled 100);
endfig;

end