# Rayons.jl : shortest optical path in 2D

**URL:** https://discourse.julialang.org/t/rayons-jl-shortest-optical-path-in-2d/95502
**Category:** Package Announcements
**Tags:** announcement, physics
**Created:** [March 3, 2023, 3:07pm UTC](https://discourse.julialang.org/t/rayons-jl-shortest-optical-path-in-2d/95502 "2023-03-03T15:07:14Z")
**Posts on this page:** 1
**Page:** 1

<div class="post-metadata">

### Author: ![LaurentPlagne](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/laurentplagne/32/10103_2.png) [@LaurentPlagne](https://discourse.julialang.org/u/LaurentPlagne)
#### Post date: [March 3, 2023, 3:07pm UTC](https://discourse.julialang.org/t/rayons-jl-shortest-optical-path-in-2d/95502/1 "2023-03-03T15:07:14Z")

</div>

Hi, I have made `Rayons.jl` public on github (not registered):

> **[GitHub - triscale-innov/Rayons.jl](https://github.com/triscale-innov/Rayons.jl)**
>
> Contribute to triscale-innov/Rayons.jl development by creating an account on GitHub.

It was very fun and easy to develop with Julia and I guess that it would have been more difficult to implement efficiently with Python or Matlab (please prove me wrong).

This project simulates **optical rays** interacting with a 2D geometry composed of a set of rectangles with different optical velocities.

**Minimal travel times** from a given **source** to a set of **sensors** are computed.

The ray interacting with a (plane) boundary is split into two sub-rays (reflected and refracted) via the following recursive function :

```julia
function recursive_generate_rays_fluid!(reduce_ray!, state,celerity_domain, idx, time,
                        u::Point, pstart::Point, np::NumericalParameters, depth, power)
    c₁,_,ρ₁ = cl_ct_rho(state)
    u=normalize(u)
    pend, pnext,uθ,state,next_state = advance_ds(pstart, u, np, state,celerity_domain)
    c₂,_,ρ₂ = cl_ct_rho(next_state)

    Δt = norm(pend - pstart) / c₁   
    time += Δt
    
    reduce_ray!(pstart, pend, c₁, time, idx,power)
    
    if depth <= np.maxdepth && time <= np.tmax && power>np.power_threshold

        uθr = maybeuθr(uθ, c₁, c₂) # refracted angle θr from incident angle θ      
        r,t = isnothing(uθr) ? (1.0,0.0) : rtpower_coeffs_fluid_fluid(uθr, uθ, c₁, c₂, ρ₁, ρ₂)
        # reflection αf(α,θ,θ) = π + α - θ - θᵣ 
        recursive_generate_rays_fluid!(reduce_ray!, state,celerity_domain, 2idx, time,
                                                uαf(u,uθ,uθ), pend, np, depth+1, r*power) 
        # refraction α + θᵣ - θ
        !isnothing(uθr) && 
        recursive_generate_rays_fluid!(reduce_ray!, next_state,celerity_domain, 2idx+1, time,
                                                uαr(u,uθ,uθr), pnext, np, depth+1, t*power)
    end
end

```

Note how different reduction functions (reduce\_ray!) can be passed to the recursive function. In particular, we can pass a function computing the minimal arrival time of a given ray into each cell of a 2D Cartesian grid.

![](https://global.discourse-cdn.com/julialang/original/3X/0/d/0d5c9fc919a680f6782129fee4a1a7d84d36fd1e.gif)
