How to get an outline of a 2D object?

classic Classic list List threaded Threaded
35 messages Options
12
Reply | Threaded
Open this post in threaded view
|

How to get an outline of a 2D object?

Troberg
I have a problem. I have 2D objects, which might be concave, and which has
holes in them. These objects are pretty complex, done in several stages, and
the holes are made in a pretty early part of the process, and the holes may
(or may not) also affect the shape of the outline.

What I want is to get just the outer contour of the object, without the
holes contained fully within, to create masks for other stages in the
production.

If I knew the objects were convex, it wouldn't be a problem, then hull()
would work, but I cannot rely on them to be convex (in fact, they most
certainly aren't).

If the objects were simple, I could do it by union() with some "cover
objects", but they aren't.

If I could do the holes last, it would (partly, but not guaranteed) help,
but I can't as I have other later stages which requires them to be there.

Likewise, bouncing an offset out and back won't work, as it'll affect
corners.

So, any idea on how one could do an outline() module?



--
Sent from: http://forum.openscad.org/

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: How to get an outline of a 2D object?

OpenSCAD mailing list-2
Position the object and then do projection()?

William


_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: How to get an outline of a 2D object?

Troberg
Wouldn't projection() just give me the same 2D object as I had, with the same
holes in it?



--
Sent from: http://forum.openscad.org/

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: How to get an outline of a 2D object?

adrianv
In reply to this post by Troberg
I don't know if this would be practical for your situation, but BOSL2 has
some functions for doing boolean operations on 2d objects expressed as point
lists.  I haven't really experimented with that code much, but I believe if
you were to construct your object with that code the final output would be
the outline you desire plus a list of (entirely internal and disjoint) holes
that need to be subtracted.  

Simple example below shows some boolean operations to make a 2d object.
Full 2d object on the left, and then just the outline object on the right.  

include<BOSL2/std.scad>

$fn=32;

obj1 = circle(5);
obj2 = apply(move([1,2]), circle(1));
obj3 = apply(move([2.5,-4]), square(3));
obj4 = apply(move([-3,-3.1]), circle(2));
obj5 = apply(move([-2,-2.5]), square(2));

obj = difference([ [obj1],[obj2], [obj3], [obj4], [obj5]]);


region(obj);      // Display compound object


right(12)
polygon(obj[0]);   // obj[0] is the desired outline

<http://forum.openscad.org/file/t2477/geom.png>




--
Sent from: http://forum.openscad.org/

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: How to get an outline of a 2D object?

Troberg
adrianv wrote
> I don't know if this would be practical for your situation, but BOSL2 has
> some functions for doing boolean operations on 2d objects expressed as
> point
> lists.

Sorry, wouldn't be practical, I use a lot of offsets and stuff to get
rounded shapes, so it would be hard to get a point list.




--
Sent from: http://forum.openscad.org/

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: How to get an outline of a 2D object?

adrianv
Not sure why this is a problem: an offset() function is available.   (There
are also other ways to make rounded shapes that are more direct and more
flexible than offset.)  

include<BOSL2/std.scad>

$fn=32;

obj1 = circle(5);
obj2 = apply(move([1,2]), circle(1));
obj3 = offset(apply(move([2,-4]), square([2,3])), r=.5, closed=true);
obj4 = apply(move([-3,-3.1]), circle(2));
obj5 = offset(apply(move([-2,-2.5]), square(2)),r=.5,closed=true);

obj = difference([ [obj1],[obj2], [obj3], [obj4], [obj5]]);

region(obj);      // Display compound object


right(12)
polygon(obj[0]);   // obj[0] is the desired outline


<http://forum.openscad.org/file/t2477/geom2.png>


Troberg wrote

> adrianv wrote
>> I don't know if this would be practical for your situation, but BOSL2 has
>> some functions for doing boolean operations on 2d objects expressed as
>> point
>> lists.
>
> Sorry, wouldn't be practical, I use a lot of offsets and stuff to get
> rounded shapes, so it would be hard to get a point list.
>
>
>
>
> --
> Sent from: http://forum.openscad.org/
>
> _______________________________________________
> OpenSCAD mailing list

> Discuss@.openscad

> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org





--
Sent from: http://forum.openscad.org/

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: How to get an outline of a 2D object?

shadowwynd
This post was updated on .
In reply to this post by Troberg
Normally, when I have this problem, I export the file as DXF/SVG, open the file in Inkscape, Ctrl+Shift+K
to break paths apart, then just grab the outside shape.  But to do this in
OpenSCAD:

Here is a simple proof of concept using offset and no external libraries.

In this case there is an interplay between the $fn and the "interior"
variable; with $fn high (like 200) interior can be between 10 and 20 (on
this example) without the outline of the external shape varying.  If $fn was
low... for example $fn=40, then you would start getting artifacts on some of
the outer curves.  But this technique works well enough for certain shapes.

------------------------

$fn=200;
interior = 20;

module shape()
{
        // Make a Complex Shape
        difference()
        {
                square (100);
                translate ([50, 50, 0]) circle (10);
                translate ([100, 100, 0]) circle (20);
                translate ([30, 70, 0]) circle (20, $fn=3);
                translate ([0, 0, 0]) circle (40);
                translate ([80, -1, ]) square (20);
                translate ([80, 80, 0]) circle (5)
                translate ([85, 40, 0]) circle (10);

                // Not perfect - uncomment the line below to break it
                //translate ([80, 40,0]) square ([40, 10]);
        }
        translate ([80,20,0]) circle (20);
}

//Create the Outline
color ("blue") offset(r=-interior) offset (r=interior) shape();

//Original Shape
color ("yellow") translate ([0, 0, 10]) shape();



--
Sent from: http://forum.openscad.org/

_______________________________________________
OpenSCAD mailing list
Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: How to get an outline of a 2D object?

Troberg
In reply to this post by adrianv
adrianv wrote
> Not sure why this is a problem: an offset() function is available.  
> (There
> are also other ways to make rounded shapes that are more direct and more
> flexible than offset.)

Well, it's not just offset(), consider it a big heap of operations, applied
in a specific order. For the purpose of this discussion, the holes may just
as well be random in shape and position.

Also, even if I could duplicate all the functionality of the ordinary
OpenSCAD syntax, I'd prefer not to. It's a huge code library, I don't want
to rewrite it too much, I still want to be able to use all the helper
modules I've written, so I'd prefer to, if at all possible, to work with
OpenSCAD, rather than against it.



--
Sent from: http://forum.openscad.org/

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: How to get an outline of a 2D object?

Troberg
In reply to this post by shadowwynd
shadowwynd wrote

> Normally, when I have this problem, I export the file as DXF/SVG, open the
> file in Inkscape, Ctrl+Shift+K
> to break paths apart, then just grab the outside shape.  But to do this in
> OpenSCAD:
>
> Here is a simple proof of concept using offset and no external libraries.
>
> In this case there is an interplay between the $fn and the "interior"
> variable; with $fn high (like 200) interior can be between 10 and 20 (on
> this example) without the outline of the external shape varying.  If $fn
> was
> low... for example $fn=40, then you would start getting artifacts on some
> of
> the outer curves.  But this technique works well enough for certain
> shapes.
>
> ------------------------
>
> $fn=200;
> interior = 20;
>
> module shape()
> {
> // Make a Complex Shape
> difference()
> {
> square (100);
> translate ([50, 50, 0]) circle (10);
> translate ([100, 100, 0]) circle (20);
> translate ([30, 70, 0]) circle (20, $fn=3);
> translate ([0, 0, 0]) circle (40);
> translate ([80, -1, ]) square (20);
> translate ([80, 80, 0]) circle (5)
> translate ([85, 40, 0]) circle (10);
>
>                 // Not perfect - uncomment the line below to break it
>                 //translate ([80, 40,0]) square ([40, 10]);
> }
> translate ([80,20,0]) circle (20);
> }
>
> //Create the Outline
> color ("blue") offset(r=-interior) offset (r=interior) shape();
>
> //Original Shape
> color ("yellow") translate ([0, 0, 10]) shape();
>
>
>
> --
> Sent from: http://forum.openscad.org/
>
> _______________________________________________
> OpenSCAD mailing list
> [hidden email]
> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org


Yep, that's about as close as I got to a generic solution, but, in my case,
I have "dents" and holes ranging from 400 mm down to 11 mm, of various
shapes, so it's hard to find a setting which works for all.



--
Sent from: http://forum.openscad.org/

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: How to get an outline of a 2D object?

cacb
In reply to this post by Troberg
On 2020-11-14 20:35, Troberg wrote:

> I have a problem. I have 2D objects, which might be concave, and which
> has
> holes in them. These objects are pretty complex, done in several
> stages, and
> the holes are made in a pretty early part of the process, and the holes
> may
> (or may not) also affect the shape of the outline.
>
> What I want is to get just the outer contour of the object, without the
> holes contained fully within, to create masks for other stages in the
> production.

I don't think there is an automatic way to do it in OpenSCAD, but
'fill2d' in AngelCAD does exactly this, it fills the holes in any 2d
shape.

https://arnholm.github.io/angelcad-docs/docs/classfill2d.html

Carsten Arnholm

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: How to get an outline of a 2D object?

Ronaldo
In reply to this post by Troberg
I don't have a general solution to your problem but if the polygon you want has some properties there is a way to find it.

The simpler case (besides a convex polygon) happens when the polygon has a "visual center", that is an inner point from which all vertices can be seen from inside. The solution for those cases is just to translate the polygon so that the center goes to the origin, then extrude it with a scale nearly zero, project it back to the xy plane and translating it back to the center. 

module fill_holes(center) 
  translate(center) { 
    projection()
      linear_extrude(1, scale=0.0001)
        translate( - center) children();
      scale(.01) hull() children();
  } 
 

The hull was added to prevent for an eventual hole at the center (because the scale cannot be zero).

If no such center exists, fill_holes(p) holed_poly() will include some points that doesn't belongs to holed_poly() for all possible point p.  In this case, you may try to intersect all  fill_holes(p) holed_poly() for p in a set of points P. A good choice of the set P may produce the correct answer.

module fill_holes2(P) 
  intersection_for(p=P)
    translate(center) {
      projection()
        linear_extrude(1, scale=0.0001)
          translate( - center) children();
    scale(.01) hull() children();
  }


In this case, the set P doesn't need to be inside the polygon.

Em sáb., 14 de nov. de 2020 às 19:36, Troberg <[hidden email]> escreveu:
I have a problem. I have 2D objects, which might be concave, and which has
holes in them. These objects are pretty complex, done in several stages, and
the holes are made in a pretty early part of the process, and the holes may
(or may not) also affect the shape of the outline.

What I want is to get just the outer contour of the object, without the
holes contained fully within, to create masks for other stages in the
production.

If I knew the objects were convex, it wouldn't be a problem, then hull()
would work, but I cannot rely on them to be convex (in fact, they most
certainly aren't).

If the objects were simple, I could do it by union() with some "cover
objects", but they aren't.

If I could do the holes last, it would (partly, but not guaranteed) help,
but I can't as I have other later stages which requires them to be there.

Likewise, bouncing an offset out and back won't work, as it'll affect
corners.

So, any idea on how one could do an outline() module?



--
Sent from: http://forum.openscad.org/

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: How to get an outline of a 2D object?

nophead
Very clever.

On Mon, 16 Nov 2020 at 22:17, Ronaldo Persiano <[hidden email]> wrote:
I don't have a general solution to your problem but if the polygon you want has some properties there is a way to find it.

The simpler case (besides a convex polygon) happens when the polygon has a "visual center", that is an inner point from which all vertices can be seen from inside. The solution for those cases is just to translate the polygon so that the center goes to the origin, then extrude it with a scale nearly zero, project it back to the xy plane and translating it back to the center. 

module fill_holes(center) 
  translate(center) { 
    projection()
      linear_extrude(1, scale=0.0001)
        translate( - center) children();
      scale(.01) hull() children();
  } 
 

The hull was added to prevent for an eventual hole at the center (because the scale cannot be zero).

If no such center exists, fill_holes(p) holed_poly() will include some points that doesn't belongs to holed_poly() for all possible point p.  In this case, you may try to intersect all  fill_holes(p) holed_poly() for p in a set of points P. A good choice of the set P may produce the correct answer.

module fill_holes2(P) 
  intersection_for(p=P)
    translate(center) {
      projection()
        linear_extrude(1, scale=0.0001)
          translate( - center) children();
    scale(.01) hull() children();
  }


In this case, the set P doesn't need to be inside the polygon.

Em sáb., 14 de nov. de 2020 às 19:36, Troberg <[hidden email]> escreveu:
I have a problem. I have 2D objects, which might be concave, and which has
holes in them. These objects are pretty complex, done in several stages, and
the holes are made in a pretty early part of the process, and the holes may
(or may not) also affect the shape of the outline.

What I want is to get just the outer contour of the object, without the
holes contained fully within, to create masks for other stages in the
production.

If I knew the objects were convex, it wouldn't be a problem, then hull()
would work, but I cannot rely on them to be convex (in fact, they most
certainly aren't).

If the objects were simple, I could do it by union() with some "cover
objects", but they aren't.

If I could do the holes last, it would (partly, but not guaranteed) help,
but I can't as I have other later stages which requires them to be there.

Likewise, bouncing an offset out and back won't work, as it'll affect
corners.

So, any idea on how one could do an outline() module?



--
Sent from: http://forum.openscad.org/

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: How to get an outline of a 2D object?

Troberg
In reply to this post by Ronaldo
Ronaldo wrote

> I don't have a general solution to your problem but if the polygon you
> want
> has some properties there is a way to find it.
>
> The simpler case (besides a convex polygon) happens when the polygon has a
> "visual center", that is an inner point from which all vertices can be
> seen
> from inside. The solution for those cases is just to translate the polygon
> so that the center goes to the origin, then extrude it with a scale nearly
> zero, project it back to the xy plane and translating it back to the
> center.

Really neat, but, sadly, my shapes doesn't (usually) have such a center,
being, in part, composed of arch-like segments.

Some examples of what I do here (not too explicit, but don't look on a work
computer):
https://beguilingtorments.com/ElMachoGrande/img/toys_notbuilt/en_toys_notbuilt.html



--
Sent from: http://forum.openscad.org/

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: How to get an outline of a 2D object?

acwest
In reply to this post by Troberg
My solution to this was annoyingly crude, I wrote my modules with two boolean parameters, includeHoles and includeOutlines, then use if statements inside the module to enable the appropriate shapes inside the module

On Sat, 14 Nov 2020, 14:36 Troberg, <[hidden email]> wrote:
I have a problem. I have 2D objects, which might be concave, and which has
holes in them. These objects are pretty complex, done in several stages, and
the holes are made in a pretty early part of the process, and the holes may
(or may not) also affect the shape of the outline.

What I want is to get just the outer contour of the object, without the
holes contained fully within, to create masks for other stages in the
production.

If I knew the objects were convex, it wouldn't be a problem, then hull()
would work, but I cannot rely on them to be convex (in fact, they most
certainly aren't).

If the objects were simple, I could do it by union() with some "cover
objects", but they aren't.

If I could do the holes last, it would (partly, but not guaranteed) help,
but I can't as I have other later stages which requires them to be there.

Likewise, bouncing an offset out and back won't work, as it'll affect
corners.

So, any idea on how one could do an outline() module?



--
Sent from: http://forum.openscad.org/

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: How to get an outline of a 2D object?

Troberg
acwest wrote
> My solution to this was annoyingly crude, I wrote my modules with two
> boolean parameters, includeHoles and includeOutlines, then use if
> statements inside the module to enable the appropriate shapes inside the
> module

If it's just simple holes, then, sure, but when they affect the shape of the
final object (using offset()), it's not that simple.

I rely on offset() a lot to produce smooth, almost organic looking shapes.



--
Sent from: http://forum.openscad.org/

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
dpa
Reply | Threaded
Open this post in threaded view
|

Re: How to get an outline of a 2D object?

dpa
I don't know if this was discussed already, this is also not 100% clean: offset() could close your internal things. The problem is that it may deform sharp notches

offset(r= -offsetsize) // set back the offset
offset(r=  offsetsize) // make a lot of offset
2Dobject();

example attached

Am Di., 17. Nov. 2020 um 13:34 Uhr schrieb Troberg <[hidden email]>:
acwest wrote
> My solution to this was annoyingly crude, I wrote my modules with two
> boolean parameters, includeHoles and includeOutlines, then use if
> statements inside the module to enable the appropriate shapes inside the
> module

If it's just simple holes, then, sure, but when they affect the shape of the
final object (using offset()), it's not that simple.

I rely on offset() a lot to produce smooth, almost organic looking shapes.



--
Sent from: http://forum.openscad.org/

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org

Howtogetanoutlineofa2Dobject.scad (558 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: How to get an outline of a 2D object?

Ronaldo
In reply to this post by Troberg
Nice designs,

I guess that if you could collect all arc and circle center points in a list P, fill_holes2(P) would give you the outline you want.

Em ter., 17 de nov. de 2020 às 06:37, Troberg <[hidden email]> escreveu:
Ronaldo wrote
> I don't have a general solution to your problem but if the polygon you
> want
> has some properties there is a way to find it.
>
> The simpler case (besides a convex polygon) happens when the polygon has a
> "visual center", that is an inner point from which all vertices can be
> seen
> from inside. The solution for those cases is just to translate the polygon
> so that the center goes to the origin, then extrude it with a scale nearly
> zero, project it back to the xy plane and translating it back to the
> center.

Really neat, but, sadly, my shapes doesn't (usually) have such a center,
being, in part, composed of arch-like segments.

Some examples of what I do here (not too explicit, but don't look on a work
computer):
https://beguilingtorments.com/ElMachoGrande/img/toys_notbuilt/en_toys_notbuilt.html


_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: How to get an outline of a 2D object?

Parkinbot
In reply to this post by Ronaldo
Ronaldo wrote
> I don't have a general solution to your problem but if the polygon you
> want
> has some properties there is a way to find it.

this was also my first thought. As long as the origin is within the polygon
it is enough to write:

projection()
linear_extrude(height = 1, scale =0)
convex_with_hole();

all other cases can easily be done with the boundingbox() function the
OpenSCAD community has been waiting for years now.





--
Sent from: http://forum.openscad.org/

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: How to get an outline of a 2D object?

Ronaldo
My last suggestion doesn't work.

What will you do if you had the bounding box?

A terça, 17/11/2020, 20:52, Parkinbot <[hidden email]> escreveu:
Ronaldo wrote
> I don't have a general solution to your problem but if the polygon you
> want
> has some properties there is a way to find it.

this was also my first thought. As long as the origin is within the polygon
it is enough to write:

projection()
linear_extrude(height = 1, scale =0)
convex_with_hole();

all other cases can easily be done with the boundingbox() function the
OpenSCAD community has been waiting for years now.

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: How to get an outline of a 2D object?

Parkinbot
A boundingbox function would probably return me the coordinates of the
diagonal and I could calculate the center and a translation, just like you
do it.

Of course a boundingbox function can also be implemented to just return the
[dx, dy, dz] extents according to the three axes. But this would be the
worst way to implement it. Usually it is implemented to return a pair of
3D-points or a box object with an origin and the [dx, dy, dz] extents.





--
Sent from: http://forum.openscad.org/

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
12