# Drawing graphics part by part

What I want to do is to draw graphics part by part, because I made a function that generates coordinates according to which I will draw graphics. The problem is that MMA does not operate as I expected. To figure out what I'm doing here's simplified example:

Graphics[{
a = 1;
Label[tag];
If[a < 3,
{Circle[{a, 1}, 1],
a = a + 1;
Goto[tag];},
{Text["It's finished", {0, 0}]}]
}]


And what I get as output is simply text "It's finished". But what I want as output is graphics with two circles with radii 1 and centers positioned at {1,1} and {2,1} together with text "It's finished".

I figure out the way MMA thinks, and why it gives me this as output. But how can I accomplish my desired output?

Edit:

Here's the code, It's really messy and tips on how to neatly write code in MMA would be appreciated.

   Manipulate[

Graphics[{

(*calculating incident angle*)
α = ArcSin[H/R];
(*calculating x-coordinate where incident ray leaves prism*)
p = Sqrt[R^2 - H^2];
(*Drawing incident ray*)
{Red, Thick, Line[{{-2, H}, {p, H}}]},

(*Drawing prism*)
{Blue, Opacity[.5], Disk[{0, 0}, R, {0, Pi/2}]},

(*checking whether it's reflection or refraction*)
If[H < R/n,
{(*refraction*)
(*calculating x-coordinate where refracted ray hits surface*)
l = (R^2 n)/(Sqrt[R^2 - H^2] n - Sqrt[R^2 - H^2 n^2]);
(*Drawing refracted ray*)
{Red, Thick, Line[{{p, H}, {l, 0}}]}
},

{(*internal reflection*)
(*calculating x-coordinate where after internal reflection ray hits \
surface*)
new = H;
k = 1;
Label[tag];
s = R Cos[α] - new/Tan[2 α];
If[s <= R,
{
{Red, Thick, Line[{{p, new}, {s, 0}}]}
},

{
θ = (2 k + 1) α - k Pi;
f = R Cos[θ];
h = R Sin[θ];
k = k + 1;
Line[{{{p, new}, {f, h}}}],
new = h;
p = f;
Goto[tag];
}
]
}
]
}],

{{H, 3, "Height"}, 0.0001, R - 0.0001, Appearance -> "Labeled"},
{{n, 1.5, "Refraction"}, 1.001, 2, Appearance -> "Labeled"},
{{R, 10, "Radius"}, 0, 10, Appearance -> "Labeled"}
]

• I think you need to reconstruct this using either While or TakeWhile Jan 20, 2012 at 1:19
• Do you really want to do this with Goto? It'll be more complicated than what I gave below.
– acl
Jan 20, 2012 at 1:24

What you want is done by

Graphics[Table[Circle[{a, 1}, 1], {a, 1, 2}] ~Append~ Text["It's finished", {0, 0}]] Here's another approach, with minimal changes to your code:

Graphics[
{
a = 1;
Label[tag];
If[a < 3,
{Sow @ Circle[{a, 1}, 1], a = a + 1; Goto[tag];},
{Sow @ Text["It's finished", {0, 0}]}]
} // Reap // Last // Last
]


EDIT: I'm afraid I am not sure what that is supposed to look like, but does this

Manipulate[
Graphics[
{
α = ArcSin[H/R];
p = Sqrt[R^2 - H^2];
{Red, Thick, Line[{{-2, H}, {p, H}}]},
{Blue, Opacity[.5], Disk[{0, 0}, R, {0, Pi/2}]},
If[
H < R/n,
{
l = (R^2 n)/(Sqrt[R^2 - H^2] n - Sqrt[R^2 - H^2 n^2]);
{Red, Thick, Line[{{p, H}, {l, 0}}]}
},
Last@Last@Reap[
{
novo = H;
k = 2;
Sow@Text[θ, {10, 5}], Text[α, {10, 7}],
Text[k, {10, 9}],
Label[oznaka];
s = R Cos[α] - novo/Tan[2 α];
If[s <= R,
Sow@{{Red, Thick, Line[{{p, novo}, {s, 0}}]}},
{θ = (2 k + 1) α - k Pi;
f = R Cos[θ];
h = R Sin[θ];
k = k + 1;
Sow@Line[{{{p, novo}, {f, h}}}], novo = h;
p = f;
Goto[oznaka];}]}
]
]
}
],
{{H, 9.45991, "Vertikalna udaljenost upadne zrake"}, 0.0001,
R - 0.0001,
Appearance -> "Labeled"}, {{n, 1.5,
"Koeficijent prelamanja stakla"}, 1.001, 2,
Appearance -> "Labeled"}, {{R, 10, "Poluprecnik prizme"}, 0, 10,
Appearance -> "Labeled"}]


work? • I don't think that Table[] will help me, because I have complicated graphics. But it's my fault, I did't explained it in my question, I'll edit it now. Jan 20, 2012 at 1:26
• This is a minimally-altered version of your code that (I think) does what you want. Are you sure Table won't work? It's practically equivalent to the If-Goto structure you have.
– acl
Jan 20, 2012 at 1:30
• yes, you solved it, I don't know how because I rushed with question and code I put was bad. But you did it. Thank you very much. And sorry for bad asked question. Jan 20, 2012 at 1:55
• No problem. I will try to make some suggestions on how to make this more readable/less error prone tomorrow (although this is the first time I've seen Goto used in mathematica, which makes this exotic...)
– acl
Jan 20, 2012 at 1:58

(Starting remark: Just like in any other language, Goto is an evil statement that should never ever be used.)

One way of accomplishing what you want is generating the code as an ordinary list, and then giving this to Graphics:

 In := circles = Table[Circle[{a, 1}], {a, 1, 2}]
Out  = {Circle[{1, 1}], Circle[{2, 1}]}

In := text = {Text["It's finished", {0, 0}]}
Out  = {Text["It's finished", {0, 0}]}

In := Join[circles, text]
Graphics[%]
Out  = {Circle[{1, 1}], Circle[{2, 1}], Text["It's finished", {0, 0}]} You could also have created two separate graphics first, and then combined these with Show:

circles = Graphics@Table[Circle[{a, 1}], {a, 1, 2}];
text = Graphics@{Text["It's finished", {0, 0}]};
Show[circles, text]

• "Goto[] is an evil statement that should never ever be used." - that's quite harsh; there are times one might need to use a label-goto pair. On the other hand, due to the richness of Mathematica, times like those are exceedingly rare. Jan 20, 2012 at 1:33

If you know for sure that it is just a matter of $a = 1, 2, 3,...$ and you want to stop at 3, then this is sufficient.

Graphics[Join[
Circle[{#, 1}, 1] & /@ Range, {Text["It's finished", {0, 0}]}]]


If the values of $a$ are not known in advance and not in order of magnitude, then something like this would be sufficient:

Graphics[Join[
Circle[{#, 1}, 1] & /@
TakeWhile[RandomInteger[4, {10}], # < 4 &], {Text["It's finished", {0, 0}]}]]


Note I've used $a<4$ as the criterion not $a<3$ as in the question, to make the second example a bit more interesting. Both cases generate a graphic identical to this one. But from the title of your question, I get the impression that what you really want is a sequence of graphics, showing the image built up step by step. For that you want something using NestWhileList, FoldList or similar. Below is an example using NestWhileList. If you only want the last one to have the text, this is a straightforward modification of the code below.

Graphics[Join[#, {Text["It's finished", {0, 0}]}]] & /@
Rest@NestWhileList[
Flatten@Join[{#}, {Circle[{Length[#] + 1, 1}, 1]}] &, {},
Length[#] < 3 &]
` 