Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create polygons with arcs in shapely (or a better library)

Tags:

python

shapely

I am trying to use shapely to identify the area used by a shape and the area used by the tools that will cut it on a CNC router. The shape is imported from a dxf drawing using ezdxf.

The tool paths can be either rectangles (if they are cut by a saw disk that follows a straight line) or a set of segments (if they are routed by a milling bit). In both cases I can use a LineString.buffer() to automatically create the offsets and find the area used by the tool.

I am using shapely because I think it is the best tool available to find out if shapes overlap each other (using union() to merge all the tools into one shape and overlaps() to find the interference). Please let me know if there is a better tool for this purpose.

buffer() does a good job at creating segments to represent arcs on the corners.

Is there a way to create the segments to represent arcs on the shape itself?

For example, how do I create the arc on the left of this shape? Do I need to create my own (slow) python function? Or is there an optimized shapely way?

Green is the part, yellow are the saw disk cuts, magenta are the milling bit cuts

like image 201
stenci Avatar asked Jun 10 '15 16:06

stenci


People also ask

How do you convert LineString to polygons?

geometry. Polygon to simply convert to line string to a polygon. It will connect the first and last coordinates. Try Polygon([(0, 0), (1, 1), (1, 2), (0, 1)]) or Polygon(s1) to produce POLYGON ((0 0, 1 1, 1 2, 0 1, 0 0)).

Is Point in polygon shapely?

There are basically two ways of conducting Point in Polygon queries in Shapely: using a function called . within() that checks if a point is within a polygon. using a function called .

What is Unary_union?

unary_union[source] Returns a geometry containing the union of all geometries in the GeoSeries .

What is LineString in Python?

A LineString has zero area and non-zero length. >>> from shapely.geometry import LineString >>> line = LineString([(0, 0), (1, 1)]) >>> line. area 0.0 >>> line. length 1.4142135623730951. Its x-y bounding box is a (minx, miny, maxx, maxy) tuple.


2 Answers

Creating your own way of making the arc in python isn't necessarily slow. Numpy is excellent for operations along these lines, and shapely is deliberately intended to interoperate well with numpy.

For example,

import numpy as np
import shapely.geometry as geom

# Define the arc (presumably ezdxf uses a similar convention)
centerx, centery = 3, 4
radius = 2
start_angle, end_angle = 30, 56 # In degrees
numsegments = 1000

# The coordinates of the arc
theta = np.radians(np.linspace(start_angle, end_angle, numsegments))
x = centerx + radius * np.cos(theta)
y = centery + radius * np.sin(theta)

arc = geom.LineString(np.column_stack([x, y]))

Approximating the arc with 1000 points between the start and end angles takes ~3 milliseconds on my machine (that's including converting it to a shapely LineString).

like image 180
Joe Kington Avatar answered Oct 31 '22 22:10

Joe Kington


I've never used shapely but I know some vector graphics principles. Overlays are usually extracted with the "difference". If you take the difference of the polygons out of the union the remaineder will be your arc. https://gis.stackexchange.com/questions/11987/polygon-overlay-with-shapely

like image 1
Alex Ivanov Avatar answered Oct 31 '22 21:10

Alex Ivanov