2

In MetaPost one can use a loop inside a drawing command; for example

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

I failed to do the same in Asymptote; tried something like

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

checked few tutorials, but did not find an answer.

Hope it is possible, is it?

0

2 Answers 2

4

Asymptote does not allow inline for loops this way. You can imitate them using anonymous functions as in g.kov's answer, but it's really clunky.

Here is a more idiomatic alternative:

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

The function you are using here is called operator... Normally operator..(a, b, c, d) is a more clunky way of writing a..b..c..d; but if you call it as a function, you can expand an array by putting three dots in front of it, so that

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

is equivalent to

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

If you want to use a for loop to produce the points list, the operator..(...points) notation becomes invaluable.

2
  • +1 this is a nice one.
    – g.kov
    Jun 9, 2019 at 1:43
  • Good that both of you took care of this. ;-) +1 to both you and @g.kov.
    – user121799
    Jun 9, 2019 at 3:57
4

I don't think there is such a macro constructor in the Asymptote (it's not a macro language), but instead we can do something equivalent like

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
);

This example uses an anonymous function inside the loop() call from within the draw() command, but there are more options available, for example, define function(s) to be used explicitly, or define a special draw() command, create a class that will generate and keep all the points as well as the curve and a special drawing command, and so on.


Edit:

Perhaps, a closest to the MetaPost construction would be a one-liner

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

which combines @Charles Staats answer with the sequence() command.

4
  • Is there a way to produce a list using a loop? say in path3[] faces={...} Jun 8, 2019 at 19:10
  • 1
    @Anton Petrunin: Why not? For example, fases.push(...); or fases[k]=...;.Check out some examples in docs or on this site, or u can ask a specific question for help.
    – g.kov
    Jun 8, 2019 at 19:27
  • I need to draw something Schwarz's boot en.wikipedia.org/wiki/Schwarz_lantern#/media/… If you know a similar code in asymptote, please share. Jun 8, 2019 at 19:49
  • @Anton Petrunin: Gladly, just create a new question.
    – g.kov
    Jun 9, 2019 at 0:59

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .