7

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

stenci
  • 8,290
  • 14
  • 64
  • 104

2 Answers2

11

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).

Joe Kington
  • 275,208
  • 71
  • 604
  • 463
  • It would have been slow if I did it my way, with python cycles. Using numpy will be much faster. (Well, I haven't tested it, but it's my assumption based on the little I know about numpy). Thanks! – stenci Jun 10 '15 at 18:59
  • I did some tests, and it turns out that the speed of using numpy arrays and python lists is about the same. Lists are 50% faster with smaller datasets, numpy arrays are 20% faster with larger datasets. – stenci Jun 16 '15 at 22:14
  • 1
    @stenci - Just for what it's worth, that 20%/50% difference will vary _a lot_ with how large your datasets are and how you're using numpy (e.g. `y = x * 5` will be much faster than `y = [i * 5 for i in x]`, and that 20% will become more like 20x or 2000x for large datasets). Numpy arrays are a very different data structure than a list (very memory-efficient, but fixed size: no appending). If you're only dealing with a few hundred items at most in a sequence, numpy is overkill. If you're dealing with a few billion, it's the only option. – Joe Kington Jun 16 '15 at 22:25
  • I imagined that was the case when I saw you using 1000 points in your example. My arcs will have between 3 and 300 segments, and using numpy only to create an array that will be lost just after feeding it to `LineString` is overkill. I used your example to borrow the `linspace` (which is faster than my old loop) and to start exploring numpy. – stenci Jun 16 '15 at 22:37
  • how would one use this solution with geographic rather than cartesian coordinates? I'm looking for a Python equivalent of [Turf JS's sector](https://turfjs.org/docs/#sector) – Martim Passos Sep 21 '20 at 13:56
  • @MartimPassos You should create a new question. If you want put a link to this one. Nobody will answer to you here in the comments. – stenci Sep 21 '20 at 15:18
1

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

Community
  • 1
  • 1
Alex Ivanov
  • 695
  • 4
  • 6