We try to make a rectangle move around in a closed space. The object moves at a certain speed in directions X and Y. When it encounters a border of the graphical window, it bounces back depending on the angle of impact. We assume a situation without overlapping of the new and old positions of the object. The function

`,`

y`,`

sy`,`

dyThe function

#let`calc_pv`

(x`,`

y)

(sx`,`

sy)

(dx`,`

dy)

`=`

let`nx1`

`=`

`x`

`+`

dx

and

`ny1`

`=`

`y`

`+`

`dy`

and`nx2`

`=`

`x`

`+`

sx`+`

dx

and

`ny2`

`=`

`y`

`+`

sy`+`

dy

and`ndx`

`=`

`ref`

`dx`

and

`ndy`

`=`

`ref`

`dy`

in

(

if

(nx1

`<`

`0`

)

`||`

(nx2

`>=`

`Graphics.size_x()`

)

then`ndx`

`:=`

`-`

dx

);

(

if

(ny1

`<`

`0`

)

`||`

(ny2

`>=`

`Graphics.size_y()`

)

then`ndy`

`:=`

`-`

dy

);

((x`+`

`!`

ndx`,`

`y`

`+`

`!`

ndy)`,`

(`!`

ndx`,`

`!`

ndy));;`val calc_pv :`

`int * int -> int * int -> int * int -> (int * int) * (int * int) = <fun>`

#let`move_rect`

`pos`

`size`

`speed`

`n`

`=`

let

(x`,`

`y`

)

`=`

`pos`

and

(sx`,`

sy)

`=`

`size`

in

let`mem`

`=`

`ref`

(Graphics.get_image`x`

`y`

`sx`

`sy`

)

in

let

rec`move_aux`

`x`

`y`

`speed`

`n`

`=`

if`n`

`=`

`0`

then`Graphics.moveto`

`x`

`y`

else

let

((nx`,`

ny)`,`

n_speed)

`=`

`calc_pv`

(x`,`

y)

(sx`,`

sy)`speed`

and`old_mem`

`=`

`!`

mem

in

`mem`

`:=`

`Graphics.get_image`

`nx`

`ny`

`sx`

`sy;`

`Graphics.set_color`

`Graphics.blue;`

`Graphics.fill_rect`

`nx`

`ny`

`sx`

`sy;`

`Graphics.draw_image`

(inv_image`old_mem`

)`x`

`y;`

`move_aux`

`nx`

`ny`

`n_speed`

(n`-`

`1`

)

in`move_aux`

`x`

`y`

`speed`

`n;;`

`val move_rect : int * int -> int * int -> int * int -> int -> unit = <fun>`

The following code corresponds to the drawings in figure 5.7. The first is obtained on a uniformly red background, the second by moving the rectangle across the image of Jussieu.

#let`anim_rect`

`()`

`=`

`Graphics.moveto`

`1`

`0`

`5`

`1`

`2`

`0`

;

`Graphics.set_color`

`Graphics.white;`

`Graphics.draw_string`

`"Start"`

;

`move_rect`

(`1`

`4`

`0`

`,`

`1`

`2`

`0`

)

(`8`

`,`

`8`

)

(`8`

`,`

`4`

)

`1`

`5`

`0`

;

let

(x`,`

y)

`=`

`Graphics.current_point()`

in

`Graphics.moveto`

(x`+`

`1`

`3`

)`y;`

`Graphics.set_color`

`Graphics.white;`

`Graphics.draw_string`

`"End"`

;;`val anim_rect : unit -> unit = <fun>`

# anim_rect();;`- : unit = ()`

The problem was simplified, because there was no intersection between two successive positions of the moved object. If this is not the case, it is necessary to write a function that computes this intersection, which can be more or less complicated depending on the form of the object. In the case of a square, the intersection of two squares yields a rectangle. This intersection has to be removed.

Figure 5.7: Moving an object.