绘图中的循环(渐近线)

绘图中的循环(渐近线)

在 MetaPost 中,可以在绘图命令中使用循环;例如

draw for ix=1 upto 8:(ix*2, 1/(1+cosd ix)).. endfor origin;

我在 Asymptote 中没有做到同样的事情;尝试了类似

draw(for (int k=0; k<=10; ++k){(sin(k),cos(k),sin(k/10))..}cycle);

检查了一些教程,但没有找到答案。

希望这是可能的,是吗?

答案1

Asymptote 不允许以这种方式内联 for 循环。你可以使用匿名函数来模仿它们,如下所示g.kov 的回答,但它确实很笨重。

这是一个更惯用的替代方法:

triple[] points;
for (int k=0; k<=10; ++k) {
    points.push((sin(k),cos(k),sin(k/10)));
}
draw(operator..(...points) .. cycle);

您在此处使用的函数称为operator..。通常,operator..(a, b, c, d)这是一种比较笨拙的写法a..b..c..d;但是,如果您将其作为函数调用,则可以通过在数组前面放置三个点来扩展数组,以便

pair[] points = {a1, a2, a3, a4, a5, a6, a7, a8, a9};
guide g = operator..(...points);

相当于

guide g = a1 .. a2 .. a3 .. a4 .. a5 .. a6 .. a7 .. a8 .. a9;

如果您想使用for循环来生成points列表,那么这种operator..(...points)符号就变得非常有价值。

答案2

我不认为 Asymptote 中有这样的宏构造函数(它不是一种宏语言),但我们可以做一些等效的事情,例如

import graph3;
size(9cm);

guide3 loop(int n, triple F(int,int)){
  guide3 g;
  for (int k=0; k<=n; ++k)g=g..F(k,n);
  return g..cycle;
}

draw(
  loop(
   10, 
   new triple(int k, int n){return (sin(k),cos(k),sin(k/n));} 
  )
 ,red+0.7bp
);

loop() 此示例在命令内部的调用中使用了匿名函数draw(),但还有更多可用选项,例如,定义要明确使用的函数,或定义特殊draw()命令,创建一个将生成并保留所有点以及曲线和特殊绘图命令的类,等等。


编辑:

也许,最接近 MetaPost 构造的可能是一行代码

draw(operator..(...sequence(new triple(int k){return (sin(k),cos(k),sin(k/10));},10))..cycle);

它将@Charles Staats 的回答与 sequence()命令结合在一起。

相关内容