How to create a streamplot only inside a polygon?

Say I got a triangle defined by

using CairoMakie, GeometryBasics, DelaunayTriangulation

P =  [(-1,0),(1,0),(0,1),(-1,0)]

Now let’s triangulate the triangle to get equal points (x,y) indside

boundary_nodes, points = convert_boundary_points_to_indices(P)

tri = DelaunayTriangulation.triangulate(points)

refine!(tri; max_area=1e-2get_total_area(tri))


pts = [Point(val[1], val[2]) for val in tri.points]
fcs = [TriangleFace(val[1], val[2], val[3]) for val in tri.triangles]


msh = GeometryBasics.Mesh(pts, fcs)


x = [val[1] for val in tri.points]

y = [val[2] for val in tri.points]

Finally let’s just define a test-function f that assigns a value based on the point (x,y)

f(x,y) = Point2f(x,y)

After all If I run

streamplot(f, x, y)

I get streamlines also outside of the triangle even if x and y are points only from the inside.

Is there a way to restrict the lines so that they don’t reach outside? This would help me tremendously with my project. Cheers!

Well…you can’t really restrict the lines easily, but what you can do is plot a white polygon with a triangular hole over the plot.

Consider something like:

fx(x,y) = Point2f(x,y)
f, a, p = streamplot(fx, -1..1, 0..1)
tri = Point2f[(-1,0),(1,0),(0,1),(-1,0)]
out = Rect(-5, -5, 10, 10)
mask_poly = Makie.GeometryBasics.Polygon(
           Makie.convert_arguments(Makie.PointBased(), out)[1], # convert the rectangle to a vector of points
           [tri]
 )
poly!(a, mask_poly; color = :white, xautolimits = false, yautolimits = false) # so that the mask does not interfere with the limits

translate!(a.scene, 0, 0, -100) # move the plots below the grid so the grid is seen!
f

Unfortunately Discourse isn’t letting me upload an image, but this worked sufficiently on my machine!

1 Like

Alright thank you :smile: This may be the easiest solution. Modifying the streamplot-code so that it adapt to boundaries might take way too much effort.