I'm not sure where to post this or how to get to the point, please bear with
me and feel free to point me in directions.
I have a function and module that will draw me a heart polygon of an exact
size:
function heartRadius(t) = (1.5 - 1.5* sin(t) + (sin(t) *
(sqrt(abs(cos(t)))/(sin(t)+1.6))));
module njHeart(xy=80, pad = 0) {
td = 1; // 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) ]; // x
co-ordinates on the curve
yp = [ for (t = [0 : td : 360-td]) heartRadius(t) * sin(t) ]; // y
co-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]+pad, ysc*yp[i]+pad] ];
// translate polygon so it is centralised at +/- xy/2
translate([0,ysc*(-max(yp)+(max(yp)-min(yp))/2)])
linear_extrude(height=0.01) polygon(p);
}
color("red") njHeart(xy=80);
color("white") njHeart(xy=78);
Originally, I thought this was going to be easy, do it in polar and then
just add 'pad' to the calculated 'r' and it'll all be good... nope.
I had already worked out that scaling is not the answer.
Then I thought about calculating normals to the gradient of the 2 sides of
the point... but then you get a hole at the top of the heart as it loops
back on itself. My most promising idea was to test if the normal (x,y) was
of the same sign in x as the current point, but that got really messy trying
to make the array work- and I never did.
I then wondered if I could find the 'true' center of the object whether the
scaling would work better, but I couldn't figure out how to do it.
The only other option I can think of is to draw the outline of the heart in
hull'd cylinders with a radius of "pad", then subtracting the solid from the
middle. After working out the math it was very clear that the computational
power required was going to make it unworkable.
I have now run out of ideas.
Any help much apprecaited.
Kind regards
Nigel
--
View this message in context: http://forum.openscad.org/Adding-a-border-of-d-thickness-to-a-polygon-tp19283.html
Sent from the OpenSCAD mailing list archive at Nabble.com.
I think you just need to use offset() to expand the shape in 2D before
extruding it to 3D if I understand the question right.
On 21 November 2016 at 12:05, nigeljohnson73 nigel@nigeljohnson.net wrote:
I'm not sure where to post this or how to get to the point, please bear
with
me and feel free to point me in directions.
I have a function and module that will draw me a heart polygon of an exact
size:
function heartRadius(t) = (1.5 - 1.5* sin(t) + (sin(t) *
(sqrt(abs(cos(t)))/(sin(t)+1.6))));
module njHeart(xy=80, pad = 0) {
td = 1; // 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) ]; // x
co-ordinates on the curve
yp = [ for (t = [0 : td : 360-td]) heartRadius(t) * sin(t) ]; // y
co-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]+pad, ysc*yp[i]+pad] ];
// translate polygon so it is centralised at +/- xy/2
translate([0,ysc*(-max(yp)+(max(yp)-min(yp))/2)])
linear_extrude(height=0.01) polygon(p);
}
color("red") njHeart(xy=80);
color("white") njHeart(xy=78);
Originally, I thought this was going to be easy, do it in polar and then
just add 'pad' to the calculated 'r' and it'll all be good... nope.
I had already worked out that scaling is not the answer.
Then I thought about calculating normals to the gradient of the 2 sides of
the point... but then you get a hole at the top of the heart as it loops
back on itself. My most promising idea was to test if the normal (x,y) was
of the same sign in x as the current point, but that got really messy
trying
to make the array work- and I never did.
I then wondered if I could find the 'true' center of the object whether the
scaling would work better, but I couldn't figure out how to do it.
The only other option I can think of is to draw the outline of the heart in
hull'd cylinders with a radius of "pad", then subtracting the solid from
the
middle. After working out the math it was very clear that the computational
power required was going to make it unworkable.
I have now run out of ideas.
Any help much apprecaited.
Kind regards
Nigel
--
View this message in context: http://forum.openscad.org/
Adding-a-border-of-d-thickness-to-a-polygon-tp19283.html
Sent from the OpenSCAD mailing list archive at Nabble.com.
OpenSCAD mailing list
Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Thanks, that's what I was after. It doesn't like the sharp points though, so
a bit of tweaking was required.
--
View this message in context: http://forum.openscad.org/Adding-a-border-of-d-thickness-to-a-polygon-tp19283p19298.html
Sent from the OpenSCAD mailing list archive at Nabble.com.
On Nov 21, 2016, at 14:49, nigeljohnson73 nigel@nigeljohnson.net wrote:
Thanks, that's what I was after. It doesn't like the sharp points though, so
a bit of tweaking was required.
Nigel,
There are some parameters to offset() which can be used to control sharp corners, see:
https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Transformations#offset
-Marius
Thanks Marius.
I should have been more specific though; with my heart shape, the delta -
which is what I wanted based on the images in the documentation - doesn't
like the top point, and with a bit of delta cuts the whole object in half.
The radius is also not the greatest here, but it works enough for my needs.
Cheers
Nigel
--
View this message in context: http://forum.openscad.org/Adding-a-border-of-d-thickness-to-a-polygon-tp19283p19321.html
Sent from the OpenSCAD mailing list archive at Nabble.com.
Check out http://www.thingiverse.com/thing:8483 (this tells you how to make
a heart using Bezier curves) and http://www.thingiverse.com/thing:186660
(tells you how to extrude along a path).
Combine the two to extrude a square or rectangle along a heart-shaped path
and you should have what you're after?
Frank
On Wed, Nov 23, 2016 at 5:37 AM, nigeljohnson73 nigel@nigeljohnson.net
wrote:
Thanks Marius.
I should have been more specific though; with my heart shape, the delta -
which is what I wanted based on the images in the documentation - doesn't
like the top point, and with a bit of delta cuts the whole object in half.
The radius is also not the greatest here, but it works enough for my needs.
Cheers
Nigel
--
View this message in context: http://forum.openscad.org/
Adding-a-border-of-d-thickness-to-a-polygon-tp19283p19321.html
Sent from the OpenSCAD mailing list archive at Nabble.com.
OpenSCAD mailing list
Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
You have a very sharp angle in your heart, which makes it hard to offset. We
have a chamfer flag for this purpose, but that doesn't look too good in this
case.
Another option is to get rid of sharp angles by offsetting the original a
small amount:
difference() {
color("red") offset(delta=2) offset(delta=0.5) njHeart(xy=80);
color("white") offset(delta=0.5) njHeart(xy=80);
}
-Marius
--
View this message in context: http://forum.openscad.org/Adding-a-border-of-d-thickness-to-a-polygon-tp19283p19323.html
Sent from the OpenSCAD mailing list archive at Nabble.com.
Another way to achieve this is with the 2-D minkowski which is
moderately efficient.
function heartRadius(t) = (1.5 - 1.5* sin(t) + (sin(t) *
(sqrt(abs(cos(t)))/(sin(t)+1.6))));
$fn=23;
module pHeart(xy,off=0) {
td = 1; // 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)])
if(off)
{
minkowski(){ polygon(p); circle(off); }
}
else polygon(p);
}
difference()
{
linear_extrude(5) pHeart(xy=78,off=2);
translate([0,0,-.5]) linear_extrude(6) pHeart(xy=78, off=.4);
}
On Mon, 21 Nov 2016 13:36:36 +0000
nop head nop.head@gmail.com wrote:
I think you just need to use offset() to expand the shape in 2D before
extruding it to 3D if I understand the question right.
On 21 November 2016 at 12:05, nigeljohnson73 nigel@nigeljohnson.net
wrote:
I'm not sure where to post this or how to get to the point, please
bear with
me and feel free to point me in directions.
I have a function and module that will draw me a heart polygon of
an exact size:
function heartRadius(t) = (1.5 - 1.5* sin(t) + (sin(t) *
(sqrt(abs(cos(t)))/(sin(t)+1.6))));
module njHeart(xy=80, pad = 0) {
td = 1; // 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) ]; // x co-ordinates on the curve
yp = [ for (t = [0 : td : 360-td]) heartRadius(t) * sin(t)
]; // y co-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]+pad,
ysc*yp[i]+pad] ];
// translate polygon so it is centralised at +/- xy/2
translate([0,ysc*(-max(yp)+(max(yp)-min(yp))/2)])
linear_extrude(height=0.01) polygon(p);
}
color("red") njHeart(xy=80);
color("white") njHeart(xy=78);
Originally, I thought this was going to be easy, do it in polar and
then just add 'pad' to the calculated 'r' and it'll all be good...
nope.
I had already worked out that scaling is not the answer.
Then I thought about calculating normals to the gradient of the 2
sides of the point... but then you get a hole at the top of the
heart as it loops back on itself. My most promising idea was to
test if the normal (x,y) was of the same sign in x as the current
point, but that got really messy trying
to make the array work- and I never did.
I then wondered if I could find the 'true' center of the object
whether the scaling would work better, but I couldn't figure out
how to do it.
The only other option I can think of is to draw the outline of the
heart in hull'd cylinders with a radius of "pad", then subtracting
the solid from the
middle. After working out the math it was very clear that the
computational power required was going to make it unworkable.
I have now run out of ideas.
Any help much apprecaited.
Kind regards
Nigel
--
View this message in context: http://forum.openscad.org/
Adding-a-border-of-d-thickness-to-a-polygon-tp19283.html
Sent from the OpenSCAD mailing list archive at Nabble.com.
OpenSCAD mailing list
Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
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