It looks like you're new here. If you want to get involved, click one of these buttons!
Hello, I am looking for a function that returns true if a given point is inside a function.
The following function returns true if a point lies inside a polygon (specified by layer and a cell).
However I don't want to use this method because I don't want to iterate over all the shapes.
Is there a simpler way of finding if a point is inside or outside (touching or not touching) a specified layer.
iter = pya.RecursiveShapeIterator.new(layout, cell, layer_index)
specified_region = iter.shape().polygon
is_point_inside = specified_region.inside(pya.Point(x, y))
Thanks for the help!
Comments
Perhaps you could use
Layout.begin_shapes_touching. You would need to make aRegionout of your point.@jheinsoo You're right. Confining the search does the trick.
But you do not necessarily need a Region. Iterating probably won't hurt if you confine the search to a small area around the test point. This will return only those polygons whose bounding boxes already contain the point:
I think this is the most efficient way to do the test.
Matthias
I want to read out the layers, which are present for a given layout coordinate, given by a selected ruler. So I tried the approach above:
But I get the following error message:
The first parameter should be a layout, not a layoutview; and the second should be a cell, not a cellview. Try using
pya.RecursiveShapeIterator(ly, cv.cell, li, test_box, True)insteadWow, thank you, taylorn, for your fast response, which was completey correct! It works now without the error message, but the output is empty. How should the report look like, if an overlap of test_box and shape is detected by RecursiveShapeIterator?
No problem!
Nothing is inherently displayed; all you've done is construct the iterator. Try calling
iter.at_end(). If it's true, there is no shape; if it's false, there is a shape. You can use that boolean to continue as you wish.Ok, but how can I get the layer indexes, where a shape exists, which overlaps with the test_box? For me, it is unclear, what the iterator contains exactly.
The iterator is a RecursiveShapeIterator that contains, iterates over, all shapes in the cell on the layer index you provided.
iter.at_end()detects whether there are no more shapes. If it's false, there is a shape that overlaps the box. If it's true, there isn't a shape.So to get the layer indices that have a shape, when you're iterating
liover all layer indices, just keep the ones whereiter.at_end()returns false.Hope this helps!
Yes, thanks. Now I understand the structure. But when I read out iter.at_end(), I always get back False, even if I use RecursiveShapeIterator in a confined box, where no shapes are present on any layer. It seems, that the box confinement does not work for me, as I can read out shapes outside the box on the same layer with iter.shape(). I would expect, that RecursiveShapeIterator looks for shapes in the region only, which is specified by test_box.
One trouble might be that
a.p1is a DPoint, not a Point. The difference is that the DPoint's coordinates are multiplied by the layout's database unit. Essentially there's a mismatch between the DPoint coordinates and the coordinates the Box wants to use, which ARE the integer coordinates.Try using
a.p1.to_itype(ly.dbu)in place ofa.p1, and similarly fora.p2.Thanks, that worked. Now I still have the problem, that RecursiveShapeIterator seems to check on bounding boxes rather than shape geometry, so I get a False also, when I put my test_box inside a shape with a hole. Is there a method to check on shape area rather than shape bounding box?
That's a trouble that RecursiveShapeIterator has, that Matthias has addressed here. You can either check against the specific polygon the iterator delivers, or you can convert the whole layer into a region and call
.interacting().@taylorn, thanks for chiming in
You're right, the RecursiveShapeIterator first of all finds shapes whose bounding box is touching the given search box. That is a first level of identification.
Once you have a shape and you know it is a polygon (or you convert it to one), you can test if a given point is inside the polygon using
Polygon#inside(https://www.klayout.de/doc-qt5/code/class_Polygon.html#method50).Note that the polygon may come from a subhierarchy, so you have to transform it into the top cell first, or you do the opposite with the point (disclaimer: not tested):
Matthias