Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/documentation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
- uses: actions/checkout@v4
- uses: julia-actions/setup-julia@v2
with:
version: '1.9'
version: '1.10'
- uses: julia-actions/cache@v2
- name: Install dependencies
run: julia --project=docs/ -e 'using Pkg; Pkg.develop(PackageSpec(path=pwd())); Pkg.instantiate()'
Expand Down
6 changes: 6 additions & 0 deletions docs/Project.toml
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
[deps]
BenchmarkTools = "6e4b80f9-dd63-53aa-95a3-0cdb28fa8baf"
CairoMakie = "13f3f980-e62b-5c42-98c6-ff1f3baf88f0"
Colors = "5ae59095-9a9b-59fe-a467-6f913c188581"
Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f"
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
MeshIntegrals = "dadec2fd-bbe0-4da4-9dbe-476c782c8e47"
Meshes = "eacbb407-ea5a-433e-ab97-5258b1ca43fa"
Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d"

[compat]
BenchmarkTools = "1"
CairoMakie = "0.15"
Colors = "0.13"
Distributions = "0.25"
Documenter = "1"
Meshes = "0.53, 0.54"
Unitful = "1.19"
Expand Down
3 changes: 3 additions & 0 deletions docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ makedocs(
"Support Status" => "support.md",
"Tips" => "tips.md"
],
"Examples" => [
"Darts Strategy Analysis" => "examples/darts.md"
],
"Developer Notes" => [
"Changelog" => "developer/CHANGELOG.md",
"How it Works" => "developer/how_it_works.md",
Expand Down
138 changes: 138 additions & 0 deletions docs/src/examples/darts.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
# Darts (Draft)

Steps
- Construct a set of geometries representing a dartboard with individual sector scores
- Develop a model of the dart trajectory with probability density distribution
- Use integration over each geometry to determine the probabilities of particular outcomes
- Calculate expected value for the throw, repeat for other distributions to compare strategies

```@example darts
using CairoMakie
using Colors
using Distributions
using Meshes
using MeshIntegrals
using Unitful
using Unitful.DefaultSymbols: mm, m

red = colorant"red"
black = colorant"black"
white = colorant"white"
green = colorant"green"

# For containing any scored landing region on the dart board
struct ScoredRegion{G, C}
geometry::G
points::Int64
color::C
end

# For defining an annular region
struct Sector{L, A}
r_inner::L
r_outer::L
phi_a::A
phi_b::A
end
Sector(rs, phis) = Sector(rs..., phis...)

# Sector -> Ngon
function Ngon(sector::Sector; N=8)
ϕs = range(sector.phi_a, sector.phi_b, length=N)
arc_o = [point(sector.r_outer, ϕ) for ϕ in ϕs]
arc_i = [point(sector.r_inner, ϕ) for ϕ in reverse(ϕs)]
return Meshes.Ngon(arc_o..., arc_i...)
end

function _Point3f(p::Meshes.Point)
x, y, z = ustrip.(m, [p.coords.x, p.coords.y, p.coords.z])
return Point3f(x, y, z)
end

_poly(circle::Meshes.Circle; N=32) = [(_Point3f(circle(t)) for t in range(0, 1, length=N))...]
_poly(ngon::Meshes.Ngon) = [(_Point3f(pt) for pt in ngon.vertices)...]
```

## Modeling the Dartboard

Model the dartboard
```@example darts
dartboard_center = Meshes.Point(0m, 0m, 1.5m)
dartboard_plane = Plane(dartboard_center, Meshes.Vec(1, 0, 0))

function point(r::Unitful.Length, ϕ)
t = ustrip(m, r)
dartboard_plane(t * sin(ϕ), t * cos(ϕ))
end

# Scores on the Board
ring1 = [20, 1, 18, 4, 13, 6, 10, 15, 2, 17, 3, 19, 7, 16, 8, 11, 14, 9, 12, 5]
ring2 = 3 .* ring1
ring3 = ring1
ring4 = 2 .* ring1
board_points = hcat(ring1, ring2, ring3, ring4)

# Colors on the board
ring1 = repeat([black, white], 10)
ring2 = repeat([red, green], 10)
ring3 = ring1
ring4 = ring2
board_colors = hcat(ring1, ring2, ring3, ring4)

# Sector geometries
sector_width = 2π/20
phis_a = range(0, 2π, 20) .- sector_width/2
phis_b = range(0, 2π, 20) .+ sector_width/2
phis = Iterators.zip(phis_a, phis_b)
rs = [ (16mm, 99mm), (99mm, 107mm), (107mm, 162mm), (162mm, 170mm) ]
board_coords = Iterators.product(phis, rs)
board_sectors = map(((phis, rs),) -> Sector(rs, phis), board_coords)
board_ngons = Ngon.(board_sectors)

# Consolidate the Sectors
sector_data = Iterators.zip(board_ngons, board_points, board_colors)
board_regions = map(args -> ScoredRegion(args...), sector_data)

# Center region
bullseye_inner = ScoredRegion(Meshes.Circle(dartboard_plane, 6.35mm), 50, red)
bullseye_outer = ScoredRegion(Ngon(Sector((6.35mm, 16.0mm), (0.0, 2π)); N=32), 25, green)

# Get set of all regions
all_regions = vcat(vec(board_regions), bullseye_inner, bullseye_outer)

# Initialize a 3D figure
fig = Figure()
#ax = LScene(fig[1, 1], scenekw=(show_axis=true,))
ax = Axis3(fig[1, 1]; xlabel="X", ylabel="Y", zlabel="Z")
limits!(ax, -0.1..0.1, -1.5..1.5, 0..3; fixed=true)

# Populate the dart board scored regions
for region in all_regions
poly!(ax, _poly(region.geometry), color=region.color)
end

fig
```

## Modeling the Dart Trajectory

Define a probability distribution for where the dart will land
```
# TODO
dist = MvNormal(μs, σs)
```

Integrand function is the distribution's PDF value at any particular point
```
# TODO
function integrand(p::Point)
v_error = dist_center - p
pdf(dist, v_error)
end
```

Example image of trajectory probability distribution on board

## Strategy Evaluation

Use these tools to evaluate different aiming/throwing parameters and their impact on expected scores.
Loading