Ethan Gonzaga
Ethan Gonzaga

Reputation: 21

Return a Boolean if Line intersects a Polygon

How can I have my list of lines return a list of booleans when they intersect a polygon, and as a result, don't show lines that return a True value?

Currently my code draws a line from the origin (0,0) to all the points on the XY cartesian plane. I want to be able to have the lines that intersect with a polygon return a boolean value. This will hopefully allow me to not display lines that return a True value.

i.e. IF Lineintersection == True: Don't display Line ELSE: Display Line

origin = [0,0]
import numpy as np
import matplotlib.pyplot as plt
from shapely.geometry import LineString
from shapely.geometry import Point, Polygon
import descartes

quality = 7
x = np.linspace(-1,1,quality)
y = np.linspace(-1,1,quality)
X,Y = np.meshgrid(x,y)
polycoords = [[-1, 1], [-1, 0.5], [0, 0.5], [0, 1]]
clip_poly = shapely.geometry.Polygon(polycoords)

positions = np.vstack([Y.ravel(), X.ravel()])

#plt.scatter(*positions[::-1])

fig = plt.figure()
ax = fig.add_subplot(111)

for i in range(len(positions)):
    for j in range(len(positions[i])):
        plt.scatter(*positions[::-1])
        x1 = positions[0][j]
        y1 = positions[1][j]
        line = LineString([origin, (x1, y1)])
        x2, y2 = line.xy
        lines = plt.plot(0, 0, x2, y2, color='green', linewidth=1, solid_capstyle='round')
        polygon = Polygon(polycoords)
        polygonbuilding = ax.add_patch(descartes.PolygonPatch(clip_poly, fc='pink', alpha=0.3))
plt.show()

Result from above code

Upvotes: 2

Views: 576

Answers (1)

mgc
mgc

Reputation: 5443

I guess that you can simplify your code by removing the polygon creation from the two for loops, for example by creating the polygon before creating the lines (also, note that your are creating it two times in your original code, once in the clip_poly variable and once ine the polygon variable).

Then you will be able to call the intersects method of the geometry objets your are handling (here polygon and line).

I simplified your two for loop in one loop, unpacking directly the x1 and y1 coordinates (and I also moved the plt.scatter call outside of the loop):

import numpy as np
import matplotlib.pyplot as plt
from shapely.geometry import LineString
from shapely.geometry import Point, Polygon
import descartes

origin = [0,0]
quality = 7
x = np.linspace(-1,1,quality)
y = np.linspace(-1,1,quality)
X,Y = np.meshgrid(x,y)
polycoords = [[-1, 1], [-1, 0.5], [0, 0.5], [0, 1]]
positions = np.vstack([Y.ravel(), X.ravel()])

fig = plt.figure()
ax = fig.add_subplot(111)

polygon = Polygon(polycoords)
polygonbuilding = ax.add_patch(
    descartes.PolygonPatch(polygon, fc='pink', alpha=0.3))
plt.scatter(*positions[::-1])
    
for x1, y1 in positions.T:
    line = LineString([origin, (x1, y1)])
    if not polygon.intersects(line):  # <- the condition you were looking for
        x2, y2 = line.xy
        plt.plot(0, 0, x2, y2, color='green', linewidth=1, solid_capstyle='round')

plt.show()

ResultPlot

Upvotes: 1

Related Questions