Open jiangzhouq opened 2 years ago
I'm not sure I understand what you mean. Do you mean this?
I'm not sure I understand what you mean. Do you mean this?
yes , man!can vpype do this job? I read the guide and didn’t find.
No, there is no such feature for the time being. It would make for a great addition and/or plug-in though!
Thx for reply!
We can keep his open for records. It's a good feature request.
Hi guys, that really sounds like a cool feature to implement. Furthermore this excellent Stack Overflow post describes the geometry of the problem at hand very well. I just have a concrete implementation question at hand: should I simply add a "rounder_corners" method to the LineCollection class? Effectively this method would create out of two LineStrings two shortened LineStrings and one LinearRing.
@dev-89 Thanks for reaching out!
I wouldn't cut/merge paths with this feature (where "path", in vpype, is always a line string – technically a numpy array of complex – where the last point might be identical to the first if it's closes). So the function would take a path, and return another path with its angle rounded (based on a radius and some quantisation control parameter).
I would first create a function to operate on a single path (typically in vpype/geometry.py
). I'd skip adding a member in LineCollection
and just create a roundcorner
command in vpype_cli
(maybe in vpype_cli/operations.py
).
Right, I think I understand now. Will get coding in the coming days and any further questions we can discuss over the PR.
There's other more simple methods of doing this. You're focusing on just replacing the corner with an arc. But really you can just segmentize the segments. Apply smooth (#216) repeatedly. Then simplify the segments.
smooth
repeatedly where we find all 3 points in series, and we move the middle point towards the midpoint of the first and last point. amount * (p1 - p2) + p2
linesimplify
in that we delete all points won't deviate a line by more than 1% (for example). It's basically simplify but for angles and not distance.And most of these things are already there and can be applied pretty easy. We only really need as many segments as we're applying the smooth. So if we apply smooth 10 times only the 10 closest points could be affected. You can also segment just part of a line nearest to the sharp corner, or some distance along that line (sort of radius)).
Keep in mind a strong point of this proposed algorithm is the use of numpy. You can apply this to line segments really easily with the code you already have without bunch of other libraries.
The segmentize
is easy. It's linear interpolation between the two complex points.
Smooth
is a little bit more complex, but follows pretty nicely (spitballing).
midpoint = (line[2:] + line[:-2]) / 2.0
middlepoint = line[1:-1]
line[1:-1] = amount * (midpoint - middlepoint) + middlepoint)
The simplify
isn't too bad. Again spitballing.
first = line[2:]
mid = line[1:-1]
last = line[:-2]
x1 = np.real(first)
y1 = np.real(first)
x2 = np.real(mid)
y2 = np.real(mid)
x3 = x2
y3 = y2
x4 = np.real(last)
y4 = np.real(last)
denom = (y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1)
Then delete the points where abs(denom) < 1e-3
or whatever. At 0
the lines are straight. It's used more often to find intersections and at 0
lines are parallel but here since p2 == p3 they are just connected there.
So all straight forward with the code you have currently.
When I use a knife to cut, the sharp corners are not handled very well, easy to lift,