Nice!
> At some point I realized that Point-Point edges although lines, (i.e.
> machinable with a single G1 move in the XY-plane), in fact for V-carving
> must be 'interpolated' using many small line-segments because the
> Z-coordinate (clearance-disk radius) does not increase/decrease linearly
> along this type of edge. This is now fixed:
> https://github.com/aewallin/openvoronoi/commit/bac7060c1608b09ba484716e728fc51a18c2679a
I've been meaning to dig in the source code (or simply ask) to answer
the question: given a medial-axis segment and a desired clearance
radius, how can we tell whether and where there's a point on the
segment having the clearance radius?
> I also found a problem in MedialAxisWalk, the class that walks along the
> medial-axis to produce a toolpath. It looks for a "dangling" edge where we
> can start the toolpath. These are edges where one end of the edge is of
> degree one, i.e. no other edges connect to the endpoint. This works OK for
> fonts/shapes with sharp corners, since these have many of these
> start-edges.
> But for example "O" will produce a closed oval-loop as the medial-axis with
> no "dangling"-edges where we naturally would start the toolpath. In this
> case we just need to start one suitable start edge. For example one that has
> a small clearance-disk (so that we initially do not have to plunge very deep
> into the material).
I wonder whether there is such a thing as a "spiral plunge" that is
like a helical plunge: find a medial axis point with large clearance,
start a spiral near the edge of this point's clearance disc, and
descend to target depth as we spiral inward toward this point.
> Another issue is ordering of the toolpaths. Currently the tool "jumps
> around" a lot and does unnecessary rapid-traverses. This might be modeled as
> an asymmetric-TSP?
Um. I think that means "traveling salesman"...
Congratulations on V-carving!
-- KN
vertices hold the clearance-disk radius as a property. You can query it with:
double my_radius = g[src].dist();
This assumes you have for example:
Edge e;
Vertex src = g.source(e);
The clearance-disk radius will increase/decrease monotonically from
the source to the target on each edge. To get a point along the edge
you call:
Point p = g[e].point( t ); // t is the clerance-disk radius
If you grok this then you can state truths like this: (might not be a
good idea in practice because of roundoff errors):
assert( g[src].position == g[e].point( g[src].dist() ) );
assert( g[trg].position == g[e].point( g[trg].dist() ) );
The naming of variables and functions isn't very consistent. Held uses
"t" for the offset-distance in the edge-parametrization, but then
clearance-disk-radius or "rho" in many other places. "dist" isn't
particularly good...
Note that for parabolic edges and for LINE edges you will not get
evenly spaced points in the xy-plane if you ask for them in an evenly
spaced interval in [ g[src].dist(), g[trg].dist() ] !
>> But for example "O" will produce a closed oval-loop as the medial-axis with
>> no "dangling"-edges where we naturally would start the toolpath. In this
>> case we just need to start one suitable start edge. For example one that has
>> a small clearance-disk (so that we initially do not have to plunge very deep
>> into the material).
>
> I wonder whether there is such a thing as a "spiral plunge" that is
> like a helical plunge: find a medial axis point with large clearance,
> start a spiral near the edge of this point's clearance disc, and
> descend to target depth as we spiral inward toward this point.
Yes. What you describe is very doable for a general pocketing
operation. The medial-axis will give points inside the polygon that
are as far as possible from the boundary of the polygon. That might be
a good place to start a spiral-pocketing path, and it can be started
at a medial-axis vertex. There is no input geometry within the
clearance-disk.
>> Another issue is ordering of the toolpaths. Currently the tool "jumps
>> around" a lot and does unnecessary rapid-traverses. This might be modeled as
>> an asymmetric-TSP?
>
> Um. I think that means "traveling salesman"...
Yes. The symmetric TSP is well-studied and there is a lot of code
floating around. But I'm looking for something slightly different,
using TSP-terminology we would have special 'cities' (start-points of
toolpaths) where if one enters this city one must follow a path
through a number of predefined cities (the toolpath) and a choice for
the next city is only allowed at the next special city (the end-point
of the toolpath). I'm not sure if this explanation makes any sense, or
if it can be used to run normal TSP-code for our case.
Anders
class path{
double entry[2],exit[2];
bool reverse
}
optimize(vector<path> &p) //or list
while(cnt<p.size()*p.size()*20)
{
choose random subpath of random length
choose ifto reverse orientation of all the subpaths segments.
choose random position where to move the subpath to in the rest of the
path.
q= create new path with this random change.
if(sum(travelingmoves) of q < old sum of traveling moves)
replace p with q.
}
apply reverse directions to all segments;
}
The p.size^2 runtime is not ideal, for smaller problems it was ok
however (e.g. euro sized voronoi pcb) . A clock-time based limit might
be better. Then, small problems might be close to a perfect solution,
and big problems are just a bit optimized, however, they are still
better than the original approach.
The actual code is here:
https://github.com/bkubicek/pcb2gcode/blob/master/geometry.cpp
DxfNgc_Layer::optiPaths
very nice greetings,
Bernhard