Reputation: 97
Can you use a whileTrue: inside a block closure? I can't get it to work so I suspect not. Or I am doing something wrong.
map := #([1 1 1 1 1]
[1 0 0 0 1]
[1 0 1 0 1]
[1 0 0 0 1]
[1 1 1 1 1]).
posx := 1.
posy := 1.
t4 := CompositePart new.
rot := (Core.Double.Pi / 4).
perspective := Core.OrderedCollection new.
1 to: 60 do: [:i | perspective add: (rot + (i - 30) asRAD).
rot_i := perspective at: i.
x := posx.
y := posy.
gsin := (0.2 * (rot_i sin)).
gcos := (0.2 * (rot_i cos)).
t2 := true.
[t2 = true]
whileTrue: [
x := (x + gcos).
y := (y + gsin).
n := (n + 1).
mapCoord := map at: x rounded asInteger.
mapCoord := (mapCoord at: y rounded asInteger).
(mapCoord = 1)
ifTrue: [
h := 1/(0.2 * n).
t2 := false]].
t3 := (i @ h extent: 2 @ h ) asFiller.
t4 add: t3].
I would like to get everything inside the whileTrue block to repeat if mapCoord isn't equal to 1. But it doesnt, it just chugs along to the next iteration in the "do:" block. I suspect Im doing something wrong, but I can't figure it out.
Upvotes: 2
Views: 332
Reputation: 143
[:i| | eye x y gsin gcos coordinate notLessThanOne h |
" So I can see it too. Yes--A while loop inside a block is fine "
eye := perspective add: (rot + (i - 30) asRAD).
X := posx. " x = 1 "
y := posy. " y = 1 "
gsin := (0.2 * (eye sin)).
gcos := (0.2 * (eye cos)).
coordinate := notLessThanOne.
[ coordinate < 1 " op changed to < "
] whileFalse:
[x := (x + gcos). " 0.8 <= x <= 1.2 "
y := (y + gsin). " 0.8 <= y <= 1.2 "
n := (n + 1). " grows forever? "
coordinate := map at: x rounded." is #[1 1 1 1 1] "
coordinate := coordinate at: y rounded." is 1 "
].
h := 1/(0.2 * n).
parts add: (1@h extent: 2@h) asFiller
]
Upvotes: 0
Reputation: 2433
Syntactically there's no reason that it shouldn't work and as you can run the code, the answer to your question is: Yes you can! If you think the while loop doesn't do what you expect, i suggest you don't "do it", but rather try the "debug it" command. That'll allow you to step through your code statement by statement. You can inspect all variables along the way and maybe find out what's wrong.
Some remarks about your code:
Point
, which has a x and y property. It also supports large parts of the number's protocol, which means you can send the message rounded
to a Point
, too. You can create Point
objects via @
like: point := 4 @ 5
. Points also allow arithmetics like point * 4
or point + something
.rounded
returns an Integer
, so there's no need to explicitly convert it via asInteger
.asRAD
but there's already a system method degreesToRadians
t4
could be aComposite
Upvotes: 3
Reputation: 14843
This is what I see.
At every do:
iteration, both x
and y
are initialized to 1
and then, inside the whileTrue:
, to something between 0.8
and 1.2
. Thus, the first assignment of mapCoord
evaluates to #[1 1 1 1 1]
and the second to 1
because #[1 1 1 1 1] at: 1
is 1
. Thus, t2
becomes false
and the whileTrue:
exits.
More clearly
x := posx. "x = 1"
y := posy. "y = 1"
gsin := (0.2 * (rot_i sin)).
gcos := (0.2 * (rot_i cos)).
t2 := true.
[t2 = true]
whileTrue: [
x := (x + gcos). "0.8 <= x <= 1.2"
y := (y + gsin). "0.8 <= y <= 1.2"
n := (n + 1).
mapCoord := map at: x rounded asInteger. "mapCoord = #[1 1 1 1 1]
mapCoord := (mapCoord at: y rounded asInteger). "mapCoord = 1"
(mapCoord = 1)
ifTrue: [
h := 1/(0.2 * n).
t2 := false]]. "t2 = false"
Upvotes: 3