-
Notifications
You must be signed in to change notification settings - Fork 36
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support tori with partial θ
ranges in Geant4 extension
#459
Conversation
In an `AbstractConstructiveGeometry`, if the volume `A` has no volume, the overall `origin` and `rotation` should correspond to those of volume `B` (not `A`).
parse_origin
and parse_rotation
in Geant4 extensionθ
ranges in Geant4 extension
function _rectangle_point(x::T)::Tuple{T,T} where {T <: Real} | ||
return ( | ||
clamp(tand(abs(mod(x-90,360)-180)-90),-1,1), | ||
clamp(tand(abs(mod( x,360)-180)-90),-1,1) | ||
) | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some back info: For tori with partial θ
ranges, I intersect a full torus with a PolyCone
.
The function _rectangle_point
returns a point on a rectangle at a given θ
(in degrees):
using SolidStateDetectors
using Geant4
using Plots
const G4 = Base.get_extension(SolidStateDetectors, :SolidStateDetectorsGeant4Ext)
base_plot = plot([1,1,-1,-1,1],[1,-1,-1,1,1], color = :black, ratio = 1, size = (400,400), label = "", xlims = (-2,2), ylims = (-2,2))
@gif for x in 0:5.:360-5
p = G4._rectangle_point(x)
plot(deepcopy(base_plot))
scatter!([p[1]], [p[2]], label = "", color = :black)
end
points = Tuple{T,T}[(zero(T), zero(T))] | ||
push!(points, _rectangle_point(theta2)) | ||
tmp::T = theta2 - mod(theta2 - 45, 90) | ||
while theta1 < tmp && tmp > 0 | ||
push!(points, _rectangle_point(tmp)) | ||
tmp -= 90 | ||
end | ||
push!(points, _rectangle_point(theta1)) | ||
push!(points, (zero(T), zero(T))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can use this to create a shape that spans over a rectangle with given theta1
and theta2
:
T = Float64
# generate random values for theta1 and theta2
theta2 = 360 * rand(T)
theta1 = theta2 * rand(T)
points = Tuple{T,T}[(zero(T), zero(T))]
push!(points, G4._rectangle_point(theta2))
tmp::T = theta2 - mod(theta2 - 45, 90)
while theta1 < tmp && tmp > 0
push!(points, G4._rectangle_point(tmp))
tmp -= 90
end
push!(points, G4._rectangle_point(theta1))
push!(points, (zero(T), zero(T)))
plot(deepcopy(base_plot), legend = :topleft)
plot!(getindex.(points,1), getindex.(points,2), color = :red, lw = 2, label = "θ1 = $(theta1),\nθ2 = $(theta2)")
Polycone( | ||
r = getindex.(points,1) .* rmax .+ e.r_torus, | ||
z = getindex.(points,2) .* rmax, | ||
origin = e.origin, | ||
rotation = e.rotation | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
... to then intersect the full-θ
Torus
with the newly defined Polycone
Looks perfect to me. Tested and good to go from my side! |
In an
AbstractConstructiveGeometry
, if the volumeA
has no volume, the overallorigin
androtation
should correspond to those of volumeB
(notA
).This fixes the issue reported in #457, where parts of boolean volumes were placed at the wrong position when the first volume was flagged as
has_volume == false
.