discuss@lists.openscad.org

OpenSCAD general discussion Mailing-list

View all threads

Adding a border of d thickness to a polygon

O
otto
Thu, Nov 24, 2016 8:29 PM

On Wed, 23 Nov 2016 20:38:02 -0500
Marius Kintel marius@kintel.net wrote:

On Nov 23, 2016, at 09:41, otto otto@123phase.com wrote:

Another way to achieve this is with the 2-D minkowski which is
moderately efficient.

Note that 2D minkowski is equivalent to 2D offset with a radius, but
2D offset should be considerably faster.

-Marius

Testing the code shows no difference in speed.  The test code is
below.  Make sure to clear the cache!  div should be a power of 2.
Incidentally, as div gets large both versions show they same failure
artifacts.  I think that the offset module is simply a wrapper around
the minkowski.  In this program they seem to behave
identically to the agree that they have the same identical timed speed
and with the same identical artifacts.  Is there a known algorithm that
can calculate the offset faster than a minkowski algorithm or
that doesn't use the minkowski or some equivalent?

Regards
Otto

function heartRadius(t) = (1.5 - 1.5* sin(t) + (sin(t) *
(sqrt(abs(cos(t)))/(sin(t)+1.6))));
$fn=23;
div=512;  //ONLY USE POWERS OF 2

module pHeart(xy,off=0) {

td = 1/div; // theta delta - the resolution of the curve

// Calculate x/y co-ords separetely so I can scale correctly later
xp = [ for (t = [0: td : 360-td]) heartRadius(t) * cos(t) ]; // xco-ordinates on the curve
yp = [ for (t = [0 : td : 360-td]) heartRadius(t) * sin(t) ]; // yco-ordinates on the curve

xsc = xy/(max(xp) - min(xp)); // x scaler to get to fit expected size
ysc = xy/(max(yp) - min(yp)); // y scaler to get to fit expected size

// Generate a vector of points for the polygon to work
p = [ for (i = [0 : 360/td-1]) [xsc*xp[i], ysc*yp[i]] ];

// translate polygon so it is centralised at +/- xy/2	
translate([0,ysc*(-max(yp)+(max(yp)-min(yp))/2)])

//// UNCOMMENT LINE TO TEST
//// CLEAR THE CACHE FIRST

///////////////////////  MINKOWSKY
//if(off){minkowski(){polygon(p);circle(off);}}else polygon(p);
///////////////////////  OFFSET
//offset(r=off) polygon(p);

}

difference()
{
linear_extrude(5) pHeart(xy=78,off=2);
translate([0,0,-.5]) linear_extrude(6) pHeart(xy=78, off=.4);
}

On Wed, 23 Nov 2016 20:38:02 -0500 Marius Kintel <marius@kintel.net> wrote: > > On Nov 23, 2016, at 09:41, otto <otto@123phase.com> wrote: > > > > Another way to achieve this is with the 2-D minkowski which is > > moderately efficient. > > Note that 2D minkowski is equivalent to 2D offset with a radius, but > 2D offset should be considerably faster. > > -Marius Testing the code shows no difference in speed. The test code is below. Make sure to clear the cache! div should be a power of 2. Incidentally, as div gets large both versions show they same failure artifacts. I think that the offset module is simply a wrapper around the minkowski. In this program they seem to behave identically to the agree that they have the same identical timed speed and with the same identical artifacts. Is there a known algorithm that can calculate the offset faster than a minkowski algorithm or that doesn't use the minkowski or some equivalent? Regards Otto function heartRadius(t) = (1.5 - 1.5* sin(t) + (sin(t) * (sqrt(abs(cos(t)))/(sin(t)+1.6)))); $fn=23; div=512; //ONLY USE POWERS OF 2 module pHeart(xy,off=0) { td = 1/div; // theta delta - the resolution of the curve // Calculate x/y co-ords separetely so I can scale correctly later xp = [ for (t = [0: td : 360-td]) heartRadius(t) * cos(t) ]; // xco-ordinates on the curve yp = [ for (t = [0 : td : 360-td]) heartRadius(t) * sin(t) ]; // yco-ordinates on the curve xsc = xy/(max(xp) - min(xp)); // x scaler to get to fit expected size ysc = xy/(max(yp) - min(yp)); // y scaler to get to fit expected size // Generate a vector of points for the polygon to work p = [ for (i = [0 : 360/td-1]) [xsc*xp[i], ysc*yp[i]] ]; // translate polygon so it is centralised at +/- xy/2 translate([0,ysc*(-max(yp)+(max(yp)-min(yp))/2)]) //// UNCOMMENT LINE TO TEST //// CLEAR THE CACHE FIRST /////////////////////// MINKOWSKY //if(off){minkowski(){polygon(p);circle(off);}}else polygon(p); /////////////////////// OFFSET //offset(r=off) polygon(p); } difference() { linear_extrude(5) pHeart(xy=78,off=2); translate([0,0,-.5]) linear_extrude(6) pHeart(xy=78, off=.4); } > > _______________________________________________ > OpenSCAD mailing list > Discuss@lists.openscad.org > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
NH
nop head
Fri, Nov 25, 2016 10:53 AM

I might be wrong but I think OpenSCAD uses the clipper library for offset
and presumably CGAL for 2D Minkowski.

The artefacts from low div values come from the polygon generation, not the
offsetting, so it is no surprise they look identical. Provided clipper
obeys $fn they should produce the same results as they are mathematically
identical operations. There is no ambiguity where each vertex should be, so
any differences should only be down to the different number representations.

I am surprised there is little difference in speed but both are very fast
until you get to tens of thousands of vertices.

BTW rather than linear extruding twice and subtracting 3D shapes I think it
is more efficient to subtract the 2D shapes and extrude that.

linear_extrude(5, convexity = 2)
difference() {
pHeart(xy = 78, off = 2);
pHeart(xy = 78, off = 0.4);
}

On 24 November 2016 at 20:29, otto otto@123phase.com wrote:

On Wed, 23 Nov 2016 20:38:02 -0500
Marius Kintel marius@kintel.net wrote:

On Nov 23, 2016, at 09:41, otto otto@123phase.com wrote:

Another way to achieve this is with the 2-D minkowski which is
moderately efficient.

Note that 2D minkowski is equivalent to 2D offset with a radius, but
2D offset should be considerably faster.

-Marius

Testing the code shows no difference in speed.  The test code is
below.  Make sure to clear the cache!  div should be a power of 2.
Incidentally, as div gets large both versions show they same failure
artifacts.  I think that the offset module is simply a wrapper around
the minkowski.  In this program they seem to behave
identically to the agree that they have the same identical timed speed
and with the same identical artifacts.  Is there a known algorithm that
can calculate the offset faster than a minkowski algorithm or
that doesn't use the minkowski or some equivalent?

Regards
Otto

function heartRadius(t) = (1.5 - 1.5* sin(t) + (sin(t) *
(sqrt(abs(cos(t)))/(sin(t)+1.6))));
$fn=23;
div=512;  //ONLY USE POWERS OF 2

module pHeart(xy,off=0) {

     td = 1/div; // theta delta - the resolution of the curve

     // Calculate x/y co-ords separetely so I can scale correctly later
     xp = [ for (t = [0: td : 360-td]) heartRadius(t) * cos(t) ]; //

xco-ordinates on the curve
yp = [ for (t = [0 : td : 360-td]) heartRadius(t) * sin(t) ]; //
yco-ordinates on the curve

     xsc = xy/(max(xp) - min(xp)); // x scaler to get to fit expected

size
ysc = xy/(max(yp) - min(yp)); // y scaler to get to fit expected
size

     // Generate a vector of points for the polygon to work
     p = [ for (i = [0 : 360/td-1]) [xsc*xp[i], ysc*yp[i]] ];

     // translate polygon so it is centralised at +/- xy/2
     translate([0,ysc*(-max(yp)+(max(yp)-min(yp))/2)])

 //// UNCOMMENT LINE TO TEST
 //// CLEAR THE CACHE FIRST

 ///////////////////////  MINKOWSKY
 //if(off){minkowski(){polygon(p);circle(off);}}else polygon(p);
 ///////////////////////  OFFSET
 //offset(r=off) polygon(p);

}

difference()
{
linear_extrude(5) pHeart(xy=78,off=2);
translate([0,0,-.5]) linear_extrude(6) pHeart(xy=78, off=.4);
}

I might be wrong but I think OpenSCAD uses the clipper library for offset and presumably CGAL for 2D Minkowski. The artefacts from low div values come from the polygon generation, not the offsetting, so it is no surprise they look identical. Provided clipper obeys $fn they should produce the same results as they are mathematically identical operations. There is no ambiguity where each vertex should be, so any differences should only be down to the different number representations. I am surprised there is little difference in speed but both are very fast until you get to tens of thousands of vertices. BTW rather than linear extruding twice and subtracting 3D shapes I think it is more efficient to subtract the 2D shapes and extrude that. linear_extrude(5, convexity = 2) difference() { pHeart(xy = 78, off = 2); pHeart(xy = 78, off = 0.4); } On 24 November 2016 at 20:29, otto <otto@123phase.com> wrote: > > > > > > On Wed, 23 Nov 2016 20:38:02 -0500 > Marius Kintel <marius@kintel.net> wrote: > > > > On Nov 23, 2016, at 09:41, otto <otto@123phase.com> wrote: > > > > > > Another way to achieve this is with the 2-D minkowski which is > > > moderately efficient. > > > > Note that 2D minkowski is equivalent to 2D offset with a radius, but > > 2D offset should be considerably faster. > > > > -Marius > > Testing the code shows no difference in speed. The test code is > below. Make sure to clear the cache! div should be a power of 2. > Incidentally, as div gets large both versions show they same failure > artifacts. I think that the offset module is simply a wrapper around > the minkowski. In this program they seem to behave > identically to the agree that they have the same identical timed speed > and with the same identical artifacts. Is there a known algorithm that > can calculate the offset faster than a minkowski algorithm or > that doesn't use the minkowski or some equivalent? > > Regards > Otto > > function heartRadius(t) = (1.5 - 1.5* sin(t) + (sin(t) * > (sqrt(abs(cos(t)))/(sin(t)+1.6)))); > $fn=23; > div=512; //ONLY USE POWERS OF 2 > > module pHeart(xy,off=0) { > > td = 1/div; // theta delta - the resolution of the curve > > // Calculate x/y co-ords separetely so I can scale correctly later > xp = [ for (t = [0: td : 360-td]) heartRadius(t) * cos(t) ]; // > xco-ordinates on the curve > yp = [ for (t = [0 : td : 360-td]) heartRadius(t) * sin(t) ]; // > yco-ordinates on the curve > > xsc = xy/(max(xp) - min(xp)); // x scaler to get to fit expected > size > ysc = xy/(max(yp) - min(yp)); // y scaler to get to fit expected > size > > // Generate a vector of points for the polygon to work > p = [ for (i = [0 : 360/td-1]) [xsc*xp[i], ysc*yp[i]] ]; > > // translate polygon so it is centralised at +/- xy/2 > translate([0,ysc*(-max(yp)+(max(yp)-min(yp))/2)]) > > //// UNCOMMENT LINE TO TEST > //// CLEAR THE CACHE FIRST > > /////////////////////// MINKOWSKY > //if(off){minkowski(){polygon(p);circle(off);}}else polygon(p); > /////////////////////// OFFSET > //offset(r=off) polygon(p); > > } > > difference() > { > linear_extrude(5) pHeart(xy=78,off=2); > translate([0,0,-.5]) linear_extrude(6) pHeart(xy=78, off=.4); > } > > > > > > > > _______________________________________________ > > OpenSCAD mailing list > > Discuss@lists.openscad.org > > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org > > > _______________________________________________ > OpenSCAD mailing list > Discuss@lists.openscad.org > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >
MK
Marius Kintel
Fri, Nov 25, 2016 3:07 PM

On Nov 25, 2016, at 05:53, nop head nop.head@gmail.com wrote:

I might be wrong but I think OpenSCAD uses the clipper library for offset and presumably CGAL for 2D Minkowski.

We use the clipper library for both offset and 2D minkowski. Perhaps they implement offset using minkowski internally?

-Marius

> On Nov 25, 2016, at 05:53, nop head <nop.head@gmail.com> wrote: > > I might be wrong but I think OpenSCAD uses the clipper library for offset and presumably CGAL for 2D Minkowski. > We use the clipper library for both offset and 2D minkowski. Perhaps they implement offset using minkowski internally? -Marius
NH
nop head
Fri, Nov 25, 2016 3:30 PM

I didn't realise clipper did Minkowski. A quick look at the code reveals
they don't use Minkowski for offset. Minkowski is just the union of a
polygon shifted by each point in a path. Offset is a lot more complex.

On 25 November 2016 at 15:07, Marius Kintel marius@kintel.net wrote:

On Nov 25, 2016, at 05:53, nop head nop.head@gmail.com wrote:

I might be wrong but I think OpenSCAD uses the clipper library for

offset and presumably CGAL for 2D Minkowski.

We use the clipper library for both offset and 2D minkowski. Perhaps they
implement offset using minkowski internally?

-Marius


OpenSCAD mailing list
Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org

I didn't realise clipper did Minkowski. A quick look at the code reveals they don't use Minkowski for offset. Minkowski is just the union of a polygon shifted by each point in a path. Offset is a lot more complex. On 25 November 2016 at 15:07, Marius Kintel <marius@kintel.net> wrote: > > On Nov 25, 2016, at 05:53, nop head <nop.head@gmail.com> wrote: > > > > I might be wrong but I think OpenSCAD uses the clipper library for > offset and presumably CGAL for 2D Minkowski. > > > We use the clipper library for both offset and 2D minkowski. Perhaps they > implement offset using minkowski internally? > > -Marius > > > _______________________________________________ > OpenSCAD mailing list > Discuss@lists.openscad.org > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >
O
otto
Fri, Nov 25, 2016 6:11 PM

I agree.

Otto

On Fri, 25 Nov 2016 10:53:27 +0000
nop head nop.head@gmail.com wrote:

I might be wrong but I think OpenSCAD uses the clipper library for
offset and presumably CGAL for 2D Minkowski.

The artefacts from low div values come from the polygon generation,
not the offsetting, so it is no surprise they look identical.
Provided clipper obeys $fn they should produce the same results as
they are mathematically identical operations. There is no ambiguity
where each vertex should be, so any differences should only be down
to the different number representations.

I am surprised there is little difference in speed but both are very
fast until you get to tens of thousands of vertices.

BTW rather than linear extruding twice and subtracting 3D shapes I
think it is more efficient to subtract the 2D shapes and extrude that.

linear_extrude(5, convexity = 2)
difference() {
pHeart(xy = 78, off = 2);
pHeart(xy = 78, off = 0.4);
}

On 24 November 2016 at 20:29, otto otto@123phase.com wrote:

On Wed, 23 Nov 2016 20:38:02 -0500
Marius Kintel marius@kintel.net wrote:

On Nov 23, 2016, at 09:41, otto otto@123phase.com wrote:

Another way to achieve this is with the 2-D minkowski which is
moderately efficient.

Note that 2D minkowski is equivalent to 2D offset with a radius,
but 2D offset should be considerably faster.

-Marius

Testing the code shows no difference in speed.  The test code is
below.  Make sure to clear the cache!  div should be a power of 2.
Incidentally, as div gets large both versions show they same failure
artifacts.  I think that the offset module is simply a wrapper
around the minkowski.  In this program they seem to behave
identically to the agree that they have the same identical timed
speed and with the same identical artifacts.  Is there a known
algorithm that can calculate the offset faster than a minkowski
algorithm or that doesn't use the minkowski or some equivalent?

Regards
Otto

function heartRadius(t) = (1.5 - 1.5* sin(t) + (sin(t) *
(sqrt(abs(cos(t)))/(sin(t)+1.6))));
$fn=23;
div=512;  //ONLY USE POWERS OF 2

module pHeart(xy,off=0) {

     td = 1/div; // theta delta - the resolution of the curve

     // Calculate x/y co-ords separetely so I can scale

correctly later xp = [ for (t = [0: td : 360-td]) heartRadius(t) *
cos(t) ]; // xco-ordinates on the curve
yp = [ for (t = [0 : td : 360-td]) heartRadius(t) * sin(t)
]; // yco-ordinates on the curve

     xsc = xy/(max(xp) - min(xp)); // x scaler to get to fit

expected size
ysc = xy/(max(yp) - min(yp)); // y scaler to get to fit
expected size

     // Generate a vector of points for the polygon to work
     p = [ for (i = [0 : 360/td-1]) [xsc*xp[i], ysc*yp[i]] ];

     // translate polygon so it is centralised at +/- xy/2
     translate([0,ysc*(-max(yp)+(max(yp)-min(yp))/2)])

 //// UNCOMMENT LINE TO TEST
 //// CLEAR THE CACHE FIRST

 ///////////////////////  MINKOWSKY
 //if(off){minkowski(){polygon(p);circle(off);}}else polygon(p);
 ///////////////////////  OFFSET
 //offset(r=off) polygon(p);

}

difference()
{
linear_extrude(5) pHeart(xy=78,off=2);
translate([0,0,-.5]) linear_extrude(6) pHeart(xy=78, off=.4);
}

I agree. Otto On Fri, 25 Nov 2016 10:53:27 +0000 nop head <nop.head@gmail.com> wrote: > I might be wrong but I think OpenSCAD uses the clipper library for > offset and presumably CGAL for 2D Minkowski. > > The artefacts from low div values come from the polygon generation, > not the offsetting, so it is no surprise they look identical. > Provided clipper obeys $fn they should produce the same results as > they are mathematically identical operations. There is no ambiguity > where each vertex should be, so any differences should only be down > to the different number representations. > > I am surprised there is little difference in speed but both are very > fast until you get to tens of thousands of vertices. > > BTW rather than linear extruding twice and subtracting 3D shapes I > think it is more efficient to subtract the 2D shapes and extrude that. > > linear_extrude(5, convexity = 2) > difference() { > pHeart(xy = 78, off = 2); > pHeart(xy = 78, off = 0.4); > } > > > On 24 November 2016 at 20:29, otto <otto@123phase.com> wrote: > > > > > > > > > > > > > On Wed, 23 Nov 2016 20:38:02 -0500 > > Marius Kintel <marius@kintel.net> wrote: > > > > > > On Nov 23, 2016, at 09:41, otto <otto@123phase.com> wrote: > > > > > > > > Another way to achieve this is with the 2-D minkowski which is > > > > moderately efficient. > > > > > > Note that 2D minkowski is equivalent to 2D offset with a radius, > > > but 2D offset should be considerably faster. > > > > > > -Marius > > > > Testing the code shows no difference in speed. The test code is > > below. Make sure to clear the cache! div should be a power of 2. > > Incidentally, as div gets large both versions show they same failure > > artifacts. I think that the offset module is simply a wrapper > > around the minkowski. In this program they seem to behave > > identically to the agree that they have the same identical timed > > speed and with the same identical artifacts. Is there a known > > algorithm that can calculate the offset faster than a minkowski > > algorithm or that doesn't use the minkowski or some equivalent? > > > > Regards > > Otto > > > > function heartRadius(t) = (1.5 - 1.5* sin(t) + (sin(t) * > > (sqrt(abs(cos(t)))/(sin(t)+1.6)))); > > $fn=23; > > div=512; //ONLY USE POWERS OF 2 > > > > module pHeart(xy,off=0) { > > > > td = 1/div; // theta delta - the resolution of the curve > > > > // Calculate x/y co-ords separetely so I can scale > > correctly later xp = [ for (t = [0: td : 360-td]) heartRadius(t) * > > cos(t) ]; // xco-ordinates on the curve > > yp = [ for (t = [0 : td : 360-td]) heartRadius(t) * sin(t) > > ]; // yco-ordinates on the curve > > > > xsc = xy/(max(xp) - min(xp)); // x scaler to get to fit > > expected size > > ysc = xy/(max(yp) - min(yp)); // y scaler to get to fit > > expected size > > > > // Generate a vector of points for the polygon to work > > p = [ for (i = [0 : 360/td-1]) [xsc*xp[i], ysc*yp[i]] ]; > > > > // translate polygon so it is centralised at +/- xy/2 > > translate([0,ysc*(-max(yp)+(max(yp)-min(yp))/2)]) > > > > //// UNCOMMENT LINE TO TEST > > //// CLEAR THE CACHE FIRST > > > > /////////////////////// MINKOWSKY > > //if(off){minkowski(){polygon(p);circle(off);}}else polygon(p); > > /////////////////////// OFFSET > > //offset(r=off) polygon(p); > > > > } > > > > difference() > > { > > linear_extrude(5) pHeart(xy=78,off=2); > > translate([0,0,-.5]) linear_extrude(6) pHeart(xy=78, off=.4); > > } > > > > > > > > > > > > > > _______________________________________________ > > > OpenSCAD mailing list > > > Discuss@lists.openscad.org > > > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org > > > > > > _______________________________________________ > > OpenSCAD mailing list > > Discuss@lists.openscad.org > > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org > >