Can you cut a 2D object into two separate parts along a line?

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

Can you cut a 2D object into two separate parts along a line?

highfellow
I am looking for a way, given a 2D object and a cut line that is known to cut the object into two parts, to generate those two parts as 2D objects in a predictable way. I would like the object to be any 2D object, and the cut line to be specified as a vector. The only way I can see of doing it at the moment is to specify the cut as a region that is known to enclose one of the parts, but this is a bit clunky for what I want. Can anyone help?

(The application is a sheet material folding module I am working on: https://github.com/highfellow/openscad-sheet-folder )


Thanks for any help with this.


Andrew Baxter



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

Re: Can you cut a 2D object into two separate parts along a line?

Ronaldo
I published here a few weeks ago a code to find the bounding box of a 3D object. See http://forum.openscad.org/Round-anything-Retrospective-rounding-filleting-module-td21794.html#a21798. The code could be simplifed to find the bounding rectangle of a 2D shape. I don't have my notebook available now to  test it. 

Em 4 de set de 2017 10:36, "Andy Baxter" <[hidden email]> escreveu:
I am looking for a way, given a 2D object and a cut line that is known to cut the object into two parts, to generate those two parts as 2D objects in a predictable way. I would like the object to be any 2D object, and the cut line to be specified as a vector. The only way I can see of doing it at the moment is to specify the cut as a region that is known to enclose one of the parts, but this is a bit clunky for what I want. Can anyone help?

(The application is a sheet material folding module I am working on: https://github.com/highfellow/openscad-sheet-folder )


Thanks for any help with this.


Andrew Baxter



_______________________________________________
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: Can you cut a 2D object into two separate parts along a line?

Ronaldo
In reply to this post by highfellow
​Andrew,

The following code may be a starting point to do what you want. For sake of completeness I included a module ( boundingRect() ) that computes the bounding rectangle of a 2D shape.

// the extent of the children projection on x axis
module xExtent()
    hull() translate([0,1/2])
        projection() rotate([90,0,0])
            linear_extrude(1) children();

// the left extreme of the xExtent of children
module leftExtreme() difference() {
    xExtent() children();
    translate([1,0]) scale([1,1.1])xExtent() children();
}

// the lower left "point" of the children bounding rectangle
module lowerLeft() minkowski() {
    leftExtreme() children(); // X
    rotate(90) leftExtreme() rotate(-90) children(); // Y
}

// the positive part of the xExtent of children
module halfExtent(){
    difference() {
        xExtent() children();
        hull(){
            translate([-1/2,0]) square(1,center=true);
            lowerLeft() xExtent() children();
        }
    }
}

// a bounding rectangle of the part of children 
// that has positive ordinate x
module halfBoundRect() offset(-1/2) minkowski() {
    halfExtent() children();
    rotate(-90) xExtent() rotate(90) children();
}

// the bounding rectangle of children
module boundingRect() offset(-1/2) minkowski() {
        xExtent() children();
        rotate(-90) xExtent() rotate(90) children();
}
      
// a test shape
module shape() translate([2.5,0]){
    rotate(0) square(10,center = true);
    rotate(45) square(10,center = true);
}

%scale([1,1,0.1]) shape();
// the shape positive part
color("red")
intersection(){
    shape(); 
    halfBoundRect() shape();
}




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

Re: Can you cut a 2D object into two separate parts along a line?

jdawgaz
why not use intersection with a block big enough to encompass the 2D object.


--
Extra Ham Operator: K7AZJ
Registered Linux User: 275424
Raspberry Pi and Openscad developer

The most exciting phrase to hear in science - the one that heralds new discoveries - is not "Eureka!" but "That's funny...".
- Isaac. Asimov


On Tue, Sep 5, 2017 at 6:51 PM, Ronaldo Persiano <[hidden email]> wrote:
​Andrew,

The following code may be a starting point to do what you want. For sake of completeness I included a module ( boundingRect() ) that computes the bounding rectangle of a 2D shape.

// the extent of the children projection on x axis
module xExtent()
    hull() translate([0,1/2])
        projection() rotate([90,0,0])
            linear_extrude(1) children();

// the left extreme of the xExtent of children
module leftExtreme() difference() {
    xExtent() children();
    translate([1,0]) scale([1,1.1])xExtent() children();
}

// the lower left "point" of the children bounding rectangle
module lowerLeft() minkowski() {
    leftExtreme() children(); // X
    rotate(90) leftExtreme() rotate(-90) children(); // Y
}

// the positive part of the xExtent of children
module halfExtent(){
    difference() {
        xExtent() children();
        hull(){
            translate([-1/2,0]) square(1,center=true);
            lowerLeft() xExtent() children();
        }
    }
}

// a bounding rectangle of the part of children 
// that has positive ordinate x
module halfBoundRect() offset(-1/2) minkowski() {
    halfExtent() children();
    rotate(-90) xExtent() rotate(90) children();
}

// the bounding rectangle of children
module boundingRect() offset(-1/2) minkowski() {
        xExtent() children();
        rotate(-90) xExtent() rotate(90) children();
}
      
// a test shape
module shape() translate([2.5,0]){
    rotate(0) square(10,center = true);
    rotate(45) square(10,center = true);
}

%scale([1,1,0.1]) shape();
// the shape positive part
color("red")
intersection(){
    shape(); 
    halfBoundRect() shape();
}




_______________________________________________
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: Can you cut a 2D object into two separate parts along a line?

Ronaldo
It would be easier indeed when you know the size of the object. In my experience, however Openscad has unpredictable behavior with very very big and small objects. 

Em 6 de set de 2017 03:06, "Jerry Davis" <[hidden email]> escreveu:
why not use intersection with a block big enough to encompass the 2D object.


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

Re: Can you cut a 2D object into two separate parts along a line?

highfellow
In reply to this post by Ronaldo
Ronaldo,

Thanks for the reply. It's interesting to see how you did this, but it
doesn't really solve my problem.

I am trying to write the module in such a way that it will be useful for
folding any 2D shape that someone can produce using OpenSCAD, including ones
where the part to be folded lies inside a hollow region, or where the
extension of the fold line intersects with other parts of the shape. My own
application for it is for making boxes with a tab and slot construction, but
I want it to be useful to other people as well.

I haven't so far been able to find a generic way of doing this, but I think
what I will do is write the module in such a way that you pass the module a
fold line plus a shape to use for the intersection. This shape
would be specified either as the length of a rectangular region whose base
is the fold line, or if necessary as a more complex polygon. The fold line
wouldn't have to go exactly from one side of the shape being
folded to the other, just to intersect the part of the shape you want to
fold and not any others. This way the module will work in all cases but
still be easy to use in cases with simple geometry.

Cheers,

Andrew Baxter




--
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: Can you cut a 2D object into two separate parts along a line?

Parkinbot
Ronaldo's code was just a hint, how you do it by use of an automated
boundingbox operator. The rest would be vector calculation stuff, which is
trivial.
Here is a solution that intersects with a dumb (but parametrized) square. Is
it this what you are looking for? Otherwise, please show us a drawing of
what you mean.


> // fold operator.
> // A, B are two points on cutting line, rightside controls which side is
> shown. maxsize controls cube size
> module fold(A=[0,0], B=[1,1], rightside = true, maxsize=10000){
>   // construct cube from vector defined by points A, B
>   v = (B-A)/norm(B-A);
>   w = [v[1], -v[0]];
>   dir = rightside?1: -1;
>   C1 = A+maxsize/2*v;
>   C2 = A-maxsize/2*v;
>   C3 = A+dir*w*maxsize - maxsize/2*v;
>   C4 = A+dir*w*maxsize + maxsize/2*v;
>   p = [C1, C2, C3, C4];
>   intersection()
>   {
>     polygon(p);
>     union() children();
>   }
> }
>
> fold(A = [0, 6], B = [6, 3], rightside= true)
> {
>   circle(10);
>   square(18, center = true);
> }





--
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: Can you cut a 2D object into two separate parts along a line?

highfellow
Hi Parkinbot,

The problem with that code is it doesn't deal with cases where the
extension of the fold line intersects other parts of the shape that you
don't want folded. This could happen either because the perimeter of the
shape is not convex, or because the region to be folded lies inside an
internal hole in the shape. I want my module to be able to handle these
cases. I know that it would be possible to specify the part of the shape
to be folded by passing the module a polygon enclosing that part, but
this would make it complicated to use and I would like to avoid it if
possible. It would be neat to be able to specify the folds just as a
list of lines to fold along, specified as a pair of points.

I have a reasonable idea of how I want to write most of the module - see
https://github.com/highfellow/openscad-sheet-folder . I am just stuck on
how to split a 2D object into two along a line. If anyone knows how to
do this that would be great; otherwise I'll have to use a less elegant
way of specifying which part of the shape to fold.

The code I have pasted below is an example of the kind of shape I want
to be able to fold. When folded along the red, green, and blue lines it
would make a simple cardboard box. (Although it really needs some tab
and slot retainers to stop it falling open again).

Cheers,

Andrew Baxter

----- code below ------

width=20;
height=10;
gap=1;
$delta=0.01;

union() {
     for (x=[-1:2:1]) {
         translate([x*(width/2+height+gap*1.5),0,0])
square([height*2+gap+$delta,width], center=true);
     }
     for (y=[-1:2:1]) {
         translate([0,y*(width/2+height/2+gap),0])
square([width*2,height+$delta], center=true);
     }
     difference() {
         square(width + gap*2, center=true);
         for (x=[-1:2:1], y=[-1:2:1]) {
             translate([x*(width/2+gap/2),y*(width/2+gap/2),0])
square(gap+$delta, center=true);
         }
     }
}
color("red") translate([0,0,$delta]) {
     for(x=[-1:2:1]) {
         thinRect([x*width/2,-width/2],[x*width/2,width/2]);
     }
     for(y=[-1:2:1]) {
         thinRect([-width/2,y*width/2],[width/2,y*width/2]);
     }
}

color("green") translate([0,0,$delta]) {
     for(x=[-1:2:1],y=[-1:2:1]) {
thinRect([x*width/2,y*(width/2+gap)],[x*width/2,y*(width/2+height+gap)]);
     }
}

color("blue") translate([0,0,$delta]) {
     for(x=[-1:2:1]) {
thinRect([x*(width+gap/2),-width/2],[x*(width+gap/2),width/2]);
     }
}

module thinRect(start=[0,0],end=[1,1],width=0.2) {
     diff=start-end;
     length=sqrt(diff[0]*diff[0]+diff[1]*diff[1]);
     normal=[diff[1],-diff[0]]/length;
polygon([start-normal*width/2,end-normal*width/2,end+normal*width/2,start+normal*width/2]);
}

On 07/09/17 11:14, Parkinbot wrote:
> Ronaldo's code was just a hint, how you do it by use of an automated
> boundingbox operator. The rest would be vector calculation stuff, which is
> trivial.
> Here is a solution that intersects with a dumb (but parametrized) square. Is
> it this what you are looking for? Otherwise, please show us a drawing of
> what you mean.


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

demo-box.png (20K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Can you cut a 2D object into two separate parts along a line?

Ronaldo
Andy,

That is not the same problem you state at this thread beginning. And it is not a well defined problem. It is clear to me that the cut line is not the only input data you need to solve the problem. But it is by no means clear what else would be needed. If a half-space defined by a line is not satisfactory, an input polygon seems to be the more adequate alternative. Or are you searching for an artificial intelligence algorithm to do it?

2017-09-09 16:18 GMT+01:00 andy <[hidden email]>:
Hi Parkinbot,

The problem with that code is it doesn't deal with cases where the extension of the fold line intersects other parts of the shape that you don't want folded. This could happen either because the perimeter of the shape is not convex, or because the region to be folded lies inside an internal hole in the shape. I want my module to be able to handle these cases. I know that it would be possible to specify the part of the shape to be folded by passing the module a polygon enclosing that part, but this would make it complicated to use and I would like to avoid it if possible. It would be neat to be able to specify the folds just as a list of lines to fold along, specified as a pair of points.

I have a reasonable idea of how I want to write most of the module - see https://github.com/highfellow/openscad-sheet-folder . I am just stuck on how to split a 2D object into two along a line. If anyone knows how to do this that would be great; otherwise I'll have to use a less elegant way of specifying which part of the shape to fold.


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

Re: Can you cut a 2D object into two separate parts along a line?

highfellow
Hi Ronaldo,

Fair comment that I should have specified the problem more clearly to
start with, although I have been trying for several posts now to make it
clear what I was looking for.

I was hoping that there might be some way that I hadn't seen to solve
this problem using just OpenSCAD primitives, but if not then I will have
to use a less neat way to specify the fold lines.

Andy



On 09/09/17 17:35, Ronaldo Persiano wrote:

> Andy,
>
> That is not the same problem you state at this thread beginning. And
> it is not a well defined problem. It is clear to me that the cut line
> is not the only input data you need to solve the problem. But it is by
> no means clear what else would be needed. If a half-space defined by a
> line is not satisfactory, an input polygon seems to be the more
> adequate alternative. Or are you searching for an artificial
> intelligence algorithm to do it?
>
> 2017-09-09 16:18 GMT+01:00 andy <[hidden email]
> <mailto:[hidden email]>>:
>
>     Hi Parkinbot,
>
>     The problem with that code is it doesn't deal with cases where the
>     extension of the fold line intersects other parts of the shape
>     that you don't want folded. This could happen either because the
>     perimeter of the shape is not convex, or because the region to be
>     folded lies inside an internal hole in the shape. I want my module
>     to be able to handle these cases. I know that it would be possible
>     to specify the part of the shape to be folded by passing the
>     module a polygon enclosing that part, but this would make it
>     complicated to use and I would like to avoid it if possible. It
>     would be neat to be able to specify the folds just as a list of
>     lines to fold along, specified as a pair of points.
>
>     I have a reasonable idea of how I want to write most of the module
>     - see https://github.com/highfellow/openscad-sheet-folder
>     <https://github.com/highfellow/openscad-sheet-folder> . I am just
>     stuck on how to split a 2D object into two along a line. If anyone
>     knows how to do this that would be great; otherwise I'll have to
>     use a less elegant way of specifying which part of the shape to fold.
>
>
>
> _______________________________________________
> 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: Can you cut a 2D object into two separate parts along a line?

Parkinbot
In reply to this post by Ronaldo
Ronaldo is right. The problem is not well-defined if you provide just a line
section between two points and want it to cut a 2D object into two pieces.
You will admit that not every pair of two points will define a line section
describing a regular fold. So what should your code do in the following
case:
<http://forum.openscad.org/file/t887/foldit.png>

Will it shorten the fold line at the blue end and extend it on the yellow
end? Not so easy, even if you would specify some well-designed rules for
automated behaviour.
It might work with *simple* polygons and some rule set like "snap each end
of the line section to the nearest point on the polygon outline"... You will
have to add (and implement) a bunch of further rules to avoid
ill-definedness and ambiguities like both ends snapping to the same point,
or something like this:
<http://forum.openscad.org/file/t887/foldit1.png>

These snap rules (which indeed lead into artificial intelligence) are
necessary, because in general your user will not (always) be able to specify
a pair points exactly.

My opinion: Due to its lack of interactiveness, OpenSCAD is not the right
approach to implement such a solution. It will not disclose any vertex
coordinates to you (so you can't use any boolean operations to define your
2D-object) and you will not be able to define a reasonable user interface
other than by editing parameters in code or by customizer.
You could try a 2D-Drawing program with built-in snapping and some scripting
facilities, like Corel Draw. I would use a reasonable language that supports
mouse interactivity and at best allows for GUI application programming.
OpenSCAD is far away from this.




--
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: Can you cut a 2D object into two separate parts along a line?

highfellow
I can see your point, but I was assuming that the user would know enough
about the shape they were feeding into my module to be able to specify a
line that *did* cut the shape into two sections. I'm not expecting the
module to work for all possible combinations of a 2D shape and a line - just
for ones that someone might plausibly want to use my module with.

I was hoping at one point that cutting the shape with a thin rectangle using
the difference() operator would return multiple children in the case where
the operation cut the first child into more than one part, but I have tested
this and it's not the case. I asked the question in the hope that someone
with more experience of OpenSCAD might know some simple hack like this that
would return the result I wanted, but it doesn't look like there is, so I
have an answer to my question at least.

Thanks people for taking the time to reply.


On 09/09/17 19:08, Parkinbot wrote:

> Ronaldo is right. The problem is not well-defined if you provide just a
> line
> section between two points and want it to cut a 2D object into two pieces.
> You will admit that not every pair of two points will define a line
> section
> describing a regular fold. So what should your code do in the following
> case:
> <http://forum.openscad.org/file/t887/foldit.png>
>
> Will it shorten the fold line at the blue end and extend it on the yellow
> end? Not so easy, even if you would specify some well-designed rules for
> automated behaviour.
> It might work with *simple* polygons and some rule set like "snap each end
> of the line section to the nearest point on the polygon outline"... You
> will
> have to add (and implement) a bunch of further rules to avoid
> ill-definedness and ambiguities like both ends snapping to the same point,
> or something like this:
> <http://forum.openscad.org/file/t887/foldit1.png>
>
> These snap rules (which indeed lead into artificial intelligence) are
> necessary, because in general your user will not (always) be able to
> specify
> a pair points exactly.
>
> My opinion: Due to its lack of interactiveness, OpenSCAD is not the right
> approach to implement such a solution. It will not disclose any vertex
> coordinates to you (so you can't use any boolean operations to define your
> 2D-object) and you will not be able to define a reasonable user interface
> other than by editing parameters in code or by customizer.
> You could try a 2D-Drawing program with built-in snapping and some
> scripting
> facilities, like Corel Draw. I would use a reasonable language that
> supports
> mouse interactivity and at best allows for GUI application programming.
> OpenSCAD is far away from this.




--
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: Can you cut a 2D object into two separate parts along a line?

highfellow
In reply to this post by Parkinbot
I can see your point, but I was assuming that the user would know enough
about the shape they were feeding into my module to be able to specify a
line that *did* cut the shape into two sections. I'm not expecting the
module to work for all possible combinations of a 2D shape and a line - just
for ones that someone might plausibly want to use my module with.

I was hoping at one point that cutting the shape with a thin rectangle using
the difference() operator would return multiple children in the case where
the operation cut the first child into more than one part, but I have tested
this and it's not the case. I asked the question in the hope that someone
with more experience of OpenSCAD might know some simple hack like this that
would return the result I wanted, but it doesn't look like there is, so I
have an answer to my question at least.

Thanks people for taking the time to reply.


On 09/09/17 19:08, Parkinbot wrote:

> Ronaldo is right. The problem is not well-defined if you provide just a
> line
> section between two points and want it to cut a 2D object into two pieces.
> You will admit that not every pair of two points will define a line
> section
> describing a regular fold. So what should your code do in the following
> case:
> <http://forum.openscad.org/file/t887/foldit.png>
>
> Will it shorten the fold line at the blue end and extend it on the yellow
> end? Not so easy, even if you would specify some well-designed rules for
> automated behaviour.
> It might work with *simple* polygons and some rule set like "snap each end
> of the line section to the nearest point on the polygon outline"... You
> will
> have to add (and implement) a bunch of further rules to avoid
> ill-definedness and ambiguities like both ends snapping to the same point,
> or something like this:
> <http://forum.openscad.org/file/t887/foldit1.png>
>
> These snap rules (which indeed lead into artificial intelligence) are
> necessary, because in general your user will not (always) be able to
> specify
> a pair points exactly.
>
> My opinion: Due to its lack of interactiveness, OpenSCAD is not the right
> approach to implement such a solution. It will not disclose any vertex
> coordinates to you (so you can't use any boolean operations to define your
> 2D-object) and you will not be able to define a reasonable user interface
> other than by editing parameters in code or by customizer.
> You could try a 2D-Drawing program with built-in snapping and some
> scripting
> facilities, like Corel Draw. I would use a reasonable language that
> supports
> mouse interactivity and at best allows for GUI application programming.
> OpenSCAD is far away from this.




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

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