Skip to content

Instantly share code, notes, and snippets.

@troyswanson
Created November 2, 2022 20:43
Show Gist options
  • Save troyswanson/735985f34a7c8d74d8fb3407b2e04fb4 to your computer and use it in GitHub Desktop.
Save troyswanson/735985f34a7c8d74d8fb3407b2e04fb4 to your computer and use it in GitHub Desktop.
Geometry Utility Functions
import math
from shapely.geometry import Point, LineString, Polygon, MultiPolygon
def create_rectangle(x, y, width, depth, angle):
width_theta = math.radians(angle)
width_x = width * math.cos(width_theta)
width_y = width * math.sin(width_theta)
depth_theta = math.radians(angle + 90)
depth_x = depth * math.cos(depth_theta)
depth_y = depth * math.sin(depth_theta)
x0 = x
y0 = y
x1 = x + width_x
y1 = y + width_y
x2 = x + width_x + depth_x
y2 = y + width_y + depth_y
x3 = x + depth_x
y3 = y + depth_y
poly = Polygon([(x0, y0), (x1, y1), (x2, y2), (x3, y3)])
return poly
def create_point(x, y, angle, distance):
t = math.radians(angle)
new_x = x + distance * math.cos(t)
new_y = y + distance * math.sin(t)
return Point(new_x, new_y)
def find_angle(a, b, c):
# c | / a
# | /
# | /
# b |/
ba = (a.y - b.y, a.x - b.x)
bc = (c.y - b.y, c.x - b.x)
ang = math.degrees(math.atan2(bc[0], bc[1]) - math.atan2(ba[0], ba[1]))
ang = ang + 360 if ang < 0 else ang
return ang
def xy(ring):
r_xs, r_ys = list(), list()
for pt in ring.coords:
r_xs.append(pt[0])
r_ys.append(pt[1])
return r_xs, r_ys
def linestring_list_xy(lines):
l_xs, l_ys = list(), list()
for line in lines:
xs, ys = xy(line)
l_xs.append(xs)
l_ys.append(ys)
return l_xs, l_ys
def polygon_xy(poly):
p_xs, p_ys = list(), list()
x, y = xy(poly.exterior)
p_xs.append(x)
p_ys.append(y)
for hole in poly.interiors:
x, y = xy(hole)
p_xs.append(x)
p_ys.append(y)
return p_xs, p_ys
def multipolygon_xy(geom):
mp_xs, mp_ys = list(), list()
mp = MultiPolygon([geom]) if type(geom) == Polygon else geom
for poly in mp.geoms:
p_xs, p_ys = polygon_xy(poly)
mp_xs.append(p_xs)
mp_ys.append(p_ys)
return mp_xs, mp_ys
def multipolygon_list_xy(geoms):
xs, ys = list(), list()
for geom in geoms:
mp_xs, mp_ys = multipolygon_xy(geom)
xs.append(mp_xs)
ys.append(mp_ys)
return xs, ys
def point_list_xy(points):
x, y = list(), list()
for pt in points:
x.append(pt.x)
y.append(pt.y)
return x, y
def create_slice_line(x, y, width, depth, angle, slices):
buf_dist = 1
slices = round(slices)
s = create_point(x, y, angle - 90, buf_dist)
pts = list()
for i in range(slices - 1):
p0 = pts[(i * 2) - 1] if len(pts) else s
p1 = create_point(p0.x, p0.y, angle, width / slices)
p2 = create_point(p1.x, p1.y, angle + (-90 if i % 2 else 90), depth + buf_dist * 2)
pts.extend([p1, p2])
l = LineString([(pt.x, pt.y) for pt in pts])
return l
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment