discuss@lists.openscad.org

OpenSCAD general discussion Mailing-list

View all threads

Polygon Offset Function

R
Ronaldo
Wed, Apr 27, 2016 3:28 PM

Zappo wrote

Any suggestion for how to code up a convex poly offset function without
writing a duplicate of the CGAL routine in native OpenSCAD?

In your case, yes, use differentiation. If you take the unit normal at each
point of the airfoil you only need to add a fixed scale of it to the point.
If the offset is not too large it will not have self-intersections.

--
View this message in context: http://forum.openscad.org/Polygon-Offset-Function-tp17186p17213.html
Sent from the OpenSCAD mailing list archive at Nabble.com.

Zappo wrote > Any suggestion for how to code up a convex poly offset function without > writing a duplicate of the CGAL routine in native OpenSCAD? In your case, yes, use differentiation. If you take the unit normal at each point of the airfoil you only need to add a fixed scale of it to the point. If the offset is not too large it will not have self-intersections. -- View this message in context: http://forum.openscad.org/Polygon-Offset-Function-tp17186p17213.html Sent from the OpenSCAD mailing list archive at Nabble.com.
R
Ronaldo
Wed, Apr 27, 2016 6:08 PM

Here you have an idea of how to offset non-cambered airfoils. The approach
applies also to cambered ones.

function unit(v) = v/norm(v);

// Non-cambered Naca example

function Naca_airfoil(c, t, x ) = let( xl = x/c)
5tc*( 0.2969sqrt(xl) - 0.126xl - 0.3516pow(xl,2) +
0.2843
pow(xl,3) - 0.1015*pow(xl,4) );

function Naca_afl_derivative(c, t, x) = let( xl = x/c)
x > 1e-12c ?
5
tc( 0.2969/sqrt(xl)/2/c - 0.126/c - 0.35162xl/c +
0.28433pow(xl,2)/c - 0.10154pow(xl,3)/c ) :
undef;

function Naca_afl_normal(c, t, x) =
x <= 1e-6*c ?
[ 1, 0 ] :
unit([ Naca_afl_derivative(c, t, x), -1 ] );

function thin_airfoil(c, t, offset, n) =
// a non-linear reparametrization to refine the discretization near 0
concat( [ for(x=[0: c/n : c]) let( xl = cpow(x/c,3) )
[ xl, Naca_airfoil(c, t, xl ) ] ] ,
[ for(x=[c: -c/n : 0]) let( xl = c
pow(x/c,3) )
[ xl, Naca_airfoil(c, t, xl ) ]
+ offset*Naca_afl_normal(c, t, xl) ] );

module thin_Naca_airfoil(c, t, offset, n) {
intersection() {
polygon( thin_airfoil(c, t, offset, n) );
square([c,c*t]);
}
}

thin_Naca_airfoil(100, 1/5, 1, 20);

--
View this message in context: http://forum.openscad.org/Polygon-Offset-Function-tp17186p17215.html
Sent from the OpenSCAD mailing list archive at Nabble.com.

Here you have an idea of how to offset non-cambered airfoils. The approach applies also to cambered ones. > function unit(v) = v/norm(v); > > // Non-cambered Naca example > > function Naca_airfoil(c, t, x ) = let( xl = x/c) > 5*t*c*( 0.2969*sqrt(xl) - 0.126*xl - 0.3516*pow(xl,2) + > 0.2843*pow(xl,3) - 0.1015*pow(xl,4) ); > > function Naca_afl_derivative(c, t, x) = let( xl = x/c) > x > 1e-12*c ? > 5*t*c*( 0.2969/sqrt(xl)/2/c - 0.126/c - 0.3516*2*xl/c + > 0.2843*3*pow(xl,2)/c - 0.1015*4*pow(xl,3)/c ) : > undef; > > function Naca_afl_normal(c, t, x) = > x <= 1e-6*c ? > [ 1, 0 ] : > unit([ Naca_afl_derivative(c, t, x), -1 ] ); > > > > function thin_airfoil(c, t, offset, n) = > // a non-linear reparametrization to refine the discretization near 0 > concat( [ for(x=[0: c/n : c]) let( xl = c*pow(x/c,3) ) > [ xl, Naca_airfoil(c, t, xl ) ] ] , > [ for(x=[c: -c/n : 0]) let( xl = c*pow(x/c,3) ) > [ xl, Naca_airfoil(c, t, xl ) ] > + offset*Naca_afl_normal(c, t, xl) ] ); > > module thin_Naca_airfoil(c, t, offset, n) { > intersection() { > polygon( thin_airfoil(c, t, offset, n) ); > square([c,c*t]); > } > } > > thin_Naca_airfoil(100, 1/5, 1, 20); > -- View this message in context: http://forum.openscad.org/Polygon-Offset-Function-tp17186p17215.html Sent from the OpenSCAD mailing list archive at Nabble.com.
DM
doug moen
Thu, Apr 28, 2016 12:51 AM

@zappo said Is there a way to call python code from within OpenSCAD?

No, but you can invoke OpenSCAD from Python. Some people use SolidPython
for this.

On Wednesday, 27 April 2016, Zappo teranick@gmail.com wrote:

I am guessing that I'll need tight control on the wall thicknesses to fake
out the slicers and keep a precise perimeter thickness for the outer
surface.  Part of the problem is that for constant wall thickness, the
inner
airfoil cut out is not a scaled version of the outer surface.  And as the
airfoil size changes on a tapered wing, you need a new unique inner cutout
for each outer airfoil.

@Parkinbot - the splines will come in handy for doing fuselages, but it
seems you still have the same problem I was seeing.  How do you get the
offset inner polygon?  I am guessing the minkowski speed is a function of
the number of faces and not necessarily the size -  Did you try to hollow
out your wing?  Need to try to dynamically decrease step size where the
sections change.  How well does your technique deal with airfoil sections
containing different numbers of polygon points?  For me, stitching together
internal airfoil cutouts with differing polygon vertex counts will require
some special casing.

@Torsten - yes a function returning a polygon vs a transform.  Any
suggestion for how to code up a convex poly offset function without writing
a duplicate of the CGAL routine in native OpenSCAD?

Is there a way to call python code from within OpenSCAD?

@cbernhardt - let me clean it up

@wolf - not sure that scaling works really well if we're trying to maintain
uniform wall thickness.  Scaling works ok on an ellipse as in your example,
but consider what happens at the pointy trailing edge compared to the
leading edge.

--
View this message in context:
http://forum.openscad.org/Polygon-Offset-Function-tp17186p17200.html
Sent from the OpenSCAD mailing list archive at Nabble.com.


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

@zappo said Is there a way to call python code from within OpenSCAD? No, but you can invoke OpenSCAD from Python. Some people use SolidPython for this. On Wednesday, 27 April 2016, Zappo <teranick@gmail.com> wrote: > I am guessing that I'll need tight control on the wall thicknesses to fake > out the slicers and keep a precise perimeter thickness for the outer > surface. Part of the problem is that for constant wall thickness, the > inner > airfoil cut out is not a scaled version of the outer surface. And as the > airfoil size changes on a tapered wing, you need a new unique inner cutout > for each outer airfoil. > > @Parkinbot - the splines will come in handy for doing fuselages, but it > seems you still have the same problem I was seeing. How do you get the > offset inner polygon? I am guessing the minkowski speed is a function of > the number of faces and not necessarily the size - Did you try to hollow > out your wing? Need to try to dynamically decrease step size where the > sections change. How well does your technique deal with airfoil sections > containing different numbers of polygon points? For me, stitching together > internal airfoil cutouts with differing polygon vertex counts will require > some special casing. > > @Torsten - yes a function returning a polygon vs a transform. Any > suggestion for how to code up a convex poly offset function without writing > a duplicate of the CGAL routine in native OpenSCAD? > > Is there a way to call python code from within OpenSCAD? > > @cbernhardt - let me clean it up > > @wolf - not sure that scaling works really well if we're trying to maintain > uniform wall thickness. Scaling works ok on an ellipse as in your example, > but consider what happens at the pointy trailing edge compared to the > leading edge. > > > > > > > > > > -- > View this message in context: > http://forum.openscad.org/Polygon-Offset-Function-tp17186p17200.html > Sent from the OpenSCAD mailing list archive at Nabble.com. > > _______________________________________________ > OpenSCAD mailing list > Discuss@lists.openscad.org <javascript:;> > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org > > >
Z
Zappo
Fri, Apr 29, 2016 4:39 AM

Thanks everyone for the ideas.

@Ronaldo "/If you take the unit normal at each point of the airfoil you only
need to add a fixed scale of it to the point. If the offset is not too large
it will not have self-intersections./" - I was headed down this path as
well, and calculating the derivative directly is interesting.  But icky part
is that at the wing tips, as the airfoil chord get smaller, the relative
thickness of the skin increases relative to the chord, so you have to start
playing games reducing the number of points in the airfoil polygon to
prevent self-intersections. - but still doable.  At some point you just go
solid and don't bother with the cut out.

@Parkinbot you're right.  Slic3r does exactly the function I am looking for
because it could create a 3D shell N perimeters thick by using zero infill.
And it is fast! I just need a way to merge in the ribbing and spars.
Meshmixer can also create shells and export them as STL.  It could also
merge an STL of the ribbing and spars with the skin.

@Doug/MichaelAtOz  I need to look at SolidPython or maybe a command line
hybrid.  Probably pre-compute the entire polyhedron skin in Python or even
C.

It is not sounding like there is enough general interest in a polygon offset
function that returns a polygon to request that it be added as a language
feature.  And there is no way to call a Python function from OpenSCAD. Then
there is the desire to be able to shell a fuselage. But it does sound like
there are some work around options....

--
View this message in context: http://forum.openscad.org/Polygon-Offset-Function-tp17186p17224.html
Sent from the OpenSCAD mailing list archive at Nabble.com.

Thanks everyone for the ideas. @Ronaldo "/If you take the unit normal at each point of the airfoil you only need to add a fixed scale of it to the point. If the offset is not too large it will not have self-intersections./" - I was headed down this path as well, and calculating the derivative directly is interesting. But icky part is that at the wing tips, as the airfoil chord get smaller, the relative thickness of the skin increases relative to the chord, so you have to start playing games reducing the number of points in the airfoil polygon to prevent self-intersections. - but still doable. At some point you just go solid and don't bother with the cut out. @Parkinbot you're right. Slic3r does exactly the function I am looking for because it could create a 3D shell N perimeters thick by using zero infill. And it is fast! I just need a way to merge in the ribbing and spars. Meshmixer can also create shells and export them as STL. It could also merge an STL of the ribbing and spars with the skin. @Doug/MichaelAtOz I need to look at SolidPython or maybe a command line hybrid. Probably pre-compute the entire polyhedron skin in Python or even C. It is not sounding like there is enough general interest in a polygon offset function that returns a polygon to request that it be added as a language feature. And there is no way to call a Python function from OpenSCAD. Then there is the desire to be able to shell a fuselage. But it does sound like there are some work around options.... -- View this message in context: http://forum.openscad.org/Polygon-Offset-Function-tp17186p17224.html Sent from the OpenSCAD mailing list archive at Nabble.com.
RP
Ronaldo Persiano
Fri, Apr 29, 2016 1:15 PM

"But icky part
is that at the wing tips, as the airfoil chord get smaller, the relative
thickness of the skin increases relative to the chord, so you have to start
playing games reducing the number of points in the airfoil polygon to
prevent self-intersections. - but still doable. "

My code was just a starting point. You can always clip each internal curve
offset against the start-end line instead of doing a overall clipping as I
did. This would avoid any self-intersections.

2016-04-29 1:39 GMT-03:00 Zappo teranick@gmail.com:

Thanks everyone for the ideas.

@Ronaldo "/If you take the unit normal at each point of the airfoil you
only
need to add a fixed scale of it to the point. If the offset is not too
large
it will not have self-intersections./" - I was headed down this path as
well, and calculating the derivative directly is interesting.  But icky
part
is that at the wing tips, as the airfoil chord get smaller, the relative
thickness of the skin increases relative to the chord, so you have to start
playing games reducing the number of points in the airfoil polygon to
prevent self-intersections. - but still doable.  At some point you just go
solid and don't bother with the cut out.

@Parkinbot you're right.  Slic3r does exactly the function I am looking for
because it could create a 3D shell N perimeters thick by using zero infill.
And it is fast! I just need a way to merge in the ribbing and spars.
Meshmixer can also create shells and export them as STL.  It could also
merge an STL of the ribbing and spars with the skin.

@Doug/MichaelAtOz  I need to look at SolidPython or maybe a command line
hybrid.  Probably pre-compute the entire polyhedron skin in Python or even
C.

It is not sounding like there is enough general interest in a polygon
offset
function that returns a polygon to request that it be added as a language
feature.  And there is no way to call a Python function from OpenSCAD. Then
there is the desire to be able to shell a fuselage. But it does sound like
there are some work around options....

--
View this message in context:
http://forum.openscad.org/Polygon-Offset-Function-tp17186p17224.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

"But icky part is that at the wing tips, as the airfoil chord get smaller, the relative thickness of the skin increases relative to the chord, so you have to start playing games reducing the number of points in the airfoil polygon to prevent self-intersections. - but still doable. " My code was just a starting point. You can always clip each internal curve offset against the start-end line instead of doing a overall clipping as I did. This would avoid any self-intersections. 2016-04-29 1:39 GMT-03:00 Zappo <teranick@gmail.com>: > Thanks everyone for the ideas. > > @Ronaldo "/If you take the unit normal at each point of the airfoil you > only > need to add a fixed scale of it to the point. If the offset is not too > large > it will not have self-intersections./" - I was headed down this path as > well, and calculating the derivative directly is interesting. But icky > part > is that at the wing tips, as the airfoil chord get smaller, the relative > thickness of the skin increases relative to the chord, so you have to start > playing games reducing the number of points in the airfoil polygon to > prevent self-intersections. - but still doable. At some point you just go > solid and don't bother with the cut out. > > @Parkinbot you're right. Slic3r does exactly the function I am looking for > because it could create a 3D shell N perimeters thick by using zero infill. > And it is fast! I just need a way to merge in the ribbing and spars. > Meshmixer can also create shells and export them as STL. It could also > merge an STL of the ribbing and spars with the skin. > > @Doug/MichaelAtOz I need to look at SolidPython or maybe a command line > hybrid. Probably pre-compute the entire polyhedron skin in Python or even > C. > > It is not sounding like there is enough general interest in a polygon > offset > function that returns a polygon to request that it be added as a language > feature. And there is no way to call a Python function from OpenSCAD. Then > there is the desire to be able to shell a fuselage. But it does sound like > there are some work around options.... > > > > > > > > > > -- > View this message in context: > http://forum.openscad.org/Polygon-Offset-Function-tp17186p17224.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 >
Z
Zappo
Sat, Apr 30, 2016 5:57 AM

Ronaldo  - I tweaked your example a little bit. I was worried about the
polygon folding back on itself and was having trouble visualizing it.  At
least in this example, the offset function is fairly well behaved, and the
direction reversal traces out a convex tip.  The clipping could obviously be
done within the thin_airfoil function itself.  Thanks for coding this up.

The closed form derivative get more complex when camber is introduced.
https://en.wikipedia.org/wiki/NACA_airfoil, so I think the next step is to
code it up approximating the derivative with a delta step off the final
cambered airfoil function.

module thin_Naca_airfoil(c, t, offset, n) {
//intersection() {
polygon( thin_airfoil(c, t, offset, n) );
//  square([c,c*t]);
//}
}

thin_Naca_airfoil(100, 1/5, 10, 20);

http://forum.openscad.org/file/n17248/unclipped.png

--
View this message in context: http://forum.openscad.org/Polygon-Offset-Function-tp17186p17248.html
Sent from the OpenSCAD mailing list archive at Nabble.com.

Ronaldo - I tweaked your example a little bit. I was worried about the polygon folding back on itself and was having trouble visualizing it. At least in this example, the offset function is fairly well behaved, and the direction reversal traces out a convex tip. The clipping could obviously be done within the thin_airfoil function itself. Thanks for coding this up. The closed form derivative get more complex when camber is introduced. https://en.wikipedia.org/wiki/NACA_airfoil, so I think the next step is to code it up approximating the derivative with a delta step off the final cambered airfoil function. module thin_Naca_airfoil(c, t, offset, n) { //intersection() { polygon( thin_airfoil(c, t, offset, n) ); // square([c,c*t]); //} } thin_Naca_airfoil(100, 1/5, 10, 20); <http://forum.openscad.org/file/n17248/unclipped.png> -- View this message in context: http://forum.openscad.org/Polygon-Offset-Function-tp17186p17248.html Sent from the OpenSCAD mailing list archive at Nabble.com.
P
Parkinbot
Sat, Apr 30, 2016 1:20 PM

The straight forward approach would be to calculate the normal for each edge
and just add up your inset along this vector to one of the vertices (or even
better: to the middle vertex of the edge). The rest is eliminating self
intersection (for inset only), which can get a bit nasty if you go into the
details. The 'dirty' one-line approach is to use some procrustes cut from
left and right.

For outset call inset() with a negative value.

use
<Naca4.scad>
L = 100;
p = airfoil_data(naca = 1410, N=90, L=L);
p_ = inset(p, 1);
q = cut(p_, 1, 92);

linear_extrude(height = .1) polygon(p);
color("white") linear_extrude(height = .3) polygon(q);

function inset(A, d) =  [for(i = [0:len(A)-2])  let (v = A[i+1]-A[i]) let
(n = [v[1], -v[0]]/norm(v))  A[i]+d*n];

function cut(A, a, b) =  [for(i = [0:len(A)-2])    if (A[i][0]>=a &&
A[i][0]<=b)

http://forum.openscad.org/file/n17251/inset.png

--
View this message in context: http://forum.openscad.org/Polygon-Offset-Function-tp17186p17251.html
Sent from the OpenSCAD mailing list archive at Nabble.com.

The straight forward approach would be to calculate the normal for each edge and just add up your inset along this vector to one of the vertices (or even better: to the middle vertex of the edge). The rest is eliminating self intersection (for inset only), which can get a bit nasty if you go into the details. The 'dirty' one-line approach is to use some procrustes cut from left and right. For outset call inset() with a negative value. > use > <Naca4.scad> > L = 100; > p = airfoil_data(naca = 1410, N=90, L=L); > p_ = inset(p, 1); > q = cut(p_, 1, 92); > > linear_extrude(height = .1) polygon(p); > color("white") linear_extrude(height = .3) polygon(q); > > function inset(A, d) = [for(i = [0:len(A)-2]) let (v = A[i+1]-A[i]) let > (n = [v[1], -v[0]]/norm(v)) A[i]+d*n]; > > function cut(A, a, b) = [for(i = [0:len(A)-2]) if (A[i][0]>=a && > A[i][0]<=b) <http://forum.openscad.org/file/n17251/inset.png> -- View this message in context: http://forum.openscad.org/Polygon-Offset-Function-tp17186p17251.html Sent from the OpenSCAD mailing list archive at Nabble.com.
J
Jamie_K
Sat, Apr 30, 2016 4:59 PM

I'm curious about this offset function.  If the offset is interpreted as an
offset to the edges, then the vertices will move by a larger amount and not
perpendicular to either segment when the two adjacent edges move, due to the
corner.  For example, at a right angle, if both edges move by x, then the
corner will move diagonally by sqrt(2) * x.

To compute this, each line segment can be transformed into an equation
ax+by = c
and then each equation offset using
ax+by = c+offs
Given two such offset equations, the new vertex is the intersection of these
two lines which is found by solving the two equations.

Here are some functions that do exactly that:

For the example airfoil below it does produce self-intersections, so I am
looking at trying to make a cleanup function for "simple" self-intersections
like these.

Incidentally, for this airfoil, adjusting each point perpendicular to the
line segments produces a rather severe distortion, so I would recommend that
approach only be used for 'organic' shapes with many small segments and
gentle angles, and avoid using it on geometric shapes with large segments
and sharp angles.

http://forum.openscad.org/file/n17256/airfoil_offset.png

http://forum.openscad.org/file/n17256/airfoil_offset_intersect.png

--
View this message in context: http://forum.openscad.org/Polygon-Offset-Function-tp17186p17256.html
Sent from the OpenSCAD mailing list archive at Nabble.com.

I'm curious about this offset function. If the offset is interpreted as an offset to the edges, then the vertices will move by a larger amount and not perpendicular to either segment when the two adjacent edges move, due to the corner. For example, at a right angle, if both edges move by x, then the corner will move diagonally by sqrt(2) * x. To compute this, each line segment can be transformed into an equation a*x+b*y = c and then each equation offset using a*x+b*y = c+offs Given two such offset equations, the new vertex is the intersection of these two lines which is found by solving the two equations. Here are some functions that do exactly that: For the example airfoil below it does produce self-intersections, so I am looking at trying to make a cleanup function for "simple" self-intersections like these. Incidentally, for this airfoil, adjusting each point perpendicular to the line segments produces a rather severe distortion, so I would recommend that approach only be used for 'organic' shapes with many small segments and gentle angles, and avoid using it on geometric shapes with large segments and sharp angles. <http://forum.openscad.org/file/n17256/airfoil_offset.png> <http://forum.openscad.org/file/n17256/airfoil_offset_intersect.png> -- View this message in context: http://forum.openscad.org/Polygon-Offset-Function-tp17186p17256.html Sent from the OpenSCAD mailing list archive at Nabble.com.
R
Ronaldo
Sat, Apr 30, 2016 7:09 PM

@Jamie K. I had proposed the use of the curve normal (computed from the curve
derivative) for the airfoil because: a) the airfoil curve is differentiable,
b) the offset was small and c) the curve was finely discretized. If you have
a right angle in the curve it is not differentiable and that approach is not
valid. Similarly if the offset is greater then curvature radius of the curve
in a convex section, self-intersections will emerge. So, its only valid for
offsets small enough. Finally, if the curve discretization is course, the
proposed procedure would generate a crude approximation of the offset. It is
not by no means a general procedure.

--
View this message in context: http://forum.openscad.org/Polygon-Offset-Function-tp17186p17258.html
Sent from the OpenSCAD mailing list archive at Nabble.com.

@Jamie K. I had proposed the use of the curve normal (computed from the curve derivative) for the airfoil because: a) the airfoil curve is differentiable, b) the offset was small and c) the curve was finely discretized. If you have a right angle in the curve it is not differentiable and that approach is not valid. Similarly if the offset is greater then curvature radius of the curve in a convex section, self-intersections will emerge. So, its only valid for offsets small enough. Finally, if the curve discretization is course, the proposed procedure would generate a crude approximation of the offset. It is not by no means a general procedure. -- View this message in context: http://forum.openscad.org/Polygon-Offset-Function-tp17186p17258.html Sent from the OpenSCAD mailing list archive at Nabble.com.
Z
Zappo
Sat, Apr 30, 2016 7:49 PM

@Jamie K
Agreed.  We need a function to "clean up" polygon self intersections.  (or
just use CGAL -hint hint)

Also once you add in the camber equations, the final X and Y points become
parametric so the first step is to identify the line segments that
intersect.  I am thinking to step thru the bottom polyline while doing a
lookup on the other polyline for a GT or LT crossing and visa-versa.  Once
the crossing segments are identified, the intersection point can be
calculated as you indicated.

The unit normal of the original function, not the polyline, at each vertex
should give the bisector between this and the next line segment.  There's
probably some cleaner geometric ways to calculate the bisector of two
adjacent segments not using the function unit normal.  I suppose you then
create the offset parallelogram and solve for the offset point. But you
still have the self intersection problem.

Here is a NACA 4312 airfoil with about 200 of polygon points.

http://forum.openscad.org/file/n17259/self_intersect.png

--
View this message in context: http://forum.openscad.org/Polygon-Offset-Function-tp17186p17259.html
Sent from the OpenSCAD mailing list archive at Nabble.com.

@Jamie K Agreed. We need a function to "clean up" polygon self intersections. (or just use CGAL -hint hint) Also once you add in the camber equations, the final X and Y points become parametric so the first step is to identify the line segments that intersect. I am thinking to step thru the bottom polyline while doing a lookup on the other polyline for a GT or LT crossing and visa-versa. Once the crossing segments are identified, the intersection point can be calculated as you indicated. The unit normal of the original function, not the polyline, at each vertex should give the bisector between this and the next line segment. There's probably some cleaner geometric ways to calculate the bisector of two adjacent segments not using the function unit normal. I suppose you then create the offset parallelogram and solve for the offset point. But you still have the self intersection problem. Here is a NACA 4312 airfoil with about 200 of polygon points. <http://forum.openscad.org/file/n17259/self_intersect.png> -- View this message in context: http://forum.openscad.org/Polygon-Offset-Function-tp17186p17259.html Sent from the OpenSCAD mailing list archive at Nabble.com.