Arrangements and Visibility¶
[1]:
from skgeom import *
In this chapter we create a 2D arrangement, and explore how to use it in order to compute the visibility from different positions inside this arrangement.
A 2D arrangement consists of vertices, segments, and faces.
We can use the insert
, and insert_point
function on the arrangement to insert new points into it.
Then, the arrangement can be queried or iterated upon by using either the find
function or the iterators.
[2]:
M = 10
outer = [
Segment2(Point2(-M, -M), Point2(-M, M)), Segment2(Point2(-M, M), Point2(M, M)),
Segment2(Point2(M, M), Point2(M, -M)), Segment2(Point2(M, -M), Point2(-M, -M))
]
segments = [
Segment2(Point2(0, 0), Point2(0, 4)), Segment2(Point2(2, 4), Point2(8, 4)),
Segment2(Point2(3, 4), Point2(-8, 0)), Segment2(Point2(1, 0), Point2(0, 5)),
]
arr = arrangement.Arrangement()
for s in outer:
arr.insert(s)
for s in segments:
arr.insert(s)
Now the arrangement can be iterated upon with the halfedges
iterator property. Note that the segments that have been inserted are split at their intersections.
[3]:
for he in arr.halfedges:
draw.draw(he.curve())
Finding things in the arrangement¶
We can find the face associated with a certain point in the arrangement, and use the outer_ccb
circulator to iterate over the halfedges associated with the face.
[4]:
q = Point2(-2.5, 5)
face = arr.find(q)
[5]:
i = face.outer_ccb
first = next(i)
halfedge = next(i)
[6]:
while first != halfedge:
print(halfedge.source().point(), halfedge.target().point())
halfedge = next(i)
print(halfedge.source().point(), halfedge.target().point())
PointC2(10, 10) PointC2(-10, 10)
PointC2(-10, 10) PointC2(-10, -10)
PointC2(-10, -10) PointC2(10, -10)
PointC2(10, -10) PointC2(10, 10)
Similarly, if we query a point that is lying on a halfedge, or a vertex itself we get either a halfedge or a vertex in return.
[7]:
vertex = arr.find(Point2(0, 0))
[8]:
vertex
[8]:
<skgeom._skgeom.arrangement.Vertex at 0x7f41aa4a3d88>
Computing Visibility¶
We can use the RotationalSweepVisibility
class to compute the visibility from a specific point inside the arrangement.
[9]:
vs = RotationalSweepVisibility(arr)
[10]:
q = Point2(-2.5, 5)
face = arr.find(q)
vx = vs.compute_visibility(q, face)
[11]:
for he in arr.halfedges:
draw.draw(he.curve(), visible_point=False)
for v in vx.halfedges:
draw.draw(v.curve(), color='red', visible_point=False)
draw.draw(q, color='magenta')
An additional, faster method to compute the visibility is also available, the TriangularExpansionVisibility
. However, the TriangularExpansionVisibility
requires a one-time initialization cost to be paid. You can read more about both algorithms here: https://doc.cgal.org/latest/Visibility_2/index.html
[12]:
ts = RotationalSweepVisibility(arr)
tx = ts.compute_visibility(q, face)
[13]:
for he in arr.halfedges:
draw.draw(he.curve(), visible_point=False)
for v in tx.halfedges:
draw.draw(v.curve(), color='red', visible_point=False)
draw.draw(q, color='magenta')
[ ]: