|
1 | 1 | export Obstacle, Disk, Antidot, RandomDisk, Wall, Circular,
|
2 | 2 | InfiniteWall, PeriodicWall, RandomWall, SplitterWall, FiniteWall,
|
3 |
| -Semicircle, Ellipse |
| 3 | +FiniteSplitterWall, Semicircle, Ellipse |
4 | 4 | export translate
|
5 | 5 |
|
6 | 6 | using InteractiveUtils
|
@@ -314,6 +314,52 @@ function SplitterWall(sp::AbstractVector, ep::AbstractVector,
|
314 | 314 | end
|
315 | 315 | SplitterWall(sp, ep, n, name::String = "Splitter wall") =
|
316 | 316 | SplitterWall(sp, ep, n, true, name)
|
| 317 | + |
| 318 | +""" |
| 319 | + FiniteSplitterWall{T<:AbstractFloat} <: Wall{T} |
| 320 | +Finite wall obstacle allowing fow ray-splitting (mutable type). |
| 321 | +### Fields: |
| 322 | +* `sp::SVector{2,T}` : Starting point of the Wall. |
| 323 | +* `ep::SVector{2,T}` : Ending point of the Wall. |
| 324 | +* `normal::SVector{2,T}` : Normal vector to the wall, pointing to where the |
| 325 | + particle *will come from before a collision* (pointing towards the inside of the |
| 326 | + billiard). The size of the vector is irrelevant |
| 327 | + since it is internally normalized. |
| 328 | +* `isdoor::Bool` : Flag of whether this `FiniteSplitterWall` instance is a "Door". |
| 329 | + Defaults to `false`. |
| 330 | +* `pflag::Bool` : Flag that keeps track of where the particle is currently |
| 331 | + propagating (`pflag` = propagation flag). |
| 332 | + `true` is associated with the `normal` vector the wall is |
| 333 | + instantiated with. Defaults to `true`. |
| 334 | +* `name::String` : Name of the obstacle, given for user convenience. |
| 335 | + Defaults to "Finite Splitter Wall". |
| 336 | +""" |
| 337 | +mutable struct FiniteSplitterWall{T<:AbstractFloat} <: Wall{T} |
| 338 | + sp::SVector{2,T} |
| 339 | + ep::SVector{2,T} |
| 340 | + normal::SVector{2,T} |
| 341 | + width::T |
| 342 | + center::SVector{2,T} |
| 343 | + isdoor::Bool |
| 344 | + pflag::Bool |
| 345 | + name::String |
| 346 | +end |
| 347 | +function FiniteSplitterWall(sp::AbstractVector, ep::AbstractVector, |
| 348 | + n::AbstractVector, isdoor::Bool = false, pflag::Bool = true, name::String = "Finite Splitter Wall") |
| 349 | + T = eltype(sp) |
| 350 | + n = normalize(n) |
| 351 | + d = dot(n, ep-sp) |
| 352 | + if abs(d) > 10eps(T) |
| 353 | + error("Normal vector is not actually normal to the wall: dot = $d") |
| 354 | + end |
| 355 | + T = eltype(sp) <: Integer ? Float64 : eltype(sp) |
| 356 | + w = norm(ep - sp) |
| 357 | + center = @. (ep+sp)/2 |
| 358 | + return FiniteSplitterWall{T}(SVector{2,T}(sp), SVector{2,T}(ep), SVector{2,T}(n), |
| 359 | + w, SVector{2,T}(center), isdoor, pflag, name) |
| 360 | +end |
| 361 | +FiniteSplitterWall(a, b, c, n::String) = FiniteSplitterWall(a, b, c, false, true, n) |
| 362 | + |
317 | 363 | #pretty print:
|
318 | 364 | show(io::IO, w::Wall{T}) where {T} = print(io, "$(w.name) {$T}\n",
|
319 | 365 | "start point: $(w.sp)\nend point: $(w.ep)\nnormal vector: $(w.normal)")
|
@@ -410,6 +456,7 @@ assumed to be very close to the obstacle's boundary).
|
410 | 456 | @inline normalvec(wall::Wall, pos) = wall.normal
|
411 | 457 | @inline normalvec(w::PeriodicWall, pos) = normalize(w.normal)
|
412 | 458 | @inline normalvec(w::SplitterWall, pos) = w.pflag ? w.normal : -w.normal
|
| 459 | +@inline normalvec(w::FiniteSplitterWall, pos) = w.pflag ? w.normal : -w.normal |
413 | 460 | @inline normalvec(disk::Circular, pos) = normalize(pos - disk.c)
|
414 | 461 | @inline normalvec(a::Antidot, pos) =
|
415 | 462 | a.pflag ? normalize(pos - a.c) : -normalize(pos - a.c)
|
@@ -494,11 +541,11 @@ function distance(pos::SV, e::Ellipse{T})::T where {T}
|
494 | 541 | end
|
495 | 542 |
|
496 | 543 | # The entire functionality of `distance_init` is necessary only for
|
497 |
| -# FiniteWall !!! |
| 544 | +# FiniteWall and FiniteSplitterWall !!! |
498 | 545 | distance_init(p::AbstractParticle, a::Obstacle) = distance_init(p.pos, a)
|
499 | 546 | distance_init(pos::SVector, a::Obstacle) = distance(pos, a)
|
500 | 547 |
|
501 |
| -function distance_init(pos::SVector{2,T}, w::FiniteWall{T})::T where {T} |
| 548 | +function distance_init(pos::SVector{2,T}, w::Union{FiniteWall{T}, FiniteSplitterWall{T}})::T where {T} |
502 | 549 |
|
503 | 550 | n = normalvec(w, pos)
|
504 | 551 | posdot = dot(w.sp .- pos, n)
|
|
0 commit comments