diff --git a/src/Geometry/Primitives/NonCSG/ConvexPolygon.jl b/src/Geometry/Primitives/NonCSG/ConvexPolygon.jl index 0a7041b8d..cb9640e6a 100644 --- a/src/Geometry/Primitives/NonCSG/ConvexPolygon.jl +++ b/src/Geometry/Primitives/NonCSG/ConvexPolygon.jl @@ -38,7 +38,7 @@ struct ConvexPolygon{N,T<:Real} <: PlanarShape{T} ) where {T<:Real} # need at least 3 points to define apolygon - @assert length(local_polygon_points) > 3 + @assert length(local_polygon_points) >= 3 local_center = Statistics.mean(local_polygon_points) world_center = local2world(local_frame) * Vec3(local_center[1], local_center[2], zero(T)) diff --git a/src/Geometry/Primitives/NonCSG/Stop.jl b/src/Geometry/Primitives/NonCSG/Stop.jl index 84b98aec2..1918bca72 100644 --- a/src/Geometry/Primitives/NonCSG/Stop.jl +++ b/src/Geometry/Primitives/NonCSG/Stop.jl @@ -332,3 +332,29 @@ function makemesh(s::FiniteStop{T,RectangularStopShape,RectangularStopShape}, :: end makemesh(::InfiniteStop, ::Int = 0) = nothing + + +# ----------------------------------------------------- +# define the convex polygon stop shape +# ----------------------------------------------------- +struct InfiniteStopConvexPoly{N, T<:Real} <: OpticSim.StopSurface{T} + poly::ConvexPolygon{N,T} +end +export InfiniteStopConvexPoly + +function surfaceintersection(stop::InfiniteStopConvexPoly{N, T}, r::AbstractRay{T,3}) where {N, T<:Real} + interval = surfaceintersection(stop.poly.plane, r) + if interval isa EmptyInterval{T} # check if ray intersect with the polygon plane + return EmptyInterval(T) # no ray polygon intersection + else + if surfaceintersection(stop.poly, r) isa EmptyInterval{T} # check if ray intersects with the actual polygon + return interval # if ray do not intersect the polygon than we return the interval + else + return EmptyInterval(T) # otherwise we indicate no intersection + end + end +end + +interface(::InfiniteStopConvexPoly) = opaqueinterface(T) +centroid(r::InfiniteStopConvexPoly{N, T}) where {N, T<:Real} = r.plane.pointonplane +makemesh(::InfiniteStopConvexPoly, ::Int = 0) = nothing \ No newline at end of file diff --git a/test/Benchmarks/Benchmarks.jl b/test/Benchmarks/Benchmarks.jl index d9713a451..687dd79c3 100644 --- a/test/Benchmarks/Benchmarks.jl +++ b/test/Benchmarks/Benchmarks.jl @@ -47,12 +47,15 @@ sphere_inside() = surfaceintersection, (Sphere(0.5), Ray([0.0, 0.0, 0.0], [0.0, plane() = surfaceintersection, (Plane(0.0, 0.0, 1.0, 0.0, 0.0, 0.0), rayz()) rectangle() = surfaceintersection, (Rectangle(1.0, 1.0, SVector(0.0, 0.0, 1.0), SVector(0.0, 0.0, 0.0)), rayz()) ellipse() = surfaceintersection, (Ellipse(1.0, 1.0, SVector(0.0, 0.0, 1.0), SVector(0.0, 0.0, 0.0)), rayz()) +convexPolygon() = surfaceintersection, (ConvexPolygon(Geometry.Transform(), [SVector(-1.0, -1.0), SVector(1.0, -1.0), SVector(1.0, 1.0), SVector(-1.0, 1.0)]), rayz()) cylinder_parallel() = surfaceintersection, (Cylinder(1.0), rayz()) cylinder_perp() = surfaceintersection, (Cylinder(1.0), rayx()) bbox_parallel() = surfaceintersection, (BoundingBox(-1.0, 1.0, -1.0, 1.0, -5.0, 5.0), rayz()) bbox_perp() = surfaceintersection, (BoundingBox(-1.0, 1.0, -1.0, 1.0, -5.0, 5.0), rayx()) -simple_surface_benchmarks() = plane, rectangle, ellipse, triangle, sphere_outside, sphere_inside, sphericalcap, cylinder_parallel, cylinder_perp, bbox_parallel, bbox_perp +infiniteStopConvexPolygon() = surfaceintersection, (InfiniteStopConvexPoly(ConvexPolygon(Geometry.Transform(), [SVector(-1.0, -1.0), SVector(1.0, -1.0), SVector(1.0, 1.0), SVector(-1.0, 1.0)])), rayz()) + +simple_surface_benchmarks() = plane, rectangle, ellipse, convexPolygon, infiniteStopConvexPolygon, triangle, sphere_outside, sphere_inside, sphericalcap, cylinder_parallel, cylinder_perp, bbox_parallel, bbox_perp zernike_surface1() = surfaceintersection, (AcceleratedParametricSurface(TestData.zernikesurface1(), 30), perturbrayz()) zernike_surface2() = surfaceintersection, (AcceleratedParametricSurface(TestData.zernikesurface3(), 30), perturbrayz()) diff --git a/test/testsets/Intersection.jl b/test/testsets/Intersection.jl index f4dc12d9d..4198d3383 100644 --- a/test/testsets/Intersection.jl +++ b/test/testsets/Intersection.jl @@ -545,6 +545,25 @@ # outside finite r = Ray([0.9, 1.0, 1.9], [0.0, -1.0, 0.0]) @test surfaceintersection(annulus, r) isa EmptyInterval + + # polygon stop intesection + polygon_stop_frame = Transform() + polygon_stop_poly = ConvexPolygon(polygon_stop_frame, [SVector(0.0, 0.0), SVector(1.0, 0.0), SVector(0.5, 0.5)], opaqueinterface(Float64)) + polygon_stop = InfiniteStopConvexPoly(polygon_stop_poly) + + # through polygon which should lead to non intersection + r = Ray([0.2, 0.1, 1.0], [0.0, 0.0, -1.0]) + @test surfaceintersection(polygon_stop, r) isa EmptyInterval + # not through the polygon + r = Ray([-0.2, 0.2, 1.0], [0.0, 0.0, -1.0]) + res = surfaceintersection(polygon_stop, r) + @test OpticSim.lower(surfaceintersection(polygon_stop, r)).point == SVector(-0.2, 0.2, 0.0) + + # parallel to the polygon's plane + r = Ray([0.0, 0.0, 1.0], [1.0, 0.0, 0.0]) + @test surfaceintersection(polygon_stop, r) isa EmptyInterval + + end # testset Stops @testset "Bezier" begin