# Javis collision detection

**URL:** <https://discourse.julialang.org/t/javis-collision-detection/87398>\
**Category:** General Usage\
**Tags:** question, package, javis\
**Created:** [September 17, 2022, 9:47am UTC](https://discourse.julialang.org/t/javis-collision-detection/87398 "2022-09-17T09:47:28Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![DoktorMike](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/doktormike/32/2736_2.png) [@DoktorMike](https://discourse.julialang.org/u/DoktorMike)\
**Post date:** [September 17, 2022, 9:47am UTC](https://discourse.julialang.org/t/javis-collision-detection/87398/1 "2022-09-17T09:47:28Z")

</div>

So I’m using the excellent package Javis.jl where I’m making a small simulation to teach my kids about entropy. Basically I want a box with a number of of balls bouncing around in it. I want to be able to detect when the balls collide with each other or with the walls of the box but i cannot see how to do it using the existing translate function. Has anyone tried something similar? The only way that came to me was to precalculate all the trajectories but there must be a better way i believe.

---

<div class="post-metadata">

**Author:** ![cormullion](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cormullion/32/49131_2.png) [@cormullion](https://discourse.julialang.org/u/cormullion)\
**Post date:** [September 17, 2022, 12:10pm UTC](https://discourse.julialang.org/t/javis-collision-detection/87398/2 "2022-09-17T12:10:44Z")

</div>

I confess I’ve not used Javis, but I think you’d just update and collision-check the positions of each ball after each frame. I’ve done similar with Luxor:

![julia-billiard-pool](https://global.discourse-cdn.com/julialang/original/3X/b/d/bd25ddef91a44c5306af4ce7d7456f82e65434a5.gif)

so it should be easier in Javis.

@Wikunia or @TheCedarPrince would be happy to help, so I’ll mention them here.

---

<div class="post-metadata">

**Author:** ![DoktorMike](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/doktormike/32/2736_2.png) [@DoktorMike](https://discourse.julialang.org/u/DoktorMike)\
**Post date:** [September 17, 2022, 2:15pm UTC](https://discourse.julialang.org/t/javis-collision-detection/87398/3 "2022-09-17T14:15:16Z")

</div>

Thank you so much for the reply, this sets me on the right path I think. I have a small example for 1 ball here

```julia
using Javis

function ground(args...)
  background("white")
  sethue("black")
end

function object(p=O, color="black")
  sethue(color)
  circle(p, 25, :fill)
  return p
end

function updatedirection!(bpos)
end

myvideo = Video(500, 500)
Background(1:70, ground)
redball = Object(1:70, (args...) -> object(O, "red"), Point(-250, -250))
Object(1:70, (args...) -> updatedirection!(pos(redball)))
act!(redball, Action(anim_translate(300, 300)))
render(myvideo; pathname="entropy.gif")

```

But the thing here is that I don’t know what to put in `updatedirection!` I’m assuming it should update the position of the ball but just accessing the x and y fields in the struct is not allowed so I guess I need a function to mutate these states somehow.

---

<div class="post-metadata">

**Author:** ![cormullion](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cormullion/32/49131_2.png) [@cormullion](https://discourse.julialang.org/u/cormullion)\
**Post date:** [September 17, 2022, 2:35pm UTC](https://discourse.julialang.org/t/javis-collision-detection/87398/4 "2022-09-17T14:35:32Z")

</div>

Not sure about Javis _per se_, but you can change points stored in a mutable struct:

```julia
ball.pos = Point(ball.pos.x + 1, ball.pos.y)

```

---

<div class="post-metadata">

**Author:** ![DoktorMike](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/doktormike/32/2736_2.png) [@DoktorMike](https://discourse.julialang.org/u/DoktorMike)\
**Post date:** [September 17, 2022, 2:36pm UTC](https://discourse.julialang.org/t/javis-collision-detection/87398/5 "2022-09-17T14:36:42Z")

</div>

~~Ahh… I was trying to update the `x` directly. Thanks!~~

I was too fast, upon testing this I cannot get it to work.

```julia
function updatedirection!(ball)
  ball.pos = Point(-ball.pos.x, ball.pos.y)
  ball
end

myvideo = Video(500, 500)
Background(1:70, ground)
redball = Object(1:70, (args...) -> object(O, "red"), Point(-250, -250))
Object(1:70, (args...) -> updatedirection!(redball))
act!(redball, Action(anim_translate(500, 500)))
render(myvideo; pathname="entropy.gif")

```

It seems that `redball` does not have a `.pos` field so I cannot set it to a new `Point`. I must misunderstand completely how the underlying state is handled in Javis.

This is the error:

```julia
ERROR: type Object has no field pos
Stacktrace:
  [1] getproperty
    @ ./Base.jl:38 [inlined]
  [2] updatedirection!(ball::Object)
    @ Main ./REPL[73]:2
  [3] (::var"#29#30")(::Video, ::Vararg{Any})
    @ Main ./REPL[77]:1
  [4] draw_object(object::Object, video::Video, frame::Int64, origin_matrix::Matrix{Float64}, layer_frames::Nothing)
    @ Javis ~/.julia/packages/Javis/UaLm7/src/Javis.jl:666
  [5] macro expansion
    @ ~/.julia/packages/Javis/UaLm7/src/Javis.jl:416 [inlined]
  [6] macro expansion
    @ ~/.julia/packages/Luxor/HNu4m/src/basics.jl:576 [inlined]
  [7] render_objects(objects::Vector{Javis.AbstractObject}, video::Video, frame::Int64; layer_frames::Nothing)
    @ Javis ~/.julia/packages/Javis/UaLm7/src/Javis.jl:415
  [8] render_objects
    @ ~/.julia/packages/Javis/UaLm7/src/Javis.jl:387 [inlined]
  [9] get_javis_frame(video::Video, objects::Vector{Javis.AbstractObject}, frame::Int64; layers::Vector{Javis.AbstractObject})
    @ Javis ~/.julia/packages/Javis/UaLm7/src/Javis.jl:609
 [10] render(video::Video; framerate::Int64, pathname::String, liveview::Bool, streamconfig::Nothing, tempdirectory::String, ffmpeg_loglevel::String, rescale_factor::Float64, postprocess_frames_flow::typeof(identity), postprocess_frame::typeof(Javis.default_postprocess))
    @ Javis ~/.julia/packages/Javis/UaLm7/src/Javis.jl:291
 [11] top-level scope
    @ REPL[79]:1

```

---

<div class="post-metadata">

**Author:** ![arbitrandomuser](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/arbitrandomuser/32/19374_2.png) [@arbitrandomuser](https://discourse.julialang.org/u/arbitrandomuser)\
**Post date:** [September 18, 2022, 7:30am UTC](https://discourse.julialang.org/t/javis-collision-detection/87398/6 "2022-09-18T07:30:40Z")

</div>

cormullion was just giving an example , but Javis objects dont have a pos field.  
the position of the object is obtained using the get\_position function on the object.  
while there is no “set\_position” the position is changed through the actions.

I think `anim_translate` is probably not the right function since it calculates the starting position and the ending position of the translation before the rendering starts . I dont know if there is a way currently to change the direction of the anim\_translate midway through the animation.

What you could try doing is , move every object by a small amount - frame by frame.  
every object can have a “velocity” the distance and direction it moves every frame.  
updatedirection! can then run through all pairs of objects detect collisions and change the “velocity”

You can hold velocity state in the `opts` field which is a dictionary

---

<div class="post-metadata">

**Author:** ![arbitrandomuser](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/arbitrandomuser/32/19374_2.png) [@arbitrandomuser](https://discourse.julialang.org/u/arbitrandomuser)\
**Post date:** [September 18, 2022, 8:20am UTC](https://discourse.julialang.org/t/javis-collision-detection/87398/7 "2022-09-18T08:20:42Z")

</div>

The following code only checks for collision with the vertical walls .

```julia
using Javis
video = Video(500,500)
nframes=250
Background(1:nframes, (v,o,f)-> background("white"))

obj = Object(1:nframes , (v,o,f)-> begin 
                    circle(O,50,:fill)
                    return O 
                end)
obj.opts[:velocity] = (10,1)

#not really an obj , as in draws nothing , but runs a function
updaterobj = Object(1:nframes , (v,o,f) -> begin
                        #hardcoded boundaries of the video
                        if !(-250+25 < get_position(obj).x < 250-25)
                            v = obj.opts[:velocity]
                            obj.opts[:velocity] = (-v[1],v[2]) 
                        end
                    end)

move() = (v,o,a,f)-> begin
    if f == 1
        #need this if since get_position doesnt work on frame 1
        translate(o.start_pos + o.opts[:velocity] )
    else
        translate(get_position(o) + o.opts[:velocity] )
    end
end

act!(obj , Action(1:nframes,move()))

render(video,pathname="vid.mp4")
run(`mpv vid.mp4`)

```

---

<div class="post-metadata">

**Author:** ![DoktorMike](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/doktormike/32/2736_2.png) [@DoktorMike](https://discourse.julialang.org/u/DoktorMike)\
**Post date:** [September 18, 2022, 8:32am UTC](https://discourse.julialang.org/t/javis-collision-detection/87398/8 "2022-09-18T08:32:09Z")

</div>

Wow great, that was really far away from what I was trying. Didn’t know that I could use the `opts` for state management. Thank you for this example it would have taken me forever to figure this out. 🤣

---

<div class="post-metadata">

**Author:** ![arbitrandomuser](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/arbitrandomuser/32/19374_2.png) [@arbitrandomuser](https://discourse.julialang.org/u/arbitrandomuser)\
**Post date:** [September 18, 2022, 8:32am UTC](https://discourse.julialang.org/t/javis-collision-detection/87398/9 "2022-09-18T08:32:41Z")

</div>

![vid](https://global.discourse-cdn.com/julialang/original/3X/4/b/4b2bc1d651fada4b0fb220fb40c78397d3590621.gif)

---

<div class="post-metadata">

**Author:** ![arbitrandomuser](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/arbitrandomuser/32/19374_2.png) [@arbitrandomuser](https://discourse.julialang.org/u/arbitrandomuser)\
**Post date:** [September 18, 2022, 8:38am UTC](https://discourse.julialang.org/t/javis-collision-detection/87398/10 "2022-09-18T08:38:18Z")

</div>

Discourse was bugged out a bit , couldnt upload the gif earlier ,

Anyway just be careful while using opts , its used internally in Javis for some purposes ,  
`opts[:result]` is one which i know is used .  
So dont use keys with those names. In the future if you want to be safe(er) give a prefix to your keys something like  
`pfx_keyname`

---

<div class="post-metadata">

**Author:** ![arbitrandomuser](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/arbitrandomuser/32/19374_2.png) [@arbitrandomuser](https://discourse.julialang.org/u/arbitrandomuser)\
**Post date:** [September 19, 2022, 1:47pm UTC](https://discourse.julialang.org/t/javis-collision-detection/87398/11 "2022-09-19T13:47:59Z")

</div>

@DoktorMike if you’re willing to , then do submit what you come up with for the example gallery on Javis.jl github repo .

> **[Javis.jl/examples at main · JuliaAnimators/Javis.jl](https://github.com/JuliaAnimators/Javis.jl/tree/main/examples)**
>
> main/examples

---

<div class="post-metadata">

**Author:** ![DoktorMike](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/doktormike/32/2736_2.png) [@DoktorMike](https://discourse.julialang.org/u/DoktorMike)\
**Post date:** [September 20, 2022, 1:30pm UTC](https://discourse.julialang.org/t/javis-collision-detection/87398/12 "2022-09-20T13:30:39Z")

</div>

@arbitrandomuser Done: [Added an example for entropy simulation. by DoktorMike · Pull Request #493 · JuliaAnimators/Javis.jl · GitHub](https://github.com/JuliaAnimators/Javis.jl/pull/493)
