Holes in polygons

139 views
Skip to first unread message

Marco

unread,
May 5, 2018, 1:27:14 PM5/5/18
to vispy
Hi,
is it possible to draw a polygon with holes?

I can't find in docs nor in examples.
Thanks for help.

Marco

David Hoese

unread,
May 6, 2018, 10:26:56 AM5/6/18
to vispy
Hi Marco,

It depends what you mean by holes. I'm guessing you mean that you can see through the polygon at certain locations. That is, polygon holes inside the larger polygon.

This is not currently supported out of the box as far as I know. If you can figure out how to describe this situation in generic terms (polygons, transparency, etc) without OpenGL and define your restrictions maybe we can figure out the best way to accomplish this. For example, if this feature did exist already how would you expect to use it?

You will likely have to make your own Visual object with your own shader or combine multiple visuals. If you think about it you can make one polygon and put other polygons inside it, but you won't be able to make them transparent all the way through the larger polygon. You could also make your own shader and make the alpha of the polygon dependent on the location in the polygon. You have a couple options, but it really depends exactly what you are trying to do. Regardless, there is nothing in vispy currently that I know of that will do this out of the box.

Dave

Marco

unread,
May 6, 2018, 1:50:46 PM5/6/18
to vispy

Thanks.
Yes, an exterior polygon and one or more interior polygons. You can see trough the hole.
Target example:

To do this I thought something like in Matplotlib.


Vispy can do this polygon:



Note: external path is clockwise, internal path counterclockwise.

If the first and the last point of exterior collapsed, and the same for the interior, I expected a similar triangulation:



Here a snippet:

import sys
import numpy as np
from vispy import app
from vispy.scene import SceneCanvas
from vispy.scene.visuals import Polygon

canvas
= SceneCanvas(keys='interactive', show=True)
v
= canvas.central_widget.add_view()
v
.bgcolor = "gray"
v
.camera = 'panzoom'

poly_coords
= np.array([[0.0, 0.0], [0.0, 1.0], [1.0, 0.0], [0.0, 0.0],
                       
[0.1, 0.1], [0.3, 0.1], [0.1, 0.3], [0.1, 0.1]])

poly
= Polygon(poly_coords, color="red", parent=v.scene)

if __name__ == '__main__':
   
if sys.flags.interactive != 1:
        app
.run()

But it does't work.


Marco

David Hoese

unread,
May 6, 2018, 6:21:30 PM5/6/18
to vispy
Thanks for the example. As far as I can tell this is an issue with the triangulation algorithm or a lack of features on the PolygonVisual. Really it's that the PolygonVisual is not meant to handle this case. If you look at the source code for the PolygonVisual you'll see it is just a MeshVisual with a LineVisual wrapped around it. The PolygonVisual is just using the `PolygonData` class which is using the `vispy.geometry.triangulation.Triangulation` class to do the calculations for converting your polygon vertices to a series of triangles to pass to the MeshVisual. I tried subclassing the polygon and hacking the `_update` method to pass my own vertices and edges to the Triangulation calculations but couldn't get anything to work. I tried making up the triangles myself and pass them directly to MeshVisual but it made my head hurt so I gave up although this should theoretically work.

Note there are some pull requests that I hope to merge for vispy 0.6 that might make the MeshVisual (vertices, faces, edges, etc) easier to use. That said, I think you currently have all the building blocks to solve this problem it just isn't simple or builtin. If you are able to accomplish this I would appreciate a pull request to add this kind of functionality even if it is just a new example showing how you do it.

Sorry I couldn't help more. Maybe someone else has an idea on how to do this.

Dave

Luke Campagnola

unread,
May 15, 2018, 6:30:33 PM5/15/18
to Vispy list
You're on the right path--triangulation does support holes, but PolygonData and PolygonVisual were not built to handle this possibility. I have opened a PR (#1481) that makes this a bit easier; works like this:

    poly_coords = np.array([
        [0.0, 0.0], [0.0, 1.0], [1.0, 0.0],
        [0.1, 0.1], [0.3, 0.1], [0.1, 0.3],
    ])

    poly_edges = np.array([
        [0, 1], [1, 2], [2, 0],
        [3, 4], [4, 5], [5, 3],
    ])

    pdata = PolygonData(poly_coords, poly_edges)
    poly = Polygon(polygon_data=pdata, color="red", border_color='white', parent=v.scene)


--
You received this message because you are subscribed to the Google Groups "vispy" group.
To unsubscribe from this group and stop receiving emails from it, send an email to vispy+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply all
Reply to author
Forward
0 new messages