# cut a polygon with a polyline (not the contrary)

Attention Topic was automatically imported from the old Question2Answer platform.
Asked By Sylvain22

Hi,

I looked for some existing code in Geomery to cut my polygon with the player’s tail in a Qix / Gals panic like game I’m working on:

But as far I understand there’s no such method exposed.

So I coded my own:

`start_edge` and `end_edge` are index of the point in the polygon representing the playground (white square on the screenshot above). In this case `start_edge` = 2, `end_edge` = 1

`PolygonIterator` is a class with a little magic for looping on the edge in the polygon array of point, which on a given size known when to go through the end of the Array and restart at the beginning.

``````func cut(tail, start_edge, end_edge):
var pol1 : Array = tail.points

# process of linking the 2 polygons:
# pol1
# 1. all the tail points
# 2. the area points from where the tail ends in clockwise order throught
#    where the tail starts

if is_on_corner(pol1[0], start_edge):
start_edge = prev_corner(start_edge)

if is_on_corner(pol1[-1], end_edge):
end_edge = next_corner(end_edge)

var iter = PolygonIterator.new(pol.polygon.size(), end_edge, start_edge)
print(iter)

for i in iter:
print("cut: add point %d" % i)
pol1.append(pol.polygon[i])

var polys = Geometry.clip_polygons_2d(pol.polygon, pol1)
print("cliped: %d" % len(polys))
return [ pol1, polys[0] ]
``````

ThePolygonIterator class code:

``````class_name PolygonIterator
# this iterator loop over start to the end to cover all points
# excluding  start, including  end

var start
var current
var end
var count = 0
var size
var counter = 0

func _init(size, start, stop):
self.size = size
self.start = start
self.current = start
if stop < size:
self.end = stop
else:
self.end = size - 1

if start < end:
count = end - start
elif start == end:
count = 0
else:
count = end + (size - start)

func should_continue():
return counter > 0

func init_count():
counter = count

func _iter_init(arg):
init_count()
current = next_val(start)
return should_continue()

func next_val(val):
return (val + 1 + size) % size

func _iter_next(arg):
counter -= 1
current = next_val(current)
return should_continue()

func _iter_get(arg):
return current

func _to_string():
return "iter: (%d) start %d end %d count %d" % [ size, start, end, count ]
``````

So I first complete my Polyline (`tail`) with some polygon’s point in order to have a polygon, and then I subtract it to the playground’s polygon with `clip_polygons_2d()`.

Is there better way to perform it?

Regards,
Sylvain.

Reply From: Xrayez

There’s no such method exposed because the underlying library for polygon clipping in Godot (Clipper) doesn’t support such operation.

You can in theory simulate this by using `Geometry.offset_polyline_2d` with a very small `delta`, which will grow your polyline into a thin polygon, and then do the clipping between polygons. Or, you can generate two rectangles along with a polyline (if it’s a straight line), and do `Geometry.intersect_polygons_2d` two times against your subject polygon on the both side of the polyline.