discuss@lists.openscad.org

OpenSCAD general discussion Mailing-list

View all threads

3D of where 2 shapes intersect

R
Rudolf
Fri, Mar 7, 2025 10:29 AM

OK, I quickly implemented it and it tends to look good. I think my code
is readable for you, even you might not have some my lib functions

w1 = 35;
res1 = intersect( shape1, shape2, w1, w1);
path3 = Rz(0,concat(mid(res1, 0, 31),
mid(res1, 64, 88),
mid(res1, 146, 177),
mid(res1, 203, 227)
));

h = 20;
th=2;
max = Max(path3);
sx=(max[0]-th)/max[0];
sy=(max[1]-th)/max[1];

resA = Tz(h/2, path3);      // outer up
resB = S(sx, sy,1, resA);  // inner up
resC = Tz(-h, resB);      // inner down
resD = Tz(-h, resA);      // outer down

// prepare circular walk
path = [for(i=[0:len(resA)-1])[resA[i],resB[i], resC[i], resD[i]]];

dx = 15;
T(dx)sweep(path, close=true);
Rz(180)T(dx)sweep(path, close=true);

echo($vpr);
$vpr =  [w1, 0, 0];

Am 07.03.2025 um 10:31 schrieb Rudolf via Discuss:

not perfect, but I think viable in your case: you can calculate
scalex, scaley values for the 2D shape that keeps the wall thickness
at least at X and Y axis. Scaling only X,Y coordinates provides you an
inner shape with the same number of points and lets you build a
sequence of squares in the second step which you can use to do a
circular extrude around Z instead of linear extruding along Z.

Am 07.03.2025 um 09:21 schrieb Peter Kriens via Discuss:

I am having one more problem and I can't seem to find a good solution.

I have a closed 3D path. How do I make this into a wall that descents
to the z=0? The problem is that the top must have the Z-variances so
extrudes seem out of the questions. I want the top of the wall to be
flat and be able to parameterize its overall thickness (the current
algorithm that uses difference() can create very steep walls when
angles are high.)

PastedGraphic-7.pngPastedGraphic-9.png

Is there any function in BOSL2 that can do this?

Peter

On 5 Mar 2025, at 11:53, Guenther Sohler via Discuss
discuss@lists.openscad.org wrote:

In PythonSCAD (and potentially soon in OpenSCAD) you could

  1. output mesh  on Object A and  create a list of edges
  2. output mesh on Object B and  create a list of edges
  3. union/difference Object A with B , output mesh and create list of
    edges
  4. select Set of Edges from 3 which are neither in included in 1)
    nor  2)
  5. sum up the lengths of Edges  from 4)

my little 2 cents. I use exactly that algorithm for filling the cut
line of 2 objects

On Thu, Feb 27, 2025 at 10:28 PM Rudolf via Discuss
discuss@lists.openscad.org wrote:

 Hi Peter,

 Adrian was right, it is not such a big drama to compute the
 intersection point of two extruded shapes, as long as they are
 somehow "well-behaved". I extracted the relevant functions and
 modules from my libraries and wrote your function
 *intersect(shape1, shape2, w1, w2)* and some test stuff with
 generic OpenSCAD. Find the scad file attached. The code is
 indeed quite neat and easy to understand. It computes the affine
 intersection of freely translated and rotated 2D-shapes, which
 are assumed to be endless in both directions.

 The function calculates all planes of the faces that delimit
 shape2, intersects each with all lines of shape1 and collects
 and returns only those points that are situated on a face This
 means, two function calls are needed to get hands on all
 intersection points. I leave it up to you to sort the sets
 together. In most cases you will be fine just using the richer set.

 I didn't have the time to protect the code against
 instabilities, mostly singularities from the dot product of two
 parallel vectors. As usual in OpenSCAD tiny-angle rotations or
 tiny-value translations get you around, as shown in the test
 code that produced the second example.

 Hope this helps you along. I'm curious whether it will bring you
 forward with the topology stuff in the paper.

 Rudolf

 // intersect two 2D shapes at an angle w
 function intersect(Sh1, Sh2, w1=w1, w2=w2) =
 let(Sh1 = Rx(w1, Sh1), Sh2 = Rx(w2, Sh2))
 let(N1 =  Rx(w1, [0,0,1]), N2 = Rx(w2, [0,0,1]))
 let(L1 = len(Sh1), L2=len(Sh2))
 let(sign = L1<L2)
 let(result =
   [
     for(i = [0:L2-1], j = [0:L1-1])
     // define the current face of Sh2
     let(P1 = Sh2[i], P2=Sh2[(i+1)%L2])
     let(P3 = P1+N2, P4 = P2+N2)
     let(d = norm(P1-P2))

     // calc the intersection of all lines of Sh1 with current
 face of Sh2
     let(A = Sh1[j], B = A+N1)
       let(I = line_plane_intersection(A, B, P1, P2, P3))
       let(dist1 = distance_point_to_line(P1, P3, I))
       let(dist2 = distance_point_to_line(P2, P4, I))
     // filter points that closely touch the face
       if(dist1+dist2<=d*1.0001)
       I
   ])
   result;


 <nGpKKGbcKaEzok3B.png>


 <ZcA2AgZ5byJR3asr.png>


 Am 22.02.2025 um 17:19 schrieb Peter Kriens via Discuss:
 I am looking for a way to calculate the 3D path where two
 shapes are intersecting. In this case, a shape can be limited
 to a linearly extruded 2D path.

 For example:

 phi = 45;
 union() {
   rotate([0,phi,0])  rotate([0,0,45]) cube([20,20,80],center=true);
   rotate([0,-phi,0]) cylinder(r=14.2,h=80,center=true);
 }

 I would like to have the 3D path indicated in red ...

 <PastedGraphic-1.png>

 I am looking for something like:

 function intersect( a, b, phi ) = ...

 Where an and b are 2D paths of the 2 shapes and phi is 1/2 the
 intersecting angle for an and b. I understand there are 2, I
 want the one closes to the XY plane.

 I am stuck ... anybody ideas or hints? I am using BOSL2 so any
 use of the built in functions would be great.

 BTW, this is related to ambiguous cylinders
 <https://www.youtube.com/watch?v=sQ-Fsv8vVKo>. I want to
 experiment with different shapes but that requires the formula
 to be generic.

 Kind regards,

 Peter Kriens




 _______________________________________________
 OpenSCAD mailing list
 To unsubscribe send an email todiscuss-leave@lists.openscad.org
 _______________________________________________
 OpenSCAD mailing list
 To unsubscribe send an email to discuss-leave@lists.openscad.org

OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email todiscuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email todiscuss-leave@lists.openscad.org

OK, I quickly implemented it and it tends to look good. I think my code is readable for you, even you might not have some my lib functions w1 = 35; res1 = intersect( shape1, shape2, w1, w1); path3 = Rz(0,concat(mid(res1, 0, 31), mid(res1, 64, 88), mid(res1, 146, 177), mid(res1, 203, 227) )); h = 20; th=2; max = Max(path3); sx=(max[0]-th)/max[0]; sy=(max[1]-th)/max[1]; resA = Tz(h/2, path3);      // outer up resB = S(sx, sy,1, resA);  // inner up resC = Tz(-h, resB);      // inner down resD = Tz(-h, resA);      // outer down // prepare circular walk path = [for(i=[0:len(resA)-1])[resA[i],resB[i], resC[i], resD[i]]]; dx = 15; T(dx)sweep(path, close=true); Rz(180)T(dx)sweep(path, close=true); echo($vpr); $vpr =  [w1, 0, 0]; Am 07.03.2025 um 10:31 schrieb Rudolf via Discuss: > > not perfect, but I think viable in your case: you can calculate > scalex, scaley values for the 2D shape that keeps the wall thickness > at least at X and Y axis. Scaling only X,Y coordinates provides you an > inner shape with the same number of points and lets you build a > sequence of squares in the second step which you can use to do a > circular extrude around Z instead of linear extruding along Z. > > > Am 07.03.2025 um 09:21 schrieb Peter Kriens via Discuss: >> I am having one more problem and I can't seem to find a good solution. >> >> I have a closed 3D path. How do I make this into a wall that descents >> to the z=0? The problem is that the top must have the Z-variances so >> extrudes seem out of the questions. I want the top of the wall to be >> flat and be able to parameterize its overall thickness (the current >> algorithm that uses difference() can create very steep walls when >> angles are high.) >> >> PastedGraphic-7.pngPastedGraphic-9.png >> >> >> >> Is there any function in BOSL2 that can do this? >> >> Peter >> >> >>> On 5 Mar 2025, at 11:53, Guenther Sohler via Discuss >>> <discuss@lists.openscad.org> wrote: >>> >>> In PythonSCAD (and potentially soon in OpenSCAD) you could >>> >>> 1) output mesh  on Object A and  create a list of edges >>> 2) output mesh on Object B and  create a list of edges >>> 3) union/difference Object A with B , output mesh and create list of >>> edges >>> 4) select Set of Edges from 3 which are neither in included in 1) >>> nor  2) >>> 5) sum up the lengths of Edges  from 4) >>> >>> my little 2 cents. I use exactly that algorithm for filling the cut >>> line of 2 objects >>> >>> >>> >>> >>> >>> On Thu, Feb 27, 2025 at 10:28 PM Rudolf via Discuss >>> <discuss@lists.openscad.org> wrote: >>> >>> Hi Peter, >>> >>> Adrian was right, it is not such a big drama to compute the >>> intersection point of two extruded shapes, as long as they are >>> somehow "well-behaved". I extracted the relevant functions and >>> modules from my libraries and wrote your function >>> *intersect(shape1, shape2, w1, w2)* and some test stuff with >>> generic OpenSCAD. Find the scad file attached. The code is >>> indeed quite neat and easy to understand. It computes the affine >>> intersection of freely translated and rotated 2D-shapes, which >>> are assumed to be endless in both directions. >>> >>> The function calculates all planes of the faces that delimit >>> shape2, intersects each with all lines of shape1 and collects >>> and returns only those points that are situated on a face This >>> means, two function calls are needed to get hands on all >>> intersection points. I leave it up to you to sort the sets >>> together. In most cases you will be fine just using the richer set. >>> >>> I didn't have the time to protect the code against >>> instabilities, mostly singularities from the dot product of two >>> parallel vectors. As usual in OpenSCAD tiny-angle rotations or >>> tiny-value translations get you around, as shown in the test >>> code that produced the second example. >>> >>> Hope this helps you along. I'm curious whether it will bring you >>> forward with the topology stuff in the paper. >>> >>> Rudolf >>> >>> // intersect two 2D shapes at an angle w >>> function intersect(Sh1, Sh2, w1=w1, w2=w2) = >>> let(Sh1 = Rx(w1, Sh1), Sh2 = Rx(w2, Sh2)) >>> let(N1 =  Rx(w1, [0,0,1]), N2 = Rx(w2, [0,0,1])) >>> let(L1 = len(Sh1), L2=len(Sh2)) >>> let(sign = L1<L2) >>> let(result = >>>   [ >>>     for(i = [0:L2-1], j = [0:L1-1]) >>>     // define the current face of Sh2 >>>     let(P1 = Sh2[i], P2=Sh2[(i+1)%L2]) >>>     let(P3 = P1+N2, P4 = P2+N2) >>>     let(d = norm(P1-P2)) >>> >>>     // calc the intersection of all lines of Sh1 with current >>> face of Sh2 >>>     let(A = Sh1[j], B = A+N1) >>>       let(I = line_plane_intersection(A, B, P1, P2, P3)) >>>       let(dist1 = distance_point_to_line(P1, P3, I)) >>>       let(dist2 = distance_point_to_line(P2, P4, I)) >>>     // filter points that closely touch the face >>>       if(dist1+dist2<=d*1.0001) >>>       I >>>   ]) >>>   result; >>> >>> >>> <nGpKKGbcKaEzok3B.png> >>> >>> >>> <ZcA2AgZ5byJR3asr.png> >>> >>> >>> Am 22.02.2025 um 17:19 schrieb Peter Kriens via Discuss: >>>> I am looking for a way to calculate the 3D path where two >>>> shapes are intersecting. In this case, a shape can be limited >>>> to a linearly extruded 2D path. >>>> >>>> For example: >>>> >>>> phi = 45; >>>> union() { >>>>   rotate([0,phi,0])  rotate([0,0,45]) cube([20,20,80],center=true); >>>>   rotate([0,-phi,0]) cylinder(r=14.2,h=80,center=true); >>>> } >>>> >>>> I would like to have the 3D path indicated in red ... >>>> >>>> <PastedGraphic-1.png> >>>> >>>> I am looking for something like: >>>> >>>> function intersect( a, b, phi ) = ... >>>> >>>> Where an and b are 2D paths of the 2 shapes and phi is 1/2 the >>>> intersecting angle for an and b. I understand there are 2, I >>>> want the one closes to the XY plane. >>>> >>>> I am stuck ... anybody ideas or hints? I am using BOSL2 so any >>>> use of the built in functions would be great. >>>> >>>> BTW, this is related to ambiguous cylinders >>>> <https://www.youtube.com/watch?v=sQ-Fsv8vVKo>. I want to >>>> experiment with different shapes but that requires the formula >>>> to be generic. >>>> >>>> Kind regards, >>>> >>>> Peter Kriens >>>> >>>> >>>> >>>> >>>> _______________________________________________ >>>> OpenSCAD mailing list >>>> To unsubscribe send an email todiscuss-leave@lists.openscad.org >>> _______________________________________________ >>> OpenSCAD mailing list >>> To unsubscribe send an email to discuss-leave@lists.openscad.org >>> >>> _______________________________________________ >>> OpenSCAD mailing list >>> To unsubscribe send an email to discuss-leave@lists.openscad.org >> >> >> _______________________________________________ >> OpenSCAD mailing list >> To unsubscribe send an email todiscuss-leave@lists.openscad.org > > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email todiscuss-leave@lists.openscad.org
R
Rudolf
Fri, Mar 7, 2025 11:11 AM

Its quite funny, best illusions you get with small view angles. Using
w1=5° gets me the following rather weird looking ground shape (middle).

Am 07.03.2025 um 11:29 schrieb Rudolf:

OK, I quickly implemented it and it tends to look good. I think my
code is readable for you, even you might not have some my lib functions

w1 = 35;
res1 = intersect( shape1, shape2, w1, -w1);
path3 = Rz(0,concat(mid(res1, 0, 31),
mid(res1, 64, 88),
mid(res1, 146, 177),
mid(res1, 203, 227)
));

h = 20;
th=2;
max = Max(path3);
sx=(max[0]-th)/max[0];
sy=(max[1]-th)/max[1];

resA = Tz(h/2, path3);      // outer up
resB = S(sx, sy,1, resA);  // inner up
resC = Tz(-h, resB);      // inner down
resD = Tz(-h, resA);      // outer down

// prepare circular walk
path = [for(i=[0:len(resA)-1])[resA[i],resB[i], resC[i], resD[i]]];

dx = 15;
T(dx)sweep(path, close=true);
Rz(180)T(dx)sweep(path, close=true);

echo($vpr);
$vpr =  [w1, 0, 0];

Am 07.03.2025 um 10:31 schrieb Rudolf via Discuss:

not perfect, but I think viable in your case: you can calculate
scalex, scaley values for the 2D shape that keeps the wall thickness
at least at X and Y axis. Scaling only X,Y coordinates provides you
an inner shape with the same number of points and lets you build a
sequence of squares in the second step which you can use to do a
circular extrude around Z instead of linear extruding along Z.

Am 07.03.2025 um 09:21 schrieb Peter Kriens via Discuss:

I am having one more problem and I can't seem to find a good solution.

I have a closed 3D path. How do I make this into a wall that
descents to the z=0? The problem is that the top must have the
Z-variances so extrudes seem out of the questions. I want the top of
the wall to be flat and be able to parameterize its overall
thickness (the current algorithm that uses difference() can create
very steep walls when angles are high.)

PastedGraphic-7.pngPastedGraphic-9.png

Is there any function in BOSL2 that can do this?

Peter

On 5 Mar 2025, at 11:53, Guenther Sohler via Discuss
discuss@lists.openscad.org wrote:

In PythonSCAD (and potentially soon in OpenSCAD) you could

  1. output mesh  on Object A and  create a list of edges
  2. output mesh on Object B and  create a list of edges
  3. union/difference Object A with B , output mesh and create list
    of edges
  4. select Set of Edges from 3 which are neither  in included in 1)
    nor  2)
  5. sum up the lengths of Edges  from 4)

my little 2 cents. I use exactly that algorithm for filling the cut
line of 2 objects

On Thu, Feb 27, 2025 at 10:28 PM Rudolf via Discuss
discuss@lists.openscad.org wrote:

 Hi Peter,

 Adrian was right, it is not such a big drama to compute the
 intersection point of two extruded shapes, as long as they are
 somehow "well-behaved". I extracted the relevant functions and
 modules from my libraries and wrote your function
 *intersect(shape1, shape2, w1, w2)* and some test stuff with
 generic OpenSCAD. Find the scad file attached. The code is
 indeed quite neat and easy to understand. It computes the
 affine intersection of freely translated and rotated 2D-shapes,
 which are assumed to be endless in both directions.

 The function calculates all planes of the faces that delimit
 shape2, intersects each with all lines of shape1 and collects
 and returns only those points that are situated on a face This
 means, two function calls are needed to get hands on all
 intersection points. I leave it up to you to sort the sets
 together. In most cases you will be fine just using the richer
 set.

 I didn't have the time to protect the code against
 instabilities, mostly singularities from the dot product of two
 parallel vectors. As usual in OpenSCAD tiny-angle rotations or
 tiny-value translations get you around, as shown in the test
 code that produced the second example.

 Hope this helps you along. I'm curious whether it will bring
 you forward with the topology stuff in the paper.

 Rudolf

 // intersect two 2D shapes at an angle w
 function intersect(Sh1, Sh2, w1=w1, w2=w2) =
 let(Sh1 = Rx(w1, Sh1), Sh2 = Rx(w2, Sh2))
 let(N1 =  Rx(w1, [0,0,1]), N2 = Rx(w2, [0,0,1]))
 let(L1 = len(Sh1), L2=len(Sh2))
 let(sign = L1<L2)
 let(result =
   [
     for(i = [0:L2-1], j = [0:L1-1])
     // define the current face of Sh2
     let(P1 = Sh2[i], P2=Sh2[(i+1)%L2])
     let(P3 = P1+N2, P4 = P2+N2)
     let(d = norm(P1-P2))

     // calc the intersection of all lines of Sh1 with current
 face of Sh2
     let(A = Sh1[j], B = A+N1)
       let(I = line_plane_intersection(A, B, P1, P2, P3))
       let(dist1 = distance_point_to_line(P1, P3, I))
       let(dist2 = distance_point_to_line(P2, P4, I))
     // filter points that closely touch the face
       if(dist1+dist2<=d*1.0001)
       I
   ])
   result;


 <nGpKKGbcKaEzok3B.png>


 <ZcA2AgZ5byJR3asr.png>


 Am 22.02.2025 um 17:19 schrieb Peter Kriens via Discuss:
 I am looking for a way to calculate the 3D path where two
 shapes are intersecting. In this case, a shape can be limited
 to a linearly extruded 2D path.

 For example:

 phi = 45;
 union() {
   rotate([0,phi,0])  rotate([0,0,45])
 cube([20,20,80],center=true);
   rotate([0,-phi,0]) cylinder(r=14.2,h=80,center=true);
 }

 I would like to have the 3D path indicated in red ...

 <PastedGraphic-1.png>

 I am looking for something like:

 function intersect( a, b, phi ) = ...

 Where an and b are 2D paths of the 2 shapes and phi is 1/2 the
 intersecting angle for an and b. I understand there are 2, I
 want the one closes to the XY plane.

 I am stuck ... anybody ideas or hints? I am using BOSL2 so any
 use of the built in functions would be great.

 BTW, this is related to ambiguous cylinders
 <https://www.youtube.com/watch?v=sQ-Fsv8vVKo>. I want to
 experiment with different shapes but that requires the formula
 to be generic.

 Kind regards,

 Peter Kriens




 _______________________________________________
 OpenSCAD mailing list
 To unsubscribe send an email todiscuss-leave@lists.openscad.org
 _______________________________________________
 OpenSCAD mailing list
 To unsubscribe send an email to discuss-leave@lists.openscad.org

OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email todiscuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email todiscuss-leave@lists.openscad.org

Its quite funny, best illusions you get with small view angles. Using w1=5° gets me the following rather weird looking ground shape (middle). Am 07.03.2025 um 11:29 schrieb Rudolf: > > OK, I quickly implemented it and it tends to look good. I think my > code is readable for you, even you might not have some my lib functions > > > w1 = 35; > res1 = intersect( shape1, shape2, w1, -w1); > path3 = Rz(0,concat(mid(res1, 0, 31), > mid(res1, 64, 88), > mid(res1, 146, 177), > mid(res1, 203, 227) > )); > > h = 20; > th=2; > max = Max(path3); > sx=(max[0]-th)/max[0]; > sy=(max[1]-th)/max[1]; > > resA = Tz(h/2, path3);      // outer up > resB = S(sx, sy,1, resA);  // inner up > resC = Tz(-h, resB);      // inner down > resD = Tz(-h, resA);      // outer down > > // prepare circular walk > path = [for(i=[0:len(resA)-1])[resA[i],resB[i], resC[i], resD[i]]]; > > dx = 15; > T(dx)sweep(path, close=true); > Rz(180)T(dx)sweep(path, close=true); > > echo($vpr); > $vpr =  [w1, 0, 0]; > > Am 07.03.2025 um 10:31 schrieb Rudolf via Discuss: >> >> not perfect, but I think viable in your case: you can calculate >> scalex, scaley values for the 2D shape that keeps the wall thickness >> at least at X and Y axis. Scaling only X,Y coordinates provides you >> an inner shape with the same number of points and lets you build a >> sequence of squares in the second step which you can use to do a >> circular extrude around Z instead of linear extruding along Z. >> >> >> Am 07.03.2025 um 09:21 schrieb Peter Kriens via Discuss: >>> I am having one more problem and I can't seem to find a good solution. >>> >>> I have a closed 3D path. How do I make this into a wall that >>> descents to the z=0? The problem is that the top must have the >>> Z-variances so extrudes seem out of the questions. I want the top of >>> the wall to be flat and be able to parameterize its overall >>> thickness (the current algorithm that uses difference() can create >>> very steep walls when angles are high.) >>> >>> PastedGraphic-7.pngPastedGraphic-9.png >>> >>> >>> >>> Is there any function in BOSL2 that can do this? >>> >>> Peter >>> >>> >>>> On 5 Mar 2025, at 11:53, Guenther Sohler via Discuss >>>> <discuss@lists.openscad.org> wrote: >>>> >>>> In PythonSCAD (and potentially soon in OpenSCAD) you could >>>> >>>> 1) output mesh  on Object A and  create a list of edges >>>> 2) output mesh on Object B and  create a list of edges >>>> 3) union/difference Object A with B , output mesh and create list >>>> of edges >>>> 4) select Set of Edges from 3 which are neither  in included in 1) >>>> nor  2) >>>> 5) sum up the lengths of Edges  from 4) >>>> >>>> my little 2 cents. I use exactly that algorithm for filling the cut >>>> line of 2 objects >>>> >>>> >>>> >>>> >>>> >>>> On Thu, Feb 27, 2025 at 10:28 PM Rudolf via Discuss >>>> <discuss@lists.openscad.org> wrote: >>>> >>>> Hi Peter, >>>> >>>> Adrian was right, it is not such a big drama to compute the >>>> intersection point of two extruded shapes, as long as they are >>>> somehow "well-behaved". I extracted the relevant functions and >>>> modules from my libraries and wrote your function >>>> *intersect(shape1, shape2, w1, w2)* and some test stuff with >>>> generic OpenSCAD. Find the scad file attached. The code is >>>> indeed quite neat and easy to understand. It computes the >>>> affine intersection of freely translated and rotated 2D-shapes, >>>> which are assumed to be endless in both directions. >>>> >>>> The function calculates all planes of the faces that delimit >>>> shape2, intersects each with all lines of shape1 and collects >>>> and returns only those points that are situated on a face This >>>> means, two function calls are needed to get hands on all >>>> intersection points. I leave it up to you to sort the sets >>>> together. In most cases you will be fine just using the richer >>>> set. >>>> >>>> I didn't have the time to protect the code against >>>> instabilities, mostly singularities from the dot product of two >>>> parallel vectors. As usual in OpenSCAD tiny-angle rotations or >>>> tiny-value translations get you around, as shown in the test >>>> code that produced the second example. >>>> >>>> Hope this helps you along. I'm curious whether it will bring >>>> you forward with the topology stuff in the paper. >>>> >>>> Rudolf >>>> >>>> // intersect two 2D shapes at an angle w >>>> function intersect(Sh1, Sh2, w1=w1, w2=w2) = >>>> let(Sh1 = Rx(w1, Sh1), Sh2 = Rx(w2, Sh2)) >>>> let(N1 =  Rx(w1, [0,0,1]), N2 = Rx(w2, [0,0,1])) >>>> let(L1 = len(Sh1), L2=len(Sh2)) >>>> let(sign = L1<L2) >>>> let(result = >>>>   [ >>>>     for(i = [0:L2-1], j = [0:L1-1]) >>>>     // define the current face of Sh2 >>>>     let(P1 = Sh2[i], P2=Sh2[(i+1)%L2]) >>>>     let(P3 = P1+N2, P4 = P2+N2) >>>>     let(d = norm(P1-P2)) >>>> >>>>     // calc the intersection of all lines of Sh1 with current >>>> face of Sh2 >>>>     let(A = Sh1[j], B = A+N1) >>>>       let(I = line_plane_intersection(A, B, P1, P2, P3)) >>>>       let(dist1 = distance_point_to_line(P1, P3, I)) >>>>       let(dist2 = distance_point_to_line(P2, P4, I)) >>>>     // filter points that closely touch the face >>>>       if(dist1+dist2<=d*1.0001) >>>>       I >>>>   ]) >>>>   result; >>>> >>>> >>>> <nGpKKGbcKaEzok3B.png> >>>> >>>> >>>> <ZcA2AgZ5byJR3asr.png> >>>> >>>> >>>> Am 22.02.2025 um 17:19 schrieb Peter Kriens via Discuss: >>>>> I am looking for a way to calculate the 3D path where two >>>>> shapes are intersecting. In this case, a shape can be limited >>>>> to a linearly extruded 2D path. >>>>> >>>>> For example: >>>>> >>>>> phi = 45; >>>>> union() { >>>>>   rotate([0,phi,0])  rotate([0,0,45]) >>>>> cube([20,20,80],center=true); >>>>>   rotate([0,-phi,0]) cylinder(r=14.2,h=80,center=true); >>>>> } >>>>> >>>>> I would like to have the 3D path indicated in red ... >>>>> >>>>> <PastedGraphic-1.png> >>>>> >>>>> I am looking for something like: >>>>> >>>>> function intersect( a, b, phi ) = ... >>>>> >>>>> Where an and b are 2D paths of the 2 shapes and phi is 1/2 the >>>>> intersecting angle for an and b. I understand there are 2, I >>>>> want the one closes to the XY plane. >>>>> >>>>> I am stuck ... anybody ideas or hints? I am using BOSL2 so any >>>>> use of the built in functions would be great. >>>>> >>>>> BTW, this is related to ambiguous cylinders >>>>> <https://www.youtube.com/watch?v=sQ-Fsv8vVKo>. I want to >>>>> experiment with different shapes but that requires the formula >>>>> to be generic. >>>>> >>>>> Kind regards, >>>>> >>>>> Peter Kriens >>>>> >>>>> >>>>> >>>>> >>>>> _______________________________________________ >>>>> OpenSCAD mailing list >>>>> To unsubscribe send an email todiscuss-leave@lists.openscad.org >>>> _______________________________________________ >>>> OpenSCAD mailing list >>>> To unsubscribe send an email to discuss-leave@lists.openscad.org >>>> >>>> _______________________________________________ >>>> OpenSCAD mailing list >>>> To unsubscribe send an email to discuss-leave@lists.openscad.org >>> >>> >>> _______________________________________________ >>> OpenSCAD mailing list >>> To unsubscribe send an email todiscuss-leave@lists.openscad.org >> >> _______________________________________________ >> OpenSCAD mailing list >> To unsubscribe send an email todiscuss-leave@lists.openscad.org
AM
Adrian Mariano
Fri, Mar 7, 2025 11:21 AM

I think something like this using  BOSL2 methods:  Say path is your
starting path.  Project to xy plane with path_proj=path2d(path).  Compute
offset, inside=offset(path_proj,r).  Now map back to the top, inside_top =
hstack(inside, column(path,2)).  Now you have all the coordinates of the
shape and can create it with vnf_vertex_array (or skin), so vnf =
vnf_vertex_array([path, path3d(path_proj), path3d(inside),
inside_top],row_wrap=true).  (I think row_wrap is right, but maybe
col_wrap...)

On Fri, Mar 7, 2025 at 5:29 AM Rudolf via Discuss <
discuss@lists.openscad.org> wrote:

OK, I quickly implemented it and it tends to look good. I think my code is
readable for you, even you might not have some my lib functions

w1 = 35;
res1 = intersect( shape1, shape2, w1, w1);
path3 = Rz(0,concat(mid(res1, 0, 31),
mid(res1, 64, 88),
mid(res1, 146, 177),
mid(res1, 203, 227)
));

h = 20;
th=2;
max = Max(path3);
sx=(max[0]-th)/max[0];
sy=(max[1]-th)/max[1];

resA = Tz(h/2, path3);      // outer up
resB = S(sx, sy,1, resA);  // inner up
resC = Tz(-h, resB);      // inner down
resD = Tz(-h, resA);      // outer down

// prepare circular walk
path = [for(i=[0:len(resA)-1])[resA[i],resB[i], resC[i], resD[i]]];

dx = 15;
T(dx)sweep(path, close=true);
Rz(180)T(dx)sweep(path, close=true);

echo($vpr);
$vpr =  [w1, 0, 0];

Am 07.03.2025 um 10:31 schrieb Rudolf via Discuss:

not perfect, but I think viable in your case: you can calculate scalex,
scaley values for the 2D shape that keeps the wall thickness at least at X
and Y axis. Scaling only X,Y coordinates provides you an inner shape with
the same number of points and lets you build a sequence of squares in the
second step which you can use to do a circular extrude around Z instead of
linear extruding along Z.

Am 07.03.2025 um 09:21 schrieb Peter Kriens via Discuss:

I am having one more problem and I can't seem to find a good solution.

I have a closed 3D path. How do I make this into a wall that descents to
the z=0? The problem is that the top must have the Z-variances so extrudes
seem out of the questions. I want the top of the wall to be flat and be
able to parameterize its overall thickness (the current algorithm that uses
difference() can create very steep walls when angles are high.)

[image: PastedGraphic-7.png][image: PastedGraphic-9.png]

Is there any function in BOSL2 that can do this?

Peter

On 5 Mar 2025, at 11:53, Guenther Sohler via Discuss
discuss@lists.openscad.org discuss@lists.openscad.org wrote:

In PythonSCAD (and potentially soon in OpenSCAD) you could

  1. output mesh  on Object A and  create a list of edges
  2. output mesh on Object B and  create a list of edges
  3. union/difference Object A with B , output mesh and create list of edges
  4. select Set of Edges from 3 which are neither  in included in 1) nor  2)
  5. sum up the lengths of Edges  from 4)

my little 2 cents. I use exactly that algorithm for filling the cut line
of 2 objects

On Thu, Feb 27, 2025 at 10:28 PM Rudolf via Discuss <
discuss@lists.openscad.org> wrote:

Hi Peter,

Adrian was right, it is not such a big drama to compute the intersection
point of two extruded shapes, as long as they are somehow "well-behaved". I
extracted the relevant functions and modules from my libraries and wrote
your function intersect(shape1, shape2, w1, w2) and some test stuff
with generic OpenSCAD. Find the scad file attached. The code is indeed
quite neat and easy to understand. It computes the affine intersection of
freely translated and rotated 2D-shapes, which are assumed to be endless in
both directions.

The function calculates all planes of the faces that delimit shape2,
intersects each with all lines of shape1 and collects and returns only
those points that are situated on a face This means, two function calls are
needed to get hands on all intersection points. I leave it up to you to
sort the sets together. In most cases you will be fine just using the
richer set.

I didn't have the time to protect the code against instabilities, mostly
singularities from the dot product of two parallel vectors. As usual in
OpenSCAD tiny-angle rotations or tiny-value translations get you around, as
shown in the test code that produced the second example.

Hope this helps you along. I'm curious whether it will bring you forward
with the topology stuff in the paper.

Rudolf

// intersect two 2D shapes at an angle w
function intersect(Sh1, Sh2, w1=w1, w2=w2) =
let(Sh1 = Rx(w1, Sh1), Sh2 = Rx(w2, Sh2))
let(N1 =  Rx(w1, [0,0,1]), N2 = Rx(w2, [0,0,1]))
let(L1 = len(Sh1), L2=len(Sh2))
let(sign = L1<L2)
let(result =
[
for(i = [0:L2-1], j = [0:L1-1])
// define the current face of Sh2
let(P1 = Sh2[i], P2=Sh2[(i+1)%L2])
let(P3 = P1+N2, P4 = P2+N2)
let(d = norm(P1-P2))

 // calc the intersection of all lines of Sh1 with current face of Sh2
 let(A = Sh1[j], B = A+N1)
   let(I = line_plane_intersection(A, B, P1, P2, P3))
   let(dist1 = distance_point_to_line(P1, P3, I))
   let(dist2 = distance_point_to_line(P2, P4, I))
 // filter points that closely touch the face
   if(dist1+dist2<=d*1.0001)
   I

])
result;

<nGpKKGbcKaEzok3B.png>

<ZcA2AgZ5byJR3asr.png>

Am 22.02.2025 um 17:19 schrieb Peter Kriens via Discuss:

I am looking for a way to calculate the 3D path where two shapes are
intersecting. In this case, a shape can be limited to a linearly extruded
2D path.

For example:

phi = 45;
union() {
rotate([0,phi,0])  rotate([0,0,45]) cube([20,20,80],center=true);
rotate([0,-phi,0]) cylinder(r=14.2,h=80,center=true);
}

I would like to have the 3D path indicated in red ...

<PastedGraphic-1.png>

I am looking for something like:

function intersect( a, b, phi ) = ...

Where an and b are 2D paths of the 2 shapes and phi is 1/2 the
intersecting angle for an and b. I understand there are 2, I want the one
closes to the XY plane.

I am stuck ... anybody ideas or hints? I am using BOSL2 so any use of the
built in functions would be great.

BTW, this is related to ambiguous cylinders
https://www.youtube.com/watch?v=sQ-Fsv8vVKo. I want to experiment with
different shapes but that requires the formula to be generic.

Kind regards,

Peter Kriens


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org

I think something like this using BOSL2 methods: Say path is your starting path. Project to xy plane with path_proj=path2d(path). Compute offset, inside=offset(path_proj,r). Now map back to the top, inside_top = hstack(inside, column(path,2)). Now you have all the coordinates of the shape and can create it with vnf_vertex_array (or skin), so vnf = vnf_vertex_array([path, path3d(path_proj), path3d(inside), inside_top],row_wrap=true). (I think row_wrap is right, but maybe col_wrap...) On Fri, Mar 7, 2025 at 5:29 AM Rudolf via Discuss < discuss@lists.openscad.org> wrote: > OK, I quickly implemented it and it tends to look good. I think my code is > readable for you, even you might not have some my lib functions > > > w1 = 35; > res1 = intersect( shape1, shape2, w1, w1); > path3 = Rz(0,concat(mid(res1, 0, 31), > mid(res1, 64, 88), > mid(res1, 146, 177), > mid(res1, 203, 227) > )); > > h = 20; > th=2; > max = Max(path3); > sx=(max[0]-th)/max[0]; > sy=(max[1]-th)/max[1]; > > resA = Tz(h/2, path3); // outer up > resB = S(sx, sy,1, resA); // inner up > resC = Tz(-h, resB); // inner down > resD = Tz(-h, resA); // outer down > > // prepare circular walk > path = [for(i=[0:len(resA)-1])[resA[i],resB[i], resC[i], resD[i]]]; > > dx = 15; > T(dx)sweep(path, close=true); > Rz(180)T(dx)sweep(path, close=true); > > echo($vpr); > $vpr = [w1, 0, 0]; > > Am 07.03.2025 um 10:31 schrieb Rudolf via Discuss: > > not perfect, but I think viable in your case: you can calculate scalex, > scaley values for the 2D shape that keeps the wall thickness at least at X > and Y axis. Scaling only X,Y coordinates provides you an inner shape with > the same number of points and lets you build a sequence of squares in the > second step which you can use to do a circular extrude around Z instead of > linear extruding along Z. > > > Am 07.03.2025 um 09:21 schrieb Peter Kriens via Discuss: > > I am having one more problem and I can't seem to find a good solution. > > I have a closed 3D path. How do I make this into a wall that descents to > the z=0? The problem is that the top must have the Z-variances so extrudes > seem out of the questions. I want the top of the wall to be flat and be > able to parameterize its overall thickness (the current algorithm that uses > difference() can create very steep walls when angles are high.) > > [image: PastedGraphic-7.png][image: PastedGraphic-9.png] > > > > Is there any function in BOSL2 that can do this? > > Peter > > > On 5 Mar 2025, at 11:53, Guenther Sohler via Discuss > <discuss@lists.openscad.org> <discuss@lists.openscad.org> wrote: > > In PythonSCAD (and potentially soon in OpenSCAD) you could > > 1) output mesh on Object A and create a list of edges > 2) output mesh on Object B and create a list of edges > 3) union/difference Object A with B , output mesh and create list of edges > 4) select Set of Edges from 3 which are neither in included in 1) nor 2) > 5) sum up the lengths of Edges from 4) > > my little 2 cents. I use exactly that algorithm for filling the cut line > of 2 objects > > > > > > On Thu, Feb 27, 2025 at 10:28 PM Rudolf via Discuss < > discuss@lists.openscad.org> wrote: > >> Hi Peter, >> >> Adrian was right, it is not such a big drama to compute the intersection >> point of two extruded shapes, as long as they are somehow "well-behaved". I >> extracted the relevant functions and modules from my libraries and wrote >> your function *intersect(shape1, shape2, w1, w2)* and some test stuff >> with generic OpenSCAD. Find the scad file attached. The code is indeed >> quite neat and easy to understand. It computes the affine intersection of >> freely translated and rotated 2D-shapes, which are assumed to be endless in >> both directions. >> >> The function calculates all planes of the faces that delimit shape2, >> intersects each with all lines of shape1 and collects and returns only >> those points that are situated on a face This means, two function calls are >> needed to get hands on all intersection points. I leave it up to you to >> sort the sets together. In most cases you will be fine just using the >> richer set. >> >> I didn't have the time to protect the code against instabilities, mostly >> singularities from the dot product of two parallel vectors. As usual in >> OpenSCAD tiny-angle rotations or tiny-value translations get you around, as >> shown in the test code that produced the second example. >> >> Hope this helps you along. I'm curious whether it will bring you forward >> with the topology stuff in the paper. >> >> Rudolf >> >> // intersect two 2D shapes at an angle w >> function intersect(Sh1, Sh2, w1=w1, w2=w2) = >> let(Sh1 = Rx(w1, Sh1), Sh2 = Rx(w2, Sh2)) >> let(N1 = Rx(w1, [0,0,1]), N2 = Rx(w2, [0,0,1])) >> let(L1 = len(Sh1), L2=len(Sh2)) >> let(sign = L1<L2) >> let(result = >> [ >> for(i = [0:L2-1], j = [0:L1-1]) >> // define the current face of Sh2 >> let(P1 = Sh2[i], P2=Sh2[(i+1)%L2]) >> let(P3 = P1+N2, P4 = P2+N2) >> let(d = norm(P1-P2)) >> >> // calc the intersection of all lines of Sh1 with current face of Sh2 >> let(A = Sh1[j], B = A+N1) >> let(I = line_plane_intersection(A, B, P1, P2, P3)) >> let(dist1 = distance_point_to_line(P1, P3, I)) >> let(dist2 = distance_point_to_line(P2, P4, I)) >> // filter points that closely touch the face >> if(dist1+dist2<=d*1.0001) >> I >> ]) >> result; >> >> <nGpKKGbcKaEzok3B.png> >> >> >> <ZcA2AgZ5byJR3asr.png> >> >> >> Am 22.02.2025 um 17:19 schrieb Peter Kriens via Discuss: >> >> I am looking for a way to calculate the 3D path where two shapes are >> intersecting. In this case, a shape can be limited to a linearly extruded >> 2D path. >> >> For example: >> >> phi = 45; >> union() { >> rotate([0,phi,0]) rotate([0,0,45]) cube([20,20,80],center=true); >> rotate([0,-phi,0]) cylinder(r=14.2,h=80,center=true); >> } >> >> I would like to have the 3D path indicated in red ... >> >> <PastedGraphic-1.png> >> >> I am looking for something like: >> >> function intersect( a, b, phi ) = ... >> >> Where an and b are 2D paths of the 2 shapes and phi is 1/2 the >> intersecting angle for an and b. I understand there are 2, I want the one >> closes to the XY plane. >> >> I am stuck ... anybody ideas or hints? I am using BOSL2 so any use of the >> built in functions would be great. >> >> BTW, this is related to ambiguous cylinders >> <https://www.youtube.com/watch?v=sQ-Fsv8vVKo>. I want to experiment with >> different shapes but that requires the formula to be generic. >> >> Kind regards, >> >> Peter Kriens >> >> >> >> >> _______________________________________________ >> OpenSCAD mailing list >> To unsubscribe send an email to discuss-leave@lists.openscad.org >> >> _______________________________________________ >> OpenSCAD mailing list >> To unsubscribe send an email to discuss-leave@lists.openscad.org >> > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org > > > > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org > > > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org > > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org >
GS
Guenther Sohler
Fri, Mar 7, 2025 12:13 PM

its a great design. is the source code public ?

On Fri, Mar 7, 2025 at 12:22 PM Adrian Mariano via Discuss <
discuss@lists.openscad.org> wrote:

I think something like this using  BOSL2 methods:  Say path is your
starting path.  Project to xy plane with path_proj=path2d(path).  Compute
offset, inside=offset(path_proj,r).  Now map back to the top, inside_top =
hstack(inside, column(path,2)).  Now you have all the coordinates of the
shape and can create it with vnf_vertex_array (or skin), so vnf =
vnf_vertex_array([path, path3d(path_proj), path3d(inside),
inside_top],row_wrap=true).  (I think row_wrap is right, but maybe
col_wrap...)

On Fri, Mar 7, 2025 at 5:29 AM Rudolf via Discuss <
discuss@lists.openscad.org> wrote:

OK, I quickly implemented it and it tends to look good. I think my code
is readable for you, even you might not have some my lib functions

w1 = 35;
res1 = intersect( shape1, shape2, w1, w1);
path3 = Rz(0,concat(mid(res1, 0, 31),
mid(res1, 64, 88),
mid(res1, 146, 177),
mid(res1, 203, 227)
));

h = 20;
th=2;
max = Max(path3);
sx=(max[0]-th)/max[0];
sy=(max[1]-th)/max[1];

resA = Tz(h/2, path3);      // outer up
resB = S(sx, sy,1, resA);  // inner up
resC = Tz(-h, resB);      // inner down
resD = Tz(-h, resA);      // outer down

// prepare circular walk
path = [for(i=[0:len(resA)-1])[resA[i],resB[i], resC[i], resD[i]]];

dx = 15;
T(dx)sweep(path, close=true);
Rz(180)T(dx)sweep(path, close=true);

echo($vpr);
$vpr =  [w1, 0, 0];

Am 07.03.2025 um 10:31 schrieb Rudolf via Discuss:

not perfect, but I think viable in your case: you can calculate scalex,
scaley values for the 2D shape that keeps the wall thickness at least at X
and Y axis. Scaling only X,Y coordinates provides you an inner shape with
the same number of points and lets you build a sequence of squares in the
second step which you can use to do a circular extrude around Z instead of
linear extruding along Z.

Am 07.03.2025 um 09:21 schrieb Peter Kriens via Discuss:

I am having one more problem and I can't seem to find a good solution.

I have a closed 3D path. How do I make this into a wall that descents to
the z=0? The problem is that the top must have the Z-variances so extrudes
seem out of the questions. I want the top of the wall to be flat and be
able to parameterize its overall thickness (the current algorithm that uses
difference() can create very steep walls when angles are high.)

[image: PastedGraphic-7.png][image: PastedGraphic-9.png]

Is there any function in BOSL2 that can do this?

Peter

On 5 Mar 2025, at 11:53, Guenther Sohler via Discuss
discuss@lists.openscad.org discuss@lists.openscad.org wrote:

In PythonSCAD (and potentially soon in OpenSCAD) you could

  1. output mesh  on Object A and  create a list of edges
  2. output mesh on Object B and  create a list of edges
  3. union/difference Object A with B , output mesh and create list of edges
  4. select Set of Edges from 3 which are neither  in included in 1) nor  2)
  5. sum up the lengths of Edges  from 4)

my little 2 cents. I use exactly that algorithm for filling the cut line
of 2 objects

On Thu, Feb 27, 2025 at 10:28 PM Rudolf via Discuss <
discuss@lists.openscad.org> wrote:

Hi Peter,

Adrian was right, it is not such a big drama to compute the intersection
point of two extruded shapes, as long as they are somehow "well-behaved". I
extracted the relevant functions and modules from my libraries and wrote
your function intersect(shape1, shape2, w1, w2) and some test stuff
with generic OpenSCAD. Find the scad file attached. The code is indeed
quite neat and easy to understand. It computes the affine intersection of
freely translated and rotated 2D-shapes, which are assumed to be endless in
both directions.

The function calculates all planes of the faces that delimit shape2,
intersects each with all lines of shape1 and collects and returns only
those points that are situated on a face This means, two function calls are
needed to get hands on all intersection points. I leave it up to you to
sort the sets together. In most cases you will be fine just using the
richer set.

I didn't have the time to protect the code against instabilities, mostly
singularities from the dot product of two parallel vectors. As usual in
OpenSCAD tiny-angle rotations or tiny-value translations get you around, as
shown in the test code that produced the second example.

Hope this helps you along. I'm curious whether it will bring you forward
with the topology stuff in the paper.

Rudolf

// intersect two 2D shapes at an angle w
function intersect(Sh1, Sh2, w1=w1, w2=w2) =
let(Sh1 = Rx(w1, Sh1), Sh2 = Rx(w2, Sh2))
let(N1 =  Rx(w1, [0,0,1]), N2 = Rx(w2, [0,0,1]))
let(L1 = len(Sh1), L2=len(Sh2))
let(sign = L1<L2)
let(result =
[
for(i = [0:L2-1], j = [0:L1-1])
// define the current face of Sh2
let(P1 = Sh2[i], P2=Sh2[(i+1)%L2])
let(P3 = P1+N2, P4 = P2+N2)
let(d = norm(P1-P2))

 // calc the intersection of all lines of Sh1 with current face of Sh2
 let(A = Sh1[j], B = A+N1)
   let(I = line_plane_intersection(A, B, P1, P2, P3))
   let(dist1 = distance_point_to_line(P1, P3, I))
   let(dist2 = distance_point_to_line(P2, P4, I))
 // filter points that closely touch the face
   if(dist1+dist2<=d*1.0001)
   I

])
result;

<nGpKKGbcKaEzok3B.png>

<ZcA2AgZ5byJR3asr.png>

Am 22.02.2025 um 17:19 schrieb Peter Kriens via Discuss:

I am looking for a way to calculate the 3D path where two shapes are
intersecting. In this case, a shape can be limited to a linearly extruded
2D path.

For example:

phi = 45;
union() {
rotate([0,phi,0])  rotate([0,0,45]) cube([20,20,80],center=true);
rotate([0,-phi,0]) cylinder(r=14.2,h=80,center=true);
}

I would like to have the 3D path indicated in red ...

<PastedGraphic-1.png>

I am looking for something like:

function intersect( a, b, phi ) = ...

Where an and b are 2D paths of the 2 shapes and phi is 1/2 the
intersecting angle for an and b. I understand there are 2, I want the one
closes to the XY plane.

I am stuck ... anybody ideas or hints? I am using BOSL2 so any use of
the built in functions would be great.

BTW, this is related to ambiguous cylinders
https://www.youtube.com/watch?v=sQ-Fsv8vVKo. I want to experiment
with different shapes but that requires the formula to be generic.

Kind regards,

Peter Kriens


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org

its a great design. is the source code public ? On Fri, Mar 7, 2025 at 12:22 PM Adrian Mariano via Discuss < discuss@lists.openscad.org> wrote: > I think something like this using BOSL2 methods: Say path is your > starting path. Project to xy plane with path_proj=path2d(path). Compute > offset, inside=offset(path_proj,r). Now map back to the top, inside_top = > hstack(inside, column(path,2)). Now you have all the coordinates of the > shape and can create it with vnf_vertex_array (or skin), so vnf = > vnf_vertex_array([path, path3d(path_proj), path3d(inside), > inside_top],row_wrap=true). (I think row_wrap is right, but maybe > col_wrap...) > > On Fri, Mar 7, 2025 at 5:29 AM Rudolf via Discuss < > discuss@lists.openscad.org> wrote: > >> OK, I quickly implemented it and it tends to look good. I think my code >> is readable for you, even you might not have some my lib functions >> >> >> w1 = 35; >> res1 = intersect( shape1, shape2, w1, w1); >> path3 = Rz(0,concat(mid(res1, 0, 31), >> mid(res1, 64, 88), >> mid(res1, 146, 177), >> mid(res1, 203, 227) >> )); >> >> h = 20; >> th=2; >> max = Max(path3); >> sx=(max[0]-th)/max[0]; >> sy=(max[1]-th)/max[1]; >> >> resA = Tz(h/2, path3); // outer up >> resB = S(sx, sy,1, resA); // inner up >> resC = Tz(-h, resB); // inner down >> resD = Tz(-h, resA); // outer down >> >> // prepare circular walk >> path = [for(i=[0:len(resA)-1])[resA[i],resB[i], resC[i], resD[i]]]; >> >> dx = 15; >> T(dx)sweep(path, close=true); >> Rz(180)T(dx)sweep(path, close=true); >> >> echo($vpr); >> $vpr = [w1, 0, 0]; >> >> Am 07.03.2025 um 10:31 schrieb Rudolf via Discuss: >> >> not perfect, but I think viable in your case: you can calculate scalex, >> scaley values for the 2D shape that keeps the wall thickness at least at X >> and Y axis. Scaling only X,Y coordinates provides you an inner shape with >> the same number of points and lets you build a sequence of squares in the >> second step which you can use to do a circular extrude around Z instead of >> linear extruding along Z. >> >> >> Am 07.03.2025 um 09:21 schrieb Peter Kriens via Discuss: >> >> I am having one more problem and I can't seem to find a good solution. >> >> I have a closed 3D path. How do I make this into a wall that descents to >> the z=0? The problem is that the top must have the Z-variances so extrudes >> seem out of the questions. I want the top of the wall to be flat and be >> able to parameterize its overall thickness (the current algorithm that uses >> difference() can create very steep walls when angles are high.) >> >> [image: PastedGraphic-7.png][image: PastedGraphic-9.png] >> >> >> >> Is there any function in BOSL2 that can do this? >> >> Peter >> >> >> On 5 Mar 2025, at 11:53, Guenther Sohler via Discuss >> <discuss@lists.openscad.org> <discuss@lists.openscad.org> wrote: >> >> In PythonSCAD (and potentially soon in OpenSCAD) you could >> >> 1) output mesh on Object A and create a list of edges >> 2) output mesh on Object B and create a list of edges >> 3) union/difference Object A with B , output mesh and create list of edges >> 4) select Set of Edges from 3 which are neither in included in 1) nor 2) >> 5) sum up the lengths of Edges from 4) >> >> my little 2 cents. I use exactly that algorithm for filling the cut line >> of 2 objects >> >> >> >> >> >> On Thu, Feb 27, 2025 at 10:28 PM Rudolf via Discuss < >> discuss@lists.openscad.org> wrote: >> >>> Hi Peter, >>> >>> Adrian was right, it is not such a big drama to compute the intersection >>> point of two extruded shapes, as long as they are somehow "well-behaved". I >>> extracted the relevant functions and modules from my libraries and wrote >>> your function *intersect(shape1, shape2, w1, w2)* and some test stuff >>> with generic OpenSCAD. Find the scad file attached. The code is indeed >>> quite neat and easy to understand. It computes the affine intersection of >>> freely translated and rotated 2D-shapes, which are assumed to be endless in >>> both directions. >>> >>> The function calculates all planes of the faces that delimit shape2, >>> intersects each with all lines of shape1 and collects and returns only >>> those points that are situated on a face This means, two function calls are >>> needed to get hands on all intersection points. I leave it up to you to >>> sort the sets together. In most cases you will be fine just using the >>> richer set. >>> >>> I didn't have the time to protect the code against instabilities, mostly >>> singularities from the dot product of two parallel vectors. As usual in >>> OpenSCAD tiny-angle rotations or tiny-value translations get you around, as >>> shown in the test code that produced the second example. >>> >>> Hope this helps you along. I'm curious whether it will bring you forward >>> with the topology stuff in the paper. >>> >>> Rudolf >>> >>> // intersect two 2D shapes at an angle w >>> function intersect(Sh1, Sh2, w1=w1, w2=w2) = >>> let(Sh1 = Rx(w1, Sh1), Sh2 = Rx(w2, Sh2)) >>> let(N1 = Rx(w1, [0,0,1]), N2 = Rx(w2, [0,0,1])) >>> let(L1 = len(Sh1), L2=len(Sh2)) >>> let(sign = L1<L2) >>> let(result = >>> [ >>> for(i = [0:L2-1], j = [0:L1-1]) >>> // define the current face of Sh2 >>> let(P1 = Sh2[i], P2=Sh2[(i+1)%L2]) >>> let(P3 = P1+N2, P4 = P2+N2) >>> let(d = norm(P1-P2)) >>> >>> // calc the intersection of all lines of Sh1 with current face of Sh2 >>> let(A = Sh1[j], B = A+N1) >>> let(I = line_plane_intersection(A, B, P1, P2, P3)) >>> let(dist1 = distance_point_to_line(P1, P3, I)) >>> let(dist2 = distance_point_to_line(P2, P4, I)) >>> // filter points that closely touch the face >>> if(dist1+dist2<=d*1.0001) >>> I >>> ]) >>> result; >>> >>> <nGpKKGbcKaEzok3B.png> >>> >>> >>> <ZcA2AgZ5byJR3asr.png> >>> >>> >>> Am 22.02.2025 um 17:19 schrieb Peter Kriens via Discuss: >>> >>> I am looking for a way to calculate the 3D path where two shapes are >>> intersecting. In this case, a shape can be limited to a linearly extruded >>> 2D path. >>> >>> For example: >>> >>> phi = 45; >>> union() { >>> rotate([0,phi,0]) rotate([0,0,45]) cube([20,20,80],center=true); >>> rotate([0,-phi,0]) cylinder(r=14.2,h=80,center=true); >>> } >>> >>> I would like to have the 3D path indicated in red ... >>> >>> <PastedGraphic-1.png> >>> >>> I am looking for something like: >>> >>> function intersect( a, b, phi ) = ... >>> >>> Where an and b are 2D paths of the 2 shapes and phi is 1/2 the >>> intersecting angle for an and b. I understand there are 2, I want the one >>> closes to the XY plane. >>> >>> I am stuck ... anybody ideas or hints? I am using BOSL2 so any use of >>> the built in functions would be great. >>> >>> BTW, this is related to ambiguous cylinders >>> <https://www.youtube.com/watch?v=sQ-Fsv8vVKo>. I want to experiment >>> with different shapes but that requires the formula to be generic. >>> >>> Kind regards, >>> >>> Peter Kriens >>> >>> >>> >>> >>> _______________________________________________ >>> OpenSCAD mailing list >>> To unsubscribe send an email to discuss-leave@lists.openscad.org >>> >>> _______________________________________________ >>> OpenSCAD mailing list >>> To unsubscribe send an email to discuss-leave@lists.openscad.org >>> >> _______________________________________________ >> OpenSCAD mailing list >> To unsubscribe send an email to discuss-leave@lists.openscad.org >> >> >> >> _______________________________________________ >> OpenSCAD mailing list >> To unsubscribe send an email to discuss-leave@lists.openscad.org >> >> >> _______________________________________________ >> OpenSCAD mailing list >> To unsubscribe send an email to discuss-leave@lists.openscad.org >> >> _______________________________________________ >> OpenSCAD mailing list >> To unsubscribe send an email to discuss-leave@lists.openscad.org >> > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org >
R
Rudolf
Fri, Mar 7, 2025 2:43 PM

The source code is all public. It is a question of bundling all pieces
into a single project and the question whether you are on BOSL2. I
personally don't. As it is Peter's thread he will have an opinion about
it and might wanna "release" it.

Just a note concerning my screenshot. It was made with 10° Z-rotate,
which I introduced when playing with the design.

Without any rotation you get a symmetric design as expected.

@Adrian. Using an offset(-d) on the 2D projection of the path is more
straight forward, but it might reduce your edge count and thus bring
some trouble when trying to do the rotate extrusion.

Am 07.03.2025 um 13:13 schrieb Guenther Sohler via Discuss:

its a great design. is the source code public ?

On Fri, Mar 7, 2025 at 12:22 PM Adrian Mariano via Discuss
discuss@lists.openscad.org wrote:

 I think something like this using  BOSL2 methods:  Say path is
 your starting path.  Project to xy plane with
 path_proj=path2d(path).  Compute offset,
 inside=offset(path_proj,r).  Now map back to the top, inside_top =
 hstack(inside, column(path,2)).  Now you have all the coordinates
 of the shape and can create it with vnf_vertex_array (or skin), so
 vnf = vnf_vertex_array([path, path3d(path_proj), path3d(inside),
 inside_top],row_wrap=true).   (I think row_wrap is right, but
 maybe col_wrap...)

 On Fri, Mar 7, 2025 at 5:29 AM Rudolf via Discuss
 <discuss@lists.openscad.org> wrote:

     OK, I quickly implemented it and it tends to look good. I
     think my code is readable for you, even you might not have
     some my lib functions


     w1 = 35;
     res1 = intersect( shape1, shape2, w1, w1);
     path3 = Rz(0,concat(mid(res1, 0, 31),
     mid(res1, 64, 88),
     mid(res1, 146, 177),
     mid(res1, 203, 227)
     ));

     h = 20;
     th=2;
     max = Max(path3);
     sx=(max[0]-th)/max[0];
     sy=(max[1]-th)/max[1];

     resA = Tz(h/2, path3);      // outer up
     resB = S(sx, sy,1, resA);  // inner up
     resC = Tz(-h, resB);      // inner down
     resD = Tz(-h, resA);      // outer down

     // prepare circular walk
     path = [for(i=[0:len(resA)-1])[resA[i],resB[i], resC[i],
     resD[i]]];

     dx = 15;
     T(dx)sweep(path, close=true);
     Rz(180)T(dx)sweep(path, close=true);

     echo($vpr);
     $vpr =  [w1, 0, 0];

     Am 07.03.2025 um 10:31 schrieb Rudolf via Discuss:
     not perfect, but I think viable in your case: you can
     calculate scalex, scaley values for the 2D shape that keeps
     the wall thickness at least at X and Y axis. Scaling only X,Y
     coordinates provides you an inner shape with the same number
     of points and lets you build a sequence of squares in the
     second step which you can use to do a circular extrude around
     Z instead of linear extruding along Z.


     Am 07.03.2025 um 09:21 schrieb Peter Kriens via Discuss:
     I am having one more problem and I can't seem to find a good
     solution.

     I have a closed 3D path. How do I make this into a wall that
     descents to the z=0? The problem is that the top must have
     the Z-variances so extrudes seem out of the questions. I
     want the top of the wall to be flat and be able to
     parameterize its overall thickness (the current algorithm
     that uses difference() can create very steep walls when
     angles are high.)

     PastedGraphic-7.pngPastedGraphic-9.png



     Is there any function in BOSL2 that can do this?

     Peter
     On 5 Mar 2025, at 11:53, Guenther Sohler via Discuss
     <discuss@lists.openscad.org>
     <mailto:discuss@lists.openscad.org> wrote:

     In PythonSCAD (and potentially soon in OpenSCAD) you could

     1) output mesh  on Object A and create a list of edges
     2) output mesh on Object B and create a list of edges
     3) union/difference Object A with B , output mesh and
     create list of edges
     4) select Set of Edges from 3 which are neither  in
     included in 1) nor  2)
     5) sum up the lengths of Edges  from 4)

     my little 2 cents. I use exactly that algorithm for filling
     the cut line of 2 objects





     On Thu, Feb 27, 2025 at 10:28 PM Rudolf via Discuss
     <discuss@lists.openscad.org> wrote:

         Hi Peter,

         Adrian was right, it is not such a big drama to compute
         the intersection point of two extruded shapes, as long
         as they are somehow "well-behaved". I extracted the
         relevant functions and modules from my libraries and
         wrote your function *intersect(shape1, shape2, w1, w2)*
         and some test stuff with generic OpenSCAD. Find the
         scad file attached. The code is indeed quite neat and
         easy to understand. It computes the affine intersection
         of freely translated and rotated 2D-shapes, which are
         assumed to be endless in both directions.

         The function calculates all planes of the faces that
         delimit shape2, intersects each with all lines of
         shape1 and collects and returns only those points that
         are situated on a face This means, two function calls
         are needed to get hands on all intersection points. I
         leave it up to you to sort the sets together. In most
         cases you will be fine just using the richer set.

         I didn't have the time to protect the code against
         instabilities, mostly singularities from the dot
         product of two parallel vectors. As usual in OpenSCAD
         tiny-angle rotations or tiny-value translations get you
         around, as shown in the test code that produced the
         second example.

         Hope this helps you along. I'm curious whether it will
         bring you forward with the topology stuff in the paper.

         Rudolf

         // intersect two 2D shapes at an angle w
         function intersect(Sh1, Sh2, w1=w1, w2=w2) =
         let(Sh1 = Rx(w1, Sh1), Sh2 = Rx(w2, Sh2))
         let(N1 =  Rx(w1, [0,0,1]), N2 = Rx(w2, [0,0,1]))
         let(L1 = len(Sh1), L2=len(Sh2))
         let(sign = L1<L2)
         let(result =
           [
             for(i = [0:L2-1], j = [0:L1-1])
             // define the current face of Sh2
             let(P1 = Sh2[i], P2=Sh2[(i+1)%L2])
             let(P3 = P1+N2, P4 = P2+N2)
             let(d = norm(P1-P2))

             // calc the intersection of all lines of Sh1 with
         current face of Sh2
             let(A = Sh1[j], B = A+N1)
               let(I = line_plane_intersection(A, B, P1, P2, P3))
               let(dist1 = distance_point_to_line(P1, P3, I))
               let(dist2 = distance_point_to_line(P2, P4, I))
             // filter points that closely touch the face
               if(dist1+dist2<=d*1.0001)
               I
           ])
           result;


         <nGpKKGbcKaEzok3B.png>


         <ZcA2AgZ5byJR3asr.png>


         Am 22.02.2025 um 17:19 schrieb Peter Kriens via Discuss:
         I am looking for a way to calculate the 3D path where
         two shapes are intersecting. In this case, a shape can
         be limited to a linearly extruded 2D path.

         For example:

         phi = 45;
         union() {
           rotate([0,phi,0])  rotate([0,0,45])
         cube([20,20,80],center=true);
           rotate([0,-phi,0]) cylinder(r=14.2,h=80,center=true);
         }

         I would like to have the 3D path indicated in red ...

         <PastedGraphic-1.png>

         I am looking for something like:

         function intersect( a, b, phi ) = ...

         Where an and b are 2D paths of the 2 shapes and phi is
         1/2 the intersecting angle for an and b. I understand
         there are 2, I want the one closes to the XY plane.

         I am stuck ... anybody ideas or hints? I am using
         BOSL2 so any use of the built in functions would be great.

         BTW, this is related to ambiguous cylinders
         <https://www.youtube.com/watch?v=sQ-Fsv8vVKo>. I want
         to experiment with different shapes but that requires
         the formula to be generic.

         Kind regards,

         Peter Kriens




         _______________________________________________
         OpenSCAD mailing list
         To unsubscribe send an email todiscuss-leave@lists.openscad.org
         _______________________________________________
         OpenSCAD mailing list
         To unsubscribe send an email to
         discuss-leave@lists.openscad.org

     _______________________________________________
     OpenSCAD mailing list
     To unsubscribe send an email to
     discuss-leave@lists.openscad.org
     _______________________________________________
     OpenSCAD mailing list
     To unsubscribe send an email todiscuss-leave@lists.openscad.org
     _______________________________________________
     OpenSCAD mailing list
     To unsubscribe send an email todiscuss-leave@lists.openscad.org
     _______________________________________________
     OpenSCAD mailing list
     To unsubscribe send an email to discuss-leave@lists.openscad.org

 _______________________________________________
 OpenSCAD mailing list
 To unsubscribe send an email to discuss-leave@lists.openscad.org

OpenSCAD mailing list
To unsubscribe send an email todiscuss-leave@lists.openscad.org

The source code is all public. It is a question of bundling all pieces into a single project and the question whether you are on BOSL2. I personally don't. As it is Peter's thread he will have an opinion about it and might wanna "release" it. Just a note concerning my screenshot. It was made with 10° Z-rotate, which I introduced when playing with the design. Without any rotation you get a symmetric design as expected. @Adrian. Using an offset(-d) on the 2D projection of the path is more straight forward, but it might reduce your edge count and thus bring some trouble when trying to do the rotate extrusion. Am 07.03.2025 um 13:13 schrieb Guenther Sohler via Discuss: > its a great design. is the source code public ? > > On Fri, Mar 7, 2025 at 12:22 PM Adrian Mariano via Discuss > <discuss@lists.openscad.org> wrote: > > I think something like this using  BOSL2 methods:  Say path is > your starting path.  Project to xy plane with > path_proj=path2d(path).  Compute offset, > inside=offset(path_proj,r).  Now map back to the top, inside_top = > hstack(inside, column(path,2)).  Now you have all the coordinates > of the shape and can create it with vnf_vertex_array (or skin), so > vnf = vnf_vertex_array([path, path3d(path_proj), path3d(inside), > inside_top],row_wrap=true).   (I think row_wrap is right, but > maybe col_wrap...) > > On Fri, Mar 7, 2025 at 5:29 AM Rudolf via Discuss > <discuss@lists.openscad.org> wrote: > > OK, I quickly implemented it and it tends to look good. I > think my code is readable for you, even you might not have > some my lib functions > > > w1 = 35; > res1 = intersect( shape1, shape2, w1, w1); > path3 = Rz(0,concat(mid(res1, 0, 31), > mid(res1, 64, 88), > mid(res1, 146, 177), > mid(res1, 203, 227) > )); > > h = 20; > th=2; > max = Max(path3); > sx=(max[0]-th)/max[0]; > sy=(max[1]-th)/max[1]; > > resA = Tz(h/2, path3);      // outer up > resB = S(sx, sy,1, resA);  // inner up > resC = Tz(-h, resB);      // inner down > resD = Tz(-h, resA);      // outer down > > // prepare circular walk > path = [for(i=[0:len(resA)-1])[resA[i],resB[i], resC[i], > resD[i]]]; > > dx = 15; > T(dx)sweep(path, close=true); > Rz(180)T(dx)sweep(path, close=true); > > echo($vpr); > $vpr =  [w1, 0, 0]; > > Am 07.03.2025 um 10:31 schrieb Rudolf via Discuss: >> >> not perfect, but I think viable in your case: you can >> calculate scalex, scaley values for the 2D shape that keeps >> the wall thickness at least at X and Y axis. Scaling only X,Y >> coordinates provides you an inner shape with the same number >> of points and lets you build a sequence of squares in the >> second step which you can use to do a circular extrude around >> Z instead of linear extruding along Z. >> >> >> Am 07.03.2025 um 09:21 schrieb Peter Kriens via Discuss: >>> I am having one more problem and I can't seem to find a good >>> solution. >>> >>> I have a closed 3D path. How do I make this into a wall that >>> descents to the z=0? The problem is that the top must have >>> the Z-variances so extrudes seem out of the questions. I >>> want the top of the wall to be flat and be able to >>> parameterize its overall thickness (the current algorithm >>> that uses difference() can create very steep walls when >>> angles are high.) >>> >>> PastedGraphic-7.pngPastedGraphic-9.png >>> >>> >>> >>> Is there any function in BOSL2 that can do this? >>> >>> Peter >>> >>> >>>> On 5 Mar 2025, at 11:53, Guenther Sohler via Discuss >>>> <discuss@lists.openscad.org> >>>> <mailto:discuss@lists.openscad.org> wrote: >>>> >>>> In PythonSCAD (and potentially soon in OpenSCAD) you could >>>> >>>> 1) output mesh  on Object A and create a list of edges >>>> 2) output mesh on Object B and create a list of edges >>>> 3) union/difference Object A with B , output mesh and >>>> create list of edges >>>> 4) select Set of Edges from 3 which are neither  in >>>> included in 1) nor  2) >>>> 5) sum up the lengths of Edges  from 4) >>>> >>>> my little 2 cents. I use exactly that algorithm for filling >>>> the cut line of 2 objects >>>> >>>> >>>> >>>> >>>> >>>> On Thu, Feb 27, 2025 at 10:28 PM Rudolf via Discuss >>>> <discuss@lists.openscad.org> wrote: >>>> >>>> Hi Peter, >>>> >>>> Adrian was right, it is not such a big drama to compute >>>> the intersection point of two extruded shapes, as long >>>> as they are somehow "well-behaved". I extracted the >>>> relevant functions and modules from my libraries and >>>> wrote your function *intersect(shape1, shape2, w1, w2)* >>>> and some test stuff with generic OpenSCAD. Find the >>>> scad file attached. The code is indeed quite neat and >>>> easy to understand. It computes the affine intersection >>>> of freely translated and rotated 2D-shapes, which are >>>> assumed to be endless in both directions. >>>> >>>> The function calculates all planes of the faces that >>>> delimit shape2, intersects each with all lines of >>>> shape1 and collects and returns only those points that >>>> are situated on a face This means, two function calls >>>> are needed to get hands on all intersection points. I >>>> leave it up to you to sort the sets together. In most >>>> cases you will be fine just using the richer set. >>>> >>>> I didn't have the time to protect the code against >>>> instabilities, mostly singularities from the dot >>>> product of two parallel vectors. As usual in OpenSCAD >>>> tiny-angle rotations or tiny-value translations get you >>>> around, as shown in the test code that produced the >>>> second example. >>>> >>>> Hope this helps you along. I'm curious whether it will >>>> bring you forward with the topology stuff in the paper. >>>> >>>> Rudolf >>>> >>>> // intersect two 2D shapes at an angle w >>>> function intersect(Sh1, Sh2, w1=w1, w2=w2) = >>>> let(Sh1 = Rx(w1, Sh1), Sh2 = Rx(w2, Sh2)) >>>> let(N1 =  Rx(w1, [0,0,1]), N2 = Rx(w2, [0,0,1])) >>>> let(L1 = len(Sh1), L2=len(Sh2)) >>>> let(sign = L1<L2) >>>> let(result = >>>>   [ >>>>     for(i = [0:L2-1], j = [0:L1-1]) >>>>     // define the current face of Sh2 >>>>     let(P1 = Sh2[i], P2=Sh2[(i+1)%L2]) >>>>     let(P3 = P1+N2, P4 = P2+N2) >>>>     let(d = norm(P1-P2)) >>>> >>>>     // calc the intersection of all lines of Sh1 with >>>> current face of Sh2 >>>>     let(A = Sh1[j], B = A+N1) >>>>       let(I = line_plane_intersection(A, B, P1, P2, P3)) >>>>       let(dist1 = distance_point_to_line(P1, P3, I)) >>>>       let(dist2 = distance_point_to_line(P2, P4, I)) >>>>     // filter points that closely touch the face >>>>       if(dist1+dist2<=d*1.0001) >>>>       I >>>>   ]) >>>>   result; >>>> >>>> >>>> <nGpKKGbcKaEzok3B.png> >>>> >>>> >>>> <ZcA2AgZ5byJR3asr.png> >>>> >>>> >>>> Am 22.02.2025 um 17:19 schrieb Peter Kriens via Discuss: >>>>> I am looking for a way to calculate the 3D path where >>>>> two shapes are intersecting. In this case, a shape can >>>>> be limited to a linearly extruded 2D path. >>>>> >>>>> For example: >>>>> >>>>> phi = 45; >>>>> union() { >>>>>   rotate([0,phi,0])  rotate([0,0,45]) >>>>> cube([20,20,80],center=true); >>>>>   rotate([0,-phi,0]) cylinder(r=14.2,h=80,center=true); >>>>> } >>>>> >>>>> I would like to have the 3D path indicated in red ... >>>>> >>>>> <PastedGraphic-1.png> >>>>> >>>>> I am looking for something like: >>>>> >>>>> function intersect( a, b, phi ) = ... >>>>> >>>>> Where an and b are 2D paths of the 2 shapes and phi is >>>>> 1/2 the intersecting angle for an and b. I understand >>>>> there are 2, I want the one closes to the XY plane. >>>>> >>>>> I am stuck ... anybody ideas or hints? I am using >>>>> BOSL2 so any use of the built in functions would be great. >>>>> >>>>> BTW, this is related to ambiguous cylinders >>>>> <https://www.youtube.com/watch?v=sQ-Fsv8vVKo>. I want >>>>> to experiment with different shapes but that requires >>>>> the formula to be generic. >>>>> >>>>> Kind regards, >>>>> >>>>> Peter Kriens >>>>> >>>>> >>>>> >>>>> >>>>> _______________________________________________ >>>>> OpenSCAD mailing list >>>>> To unsubscribe send an email todiscuss-leave@lists.openscad.org >>>> _______________________________________________ >>>> OpenSCAD mailing list >>>> To unsubscribe send an email to >>>> discuss-leave@lists.openscad.org >>>> >>>> _______________________________________________ >>>> OpenSCAD mailing list >>>> To unsubscribe send an email to >>>> discuss-leave@lists.openscad.org >>> >>> >>> _______________________________________________ >>> OpenSCAD mailing list >>> To unsubscribe send an email todiscuss-leave@lists.openscad.org >> >> _______________________________________________ >> OpenSCAD mailing list >> To unsubscribe send an email todiscuss-leave@lists.openscad.org > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org > > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org > > > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email todiscuss-leave@lists.openscad.org
AM
Adrian Mariano
Fri, Mar 7, 2025 4:29 PM

The BOSL2 offset has a same_length option so that point count will not
change and the points will align when linked into a 3d object.

On Fri, Mar 7, 2025 at 09:44 Rudolf via Discuss discuss@lists.openscad.org
wrote:

The source code is all public. It is a question of bundling all pieces
into a single project and the question whether you are on BOSL2. I
personally don't. As it is Peter's thread he will have an opinion about it
and might wanna "release" it.

Just a note concerning my screenshot. It was made with 10° Z-rotate, which
I introduced when playing with the design.

Without any rotation you get a symmetric design as expected.

@Adrian. Using an offset(-d) on the 2D projection of the path is more
straight forward, but it might reduce your edge count and thus bring some
trouble when trying to do the rotate extrusion.

Am 07.03.2025 um 13:13 schrieb Guenther Sohler via Discuss:

its a great design. is the source code public ?

On Fri, Mar 7, 2025 at 12:22 PM Adrian Mariano via Discuss <
discuss@lists.openscad.org> wrote:

I think something like this using  BOSL2 methods:  Say path is your
starting path.  Project to xy plane with path_proj=path2d(path).  Compute
offset, inside=offset(path_proj,r).  Now map back to the top, inside_top =
hstack(inside, column(path,2)).  Now you have all the coordinates of the
shape and can create it with vnf_vertex_array (or skin), so vnf =
vnf_vertex_array([path, path3d(path_proj), path3d(inside),
inside_top],row_wrap=true).  (I think row_wrap is right, but maybe
col_wrap...)

On Fri, Mar 7, 2025 at 5:29 AM Rudolf via Discuss <
discuss@lists.openscad.org> wrote:

OK, I quickly implemented it and it tends to look good. I think my code
is readable for you, even you might not have some my lib functions

w1 = 35;
res1 = intersect( shape1, shape2, w1, w1);
path3 = Rz(0,concat(mid(res1, 0, 31),
mid(res1, 64, 88),
mid(res1, 146, 177),
mid(res1, 203, 227)
));

h = 20;
th=2;
max = Max(path3);
sx=(max[0]-th)/max[0];
sy=(max[1]-th)/max[1];

resA = Tz(h/2, path3);      // outer up
resB = S(sx, sy,1, resA);  // inner up
resC = Tz(-h, resB);      // inner down
resD = Tz(-h, resA);      // outer down

// prepare circular walk
path = [for(i=[0:len(resA)-1])[resA[i],resB[i], resC[i], resD[i]]];

dx = 15;
T(dx)sweep(path, close=true);
Rz(180)T(dx)sweep(path, close=true);

echo($vpr);
$vpr =  [w1, 0, 0];

Am 07.03.2025 um 10:31 schrieb Rudolf via Discuss:

not perfect, but I think viable in your case: you can calculate scalex,
scaley values for the 2D shape that keeps the wall thickness at least at X
and Y axis. Scaling only X,Y coordinates provides you an inner shape with
the same number of points and lets you build a sequence of squares in the
second step which you can use to do a circular extrude around Z instead of
linear extruding along Z.

Am 07.03.2025 um 09:21 schrieb Peter Kriens via Discuss:

I am having one more problem and I can't seem to find a good solution.

I have a closed 3D path. How do I make this into a wall that descents to
the z=0? The problem is that the top must have the Z-variances so extrudes
seem out of the questions. I want the top of the wall to be flat and be
able to parameterize its overall thickness (the current algorithm that uses
difference() can create very steep walls when angles are high.)

[image: PastedGraphic-7.png][image: PastedGraphic-9.png]

Is there any function in BOSL2 that can do this?

Peter

On 5 Mar 2025, at 11:53, Guenther Sohler via Discuss
discuss@lists.openscad.org discuss@lists.openscad.org wrote:

In PythonSCAD (and potentially soon in OpenSCAD) you could

  1. output mesh  on Object A and  create a list of edges
  2. output mesh on Object B and  create a list of edges
  3. union/difference Object A with B , output mesh and create list of
    edges
  4. select Set of Edges from 3 which are neither  in included in 1) nor
  5. sum up the lengths of Edges  from 4)

my little 2 cents. I use exactly that algorithm for filling the cut line
of 2 objects

On Thu, Feb 27, 2025 at 10:28 PM Rudolf via Discuss <
discuss@lists.openscad.org> wrote:

Hi Peter,

Adrian was right, it is not such a big drama to compute the
intersection point of two extruded shapes, as long as they are somehow
"well-behaved". I extracted the relevant functions and modules from my
libraries and wrote your function intersect(shape1, shape2, w1, w2)
and some test stuff with generic OpenSCAD. Find the scad file attached. The
code is indeed quite neat and easy to understand. It computes the affine
intersection of freely translated and rotated 2D-shapes, which are assumed
to be endless in both directions.

The function calculates all planes of the faces that delimit shape2,
intersects each with all lines of shape1 and collects and returns only
those points that are situated on a face This means, two function calls are
needed to get hands on all intersection points. I leave it up to you to
sort the sets together. In most cases you will be fine just using the
richer set.

I didn't have the time to protect the code against instabilities,
mostly singularities from the dot product of two parallel vectors. As usual
in OpenSCAD tiny-angle rotations or tiny-value translations get you around,
as shown in the test code that produced the second example.

Hope this helps you along. I'm curious whether it will bring you
forward with the topology stuff in the paper.

Rudolf

// intersect two 2D shapes at an angle w
function intersect(Sh1, Sh2, w1=w1, w2=w2) =
let(Sh1 = Rx(w1, Sh1), Sh2 = Rx(w2, Sh2))
let(N1 =  Rx(w1, [0,0,1]), N2 = Rx(w2, [0,0,1]))
let(L1 = len(Sh1), L2=len(Sh2))
let(sign = L1<L2)
let(result =
[
for(i = [0:L2-1], j = [0:L1-1])
// define the current face of Sh2
let(P1 = Sh2[i], P2=Sh2[(i+1)%L2])
let(P3 = P1+N2, P4 = P2+N2)
let(d = norm(P1-P2))

 // calc the intersection of all lines of Sh1 with current face of

Sh2
let(A = Sh1[j], B = A+N1)
let(I = line_plane_intersection(A, B, P1, P2, P3))
let(dist1 = distance_point_to_line(P1, P3, I))
let(dist2 = distance_point_to_line(P2, P4, I))
// filter points that closely touch the face
if(dist1+dist2<=d*1.0001)
I
])
result;

<nGpKKGbcKaEzok3B.png>

<ZcA2AgZ5byJR3asr.png>

Am 22.02.2025 um 17:19 schrieb Peter Kriens via Discuss:

I am looking for a way to calculate the 3D path where two shapes are
intersecting. In this case, a shape can be limited to a linearly extruded
2D path.

For example:

phi = 45;
union() {
rotate([0,phi,0])  rotate([0,0,45]) cube([20,20,80],center=true);
rotate([0,-phi,0]) cylinder(r=14.2,h=80,center=true);
}

I would like to have the 3D path indicated in red ...

<PastedGraphic-1.png>

I am looking for something like:

function intersect( a, b, phi ) = ...

Where an and b are 2D paths of the 2 shapes and phi is 1/2 the
intersecting angle for an and b. I understand there are 2, I want the one
closes to the XY plane.

I am stuck ... anybody ideas or hints? I am using BOSL2 so any use of
the built in functions would be great.

BTW, this is related to ambiguous cylinders
https://www.youtube.com/watch?v=sQ-Fsv8vVKo. I want to experiment
with different shapes but that requires the formula to be generic.

Kind regards,

Peter Kriens


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org

The BOSL2 offset has a same_length option so that point count will not change and the points will align when linked into a 3d object. On Fri, Mar 7, 2025 at 09:44 Rudolf via Discuss <discuss@lists.openscad.org> wrote: > The source code is all public. It is a question of bundling all pieces > into a single project and the question whether you are on BOSL2. I > personally don't. As it is Peter's thread he will have an opinion about it > and might wanna "release" it. > > Just a note concerning my screenshot. It was made with 10° Z-rotate, which > I introduced when playing with the design. > > Without any rotation you get a symmetric design as expected. > > @Adrian. Using an offset(-d) on the 2D projection of the path is more > straight forward, but it might reduce your edge count and thus bring some > trouble when trying to do the rotate extrusion. > > Am 07.03.2025 um 13:13 schrieb Guenther Sohler via Discuss: > > its a great design. is the source code public ? > > On Fri, Mar 7, 2025 at 12:22 PM Adrian Mariano via Discuss < > discuss@lists.openscad.org> wrote: > >> I think something like this using BOSL2 methods: Say path is your >> starting path. Project to xy plane with path_proj=path2d(path). Compute >> offset, inside=offset(path_proj,r). Now map back to the top, inside_top = >> hstack(inside, column(path,2)). Now you have all the coordinates of the >> shape and can create it with vnf_vertex_array (or skin), so vnf = >> vnf_vertex_array([path, path3d(path_proj), path3d(inside), >> inside_top],row_wrap=true). (I think row_wrap is right, but maybe >> col_wrap...) >> >> On Fri, Mar 7, 2025 at 5:29 AM Rudolf via Discuss < >> discuss@lists.openscad.org> wrote: >> >>> OK, I quickly implemented it and it tends to look good. I think my code >>> is readable for you, even you might not have some my lib functions >>> >>> >>> w1 = 35; >>> res1 = intersect( shape1, shape2, w1, w1); >>> path3 = Rz(0,concat(mid(res1, 0, 31), >>> mid(res1, 64, 88), >>> mid(res1, 146, 177), >>> mid(res1, 203, 227) >>> )); >>> >>> h = 20; >>> th=2; >>> max = Max(path3); >>> sx=(max[0]-th)/max[0]; >>> sy=(max[1]-th)/max[1]; >>> >>> resA = Tz(h/2, path3); // outer up >>> resB = S(sx, sy,1, resA); // inner up >>> resC = Tz(-h, resB); // inner down >>> resD = Tz(-h, resA); // outer down >>> >>> // prepare circular walk >>> path = [for(i=[0:len(resA)-1])[resA[i],resB[i], resC[i], resD[i]]]; >>> >>> dx = 15; >>> T(dx)sweep(path, close=true); >>> Rz(180)T(dx)sweep(path, close=true); >>> >>> echo($vpr); >>> $vpr = [w1, 0, 0]; >>> >>> Am 07.03.2025 um 10:31 schrieb Rudolf via Discuss: >>> >>> not perfect, but I think viable in your case: you can calculate scalex, >>> scaley values for the 2D shape that keeps the wall thickness at least at X >>> and Y axis. Scaling only X,Y coordinates provides you an inner shape with >>> the same number of points and lets you build a sequence of squares in the >>> second step which you can use to do a circular extrude around Z instead of >>> linear extruding along Z. >>> >>> >>> Am 07.03.2025 um 09:21 schrieb Peter Kriens via Discuss: >>> >>> I am having one more problem and I can't seem to find a good solution. >>> >>> I have a closed 3D path. How do I make this into a wall that descents to >>> the z=0? The problem is that the top must have the Z-variances so extrudes >>> seem out of the questions. I want the top of the wall to be flat and be >>> able to parameterize its overall thickness (the current algorithm that uses >>> difference() can create very steep walls when angles are high.) >>> >>> [image: PastedGraphic-7.png][image: PastedGraphic-9.png] >>> >>> >>> >>> Is there any function in BOSL2 that can do this? >>> >>> Peter >>> >>> >>> On 5 Mar 2025, at 11:53, Guenther Sohler via Discuss >>> <discuss@lists.openscad.org> <discuss@lists.openscad.org> wrote: >>> >>> In PythonSCAD (and potentially soon in OpenSCAD) you could >>> >>> 1) output mesh on Object A and create a list of edges >>> 2) output mesh on Object B and create a list of edges >>> 3) union/difference Object A with B , output mesh and create list of >>> edges >>> 4) select Set of Edges from 3 which are neither in included in 1) nor >>> 2) >>> 5) sum up the lengths of Edges from 4) >>> >>> my little 2 cents. I use exactly that algorithm for filling the cut line >>> of 2 objects >>> >>> >>> >>> >>> >>> On Thu, Feb 27, 2025 at 10:28 PM Rudolf via Discuss < >>> discuss@lists.openscad.org> wrote: >>> >>>> Hi Peter, >>>> >>>> Adrian was right, it is not such a big drama to compute the >>>> intersection point of two extruded shapes, as long as they are somehow >>>> "well-behaved". I extracted the relevant functions and modules from my >>>> libraries and wrote your function *intersect(shape1, shape2, w1, w2)* >>>> and some test stuff with generic OpenSCAD. Find the scad file attached. The >>>> code is indeed quite neat and easy to understand. It computes the affine >>>> intersection of freely translated and rotated 2D-shapes, which are assumed >>>> to be endless in both directions. >>>> >>>> The function calculates all planes of the faces that delimit shape2, >>>> intersects each with all lines of shape1 and collects and returns only >>>> those points that are situated on a face This means, two function calls are >>>> needed to get hands on all intersection points. I leave it up to you to >>>> sort the sets together. In most cases you will be fine just using the >>>> richer set. >>>> >>>> I didn't have the time to protect the code against instabilities, >>>> mostly singularities from the dot product of two parallel vectors. As usual >>>> in OpenSCAD tiny-angle rotations or tiny-value translations get you around, >>>> as shown in the test code that produced the second example. >>>> >>>> Hope this helps you along. I'm curious whether it will bring you >>>> forward with the topology stuff in the paper. >>>> >>>> Rudolf >>>> >>>> // intersect two 2D shapes at an angle w >>>> function intersect(Sh1, Sh2, w1=w1, w2=w2) = >>>> let(Sh1 = Rx(w1, Sh1), Sh2 = Rx(w2, Sh2)) >>>> let(N1 = Rx(w1, [0,0,1]), N2 = Rx(w2, [0,0,1])) >>>> let(L1 = len(Sh1), L2=len(Sh2)) >>>> let(sign = L1<L2) >>>> let(result = >>>> [ >>>> for(i = [0:L2-1], j = [0:L1-1]) >>>> // define the current face of Sh2 >>>> let(P1 = Sh2[i], P2=Sh2[(i+1)%L2]) >>>> let(P3 = P1+N2, P4 = P2+N2) >>>> let(d = norm(P1-P2)) >>>> >>>> // calc the intersection of all lines of Sh1 with current face of >>>> Sh2 >>>> let(A = Sh1[j], B = A+N1) >>>> let(I = line_plane_intersection(A, B, P1, P2, P3)) >>>> let(dist1 = distance_point_to_line(P1, P3, I)) >>>> let(dist2 = distance_point_to_line(P2, P4, I)) >>>> // filter points that closely touch the face >>>> if(dist1+dist2<=d*1.0001) >>>> I >>>> ]) >>>> result; >>>> >>>> <nGpKKGbcKaEzok3B.png> >>>> >>>> >>>> <ZcA2AgZ5byJR3asr.png> >>>> >>>> >>>> Am 22.02.2025 um 17:19 schrieb Peter Kriens via Discuss: >>>> >>>> I am looking for a way to calculate the 3D path where two shapes are >>>> intersecting. In this case, a shape can be limited to a linearly extruded >>>> 2D path. >>>> >>>> For example: >>>> >>>> phi = 45; >>>> union() { >>>> rotate([0,phi,0]) rotate([0,0,45]) cube([20,20,80],center=true); >>>> rotate([0,-phi,0]) cylinder(r=14.2,h=80,center=true); >>>> } >>>> >>>> I would like to have the 3D path indicated in red ... >>>> >>>> <PastedGraphic-1.png> >>>> >>>> I am looking for something like: >>>> >>>> function intersect( a, b, phi ) = ... >>>> >>>> Where an and b are 2D paths of the 2 shapes and phi is 1/2 the >>>> intersecting angle for an and b. I understand there are 2, I want the one >>>> closes to the XY plane. >>>> >>>> I am stuck ... anybody ideas or hints? I am using BOSL2 so any use of >>>> the built in functions would be great. >>>> >>>> BTW, this is related to ambiguous cylinders >>>> <https://www.youtube.com/watch?v=sQ-Fsv8vVKo>. I want to experiment >>>> with different shapes but that requires the formula to be generic. >>>> >>>> Kind regards, >>>> >>>> Peter Kriens >>>> >>>> >>>> >>>> >>>> _______________________________________________ >>>> OpenSCAD mailing list >>>> To unsubscribe send an email to discuss-leave@lists.openscad.org >>>> >>>> _______________________________________________ >>>> OpenSCAD mailing list >>>> To unsubscribe send an email to discuss-leave@lists.openscad.org >>>> >>> _______________________________________________ >>> OpenSCAD mailing list >>> To unsubscribe send an email to discuss-leave@lists.openscad.org >>> >>> >>> >>> _______________________________________________ >>> OpenSCAD mailing list >>> To unsubscribe send an email to discuss-leave@lists.openscad.org >>> >>> >>> _______________________________________________ >>> OpenSCAD mailing list >>> To unsubscribe send an email to discuss-leave@lists.openscad.org >>> >>> _______________________________________________ >>> OpenSCAD mailing list >>> To unsubscribe send an email to discuss-leave@lists.openscad.org >>> >> _______________________________________________ >> OpenSCAD mailing list >> To unsubscribe send an email to discuss-leave@lists.openscad.org >> > > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org > > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org >
PK
Peter Kriens
Tue, Mar 11, 2025 6:20 PM

That did work quite well! the vnf_vertex_array seems magically find its way! Thanks.

path = smooth_path(
resample_path(
path_merge_collinear(top,closed=true)
,200,closed=true),
method="corners", closed=true);

path_proj=path2d(path);
inside=offset(path_proj,delta=1.5, same_length=true);
inside_top = hstack(inside, column(path,2));
vnf = vnf_vertex_array(
[path, path3d(path_proj), path3d(inside), inside_top],
col_wrap=true,
row_wrap=true);

vnf_polyhedron(vnf);

BOSL2 is quite magic ... it seems to have a function for everything.

The solution is very sensitive to the input values. Rudolf's solution tends to create very bizarre paths when I have more than 40 segments in the circle. These paths then fall apart later in the BOSL2 functions. I'd like to have a smoother outside. There is another algorithm in the original paperthat I will try out.

Peter Kriens

On 7 Mar 2025, at 17:29, Adrian Mariano via Discuss discuss@lists.openscad.org wrote:

The BOSL2 offset has a same_length option so that point count will not change and the points will align when linked into a 3d object.

On Fri, Mar 7, 2025 at 09:44 Rudolf via Discuss <discuss@lists.openscad.org mailto:discuss@lists.openscad.org> wrote:

The source code is all public. It is a question of bundling all pieces into a single project and the question whether you are on BOSL2. I personally don't. As it is Peter's thread he will have an opinion about it and might wanna "release" it.

Just a note concerning my screenshot. It was made with 10° Z-rotate, which I introduced when playing with the design.

Without any rotation you get a symmetric design as expected.

@Adrian. Using an offset(-d) on the 2D projection of the path is more straight forward, but it might reduce your edge count and thus bring some trouble when trying to do the rotate extrusion.

<DGiyEeSR1V9aDaeM.png>

Am 07.03.2025 um 13:13 schrieb Guenther Sohler via Discuss:

its a great design. is the source code public ?

On Fri, Mar 7, 2025 at 12:22 PM Adrian Mariano via Discuss <discuss@lists.openscad.org mailto:discuss@lists.openscad.org> wrote:

I think something like this using  BOSL2 methods:  Say path is your starting path.  Project to xy plane with path_proj=path2d(path).  Compute offset, inside=offset(path_proj,r).  Now map back to the top, inside_top = hstack(inside, column(path,2)).  Now you have all the coordinates of the shape and can create it with vnf_vertex_array (or skin), so vnf = vnf_vertex_array([path, path3d(path_proj), path3d(inside), inside_top],row_wrap=true).  (I think row_wrap is right, but maybe col_wrap...)

On Fri, Mar 7, 2025 at 5:29 AM Rudolf via Discuss <discuss@lists.openscad.org mailto:discuss@lists.openscad.org> wrote:

OK, I quickly implemented it and it tends to look good. I think my code is readable for you, even you might not have some my lib functions

<H9GcJaPmmg60MwIz.png>

w1 = 35;
res1 = intersect( shape1, shape2, w1, w1);
path3 = Rz(0,concat(mid(res1, 0, 31),
mid(res1, 64, 88),
mid(res1, 146, 177),
mid(res1, 203, 227)
));

h = 20;
th=2;
max = Max(path3);
sx=(max[0]-th)/max[0];
sy=(max[1]-th)/max[1];

resA = Tz(h/2, path3);      // outer up
resB = S(sx, sy,1, resA);  // inner up
resC = Tz(-h, resB);      // inner down
resD = Tz(-h, resA);      // outer down

// prepare circular walk
path = [for(i=[0:len(resA)-1])[resA[i],resB[i], resC[i], resD[i]]];

dx = 15;
T(dx)sweep(path, close=true);
Rz(180)T(dx)sweep(path, close=true);

echo($vpr);
$vpr =  [w1, 0, 0];

Am 07.03.2025 um 10:31 schrieb Rudolf via Discuss:

not perfect, but I think viable in your case: you can calculate scalex, scaley values for the 2D shape that keeps the wall thickness at least at X and Y axis. Scaling only X,Y coordinates provides you an inner shape with the same number of points and lets you build a sequence of squares in the second step which you can use to do a circular extrude around Z instead of linear extruding along Z.

Am 07.03.2025 um 09:21 schrieb Peter Kriens via Discuss:

I am having one more problem and I can't seem to find a good solution.

I have a closed 3D path. How do I make this into a wall that descents to the z=0? The problem is that the top must have the Z-variances so extrudes seem out of the questions. I want the top of the wall to be flat and be able to parameterize its overall thickness (the current algorithm that uses difference() can create very steep walls when angles are high.)

<PastedGraphic-7.png><PastedGraphic-9.png>

Is there any function in BOSL2 that can do this?

Peter

On 5 Mar 2025, at 11:53, Guenther Sohler via Discuss discuss@lists.openscad.org mailto:discuss@lists.openscad.org wrote:

In PythonSCAD (and potentially soon in OpenSCAD) you could

  1. output mesh  on Object A and  create a list of edges
  2. output mesh on Object B and  create a list of edges
  3. union/difference Object A with B , output mesh and create list of edges
  4. select Set of Edges from 3 which are neither  in included in 1) nor  2)
  5. sum up the lengths of Edges  from 4)

my little 2 cents. I use exactly that algorithm for filling the cut line of 2 objects

On Thu, Feb 27, 2025 at 10:28 PM Rudolf via Discuss <discuss@lists.openscad.org mailto:discuss@lists.openscad.org> wrote:

Hi Peter,

Adrian was right, it is not such a big drama to compute the intersection point of two extruded shapes, as long as they are somehow "well-behaved". I extracted the relevant functions and modules from my libraries and wrote your function intersect(shape1, shape2, w1, w2) and some test stuff with generic OpenSCAD. Find the scad file attached. The code is indeed quite neat and easy to understand. It computes the affine intersection of freely translated and rotated 2D-shapes, which are assumed to be endless in both directions.

The function calculates all planes of the faces that delimit shape2, intersects each with all lines of shape1 and collects and returns only those points that are situated on a face This means, two function calls are needed to get hands on all intersection points. I leave it up to you to sort the sets together. In most cases you will be fine just using the richer set.

I didn't have the time to protect the code against instabilities, mostly singularities from the dot product of two parallel vectors. As usual in OpenSCAD tiny-angle rotations or tiny-value translations get you around, as shown in the test code that produced the second example.

Hope this helps you along. I'm curious whether it will bring you forward with the topology stuff in the paper.

Rudolf

// intersect two 2D shapes at an angle w
function intersect(Sh1, Sh2, w1=w1, w2=w2) =
let(Sh1 = Rx(w1, Sh1), Sh2 = Rx(w2, Sh2))
let(N1 =  Rx(w1, [0,0,1]), N2 = Rx(w2, [0,0,1]))
let(L1 = len(Sh1), L2=len(Sh2))
let(sign = L1<L2)
let(result =
[
for(i = [0:L2-1], j = [0:L1-1])
// define the current face of Sh2
let(P1 = Sh2[i], P2=Sh2[(i+1)%L2])
let(P3 = P1+N2, P4 = P2+N2)
let(d = norm(P1-P2))

 // calc the intersection of all lines of Sh1 with current face of Sh2
 let(A = Sh1[j], B = A+N1)   
   let(I = line_plane_intersection(A, B, P1, P2, P3))  
   let(dist1 = distance_point_to_line(P1, P3, I))
   let(dist2 = distance_point_to_line(P2, P4, I))
 // filter points that closely touch the face
   if(dist1+dist2<=d*1.0001) 
   I

])
result;

<nGpKKGbcKaEzok3B.png>

<ZcA2AgZ5byJR3asr.png>

Am 22.02.2025 um 17:19 schrieb Peter Kriens via Discuss:

I am looking for a way to calculate the 3D path where two shapes are intersecting. In this case, a shape can be limited to a linearly extruded 2D path.

For example:

phi = 45;
union() {
rotate([0,phi,0])  rotate([0,0,45]) cube([20,20,80],center=true);
rotate([0,-phi,0]) cylinder(r=14.2,h=80,center=true);
}

I would like to have the 3D path indicated in red ...

<PastedGraphic-1.png>

I am looking for something like:

function intersect( a, b, phi ) = ...

Where an and b are 2D paths of the 2 shapes and phi is 1/2 the intersecting angle for an and b. I understand there are 2, I want the one closes to the XY plane.

I am stuck ... anybody ideas or hints? I am using BOSL2 so any use of the built in functions would be great.

BTW, this is related to ambiguous cylinders https://www.youtube.com/watch?v=sQ-Fsv8vVKo. I want to experiment with different shapes but that requires the formula to be generic.

Kind regards,

Peter Kriens

OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org mailto:discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org mailto:discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org mailto:discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org mailto:discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org mailto:discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org mailto:discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org mailto:discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org mailto:discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org mailto:discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org

That did work quite well! the vnf_vertex_array seems magically find its way! Thanks. path = smooth_path( resample_path( path_merge_collinear(top,closed=true) ,200,closed=true), method="corners", closed=true); path_proj=path2d(path); inside=offset(path_proj,delta=1.5, same_length=true); inside_top = hstack(inside, column(path,2)); vnf = vnf_vertex_array( [path, path3d(path_proj), path3d(inside), inside_top], col_wrap=true, row_wrap=true); vnf_polyhedron(vnf); BOSL2 is quite magic ... it seems to have a function for everything.  The solution is very sensitive to the input values. Rudolf's solution tends to create very bizarre paths when I have more than 40 segments in the circle. These paths then fall apart later in the BOSL2 functions. I'd like to have a smoother outside. There is another algorithm in the original paperthat I will try out. Peter Kriens  > On 7 Mar 2025, at 17:29, Adrian Mariano via Discuss <discuss@lists.openscad.org> wrote: > > The BOSL2 offset has a same_length option so that point count will not change and the points will align when linked into a 3d object. > > On Fri, Mar 7, 2025 at 09:44 Rudolf via Discuss <discuss@lists.openscad.org <mailto:discuss@lists.openscad.org>> wrote: >> The source code is all public. It is a question of bundling all pieces into a single project and the question whether you are on BOSL2. I personally don't. As it is Peter's thread he will have an opinion about it and might wanna "release" it. >> >> Just a note concerning my screenshot. It was made with 10° Z-rotate, which I introduced when playing with the design. >> >> Without any rotation you get a symmetric design as expected. >> >> @Adrian. Using an offset(-d) on the 2D projection of the path is more straight forward, but it might reduce your edge count and thus bring some trouble when trying to do the rotate extrusion. >> >> <DGiyEeSR1V9aDaeM.png> >> >> Am 07.03.2025 um 13:13 schrieb Guenther Sohler via Discuss: >>> its a great design. is the source code public ? >>> >>> On Fri, Mar 7, 2025 at 12:22 PM Adrian Mariano via Discuss <discuss@lists.openscad.org <mailto:discuss@lists.openscad.org>> wrote: >>>> I think something like this using BOSL2 methods: Say path is your starting path. Project to xy plane with path_proj=path2d(path). Compute offset, inside=offset(path_proj,r). Now map back to the top, inside_top = hstack(inside, column(path,2)). Now you have all the coordinates of the shape and can create it with vnf_vertex_array (or skin), so vnf = vnf_vertex_array([path, path3d(path_proj), path3d(inside), inside_top],row_wrap=true). (I think row_wrap is right, but maybe col_wrap...) >>>> >>>> On Fri, Mar 7, 2025 at 5:29 AM Rudolf via Discuss <discuss@lists.openscad.org <mailto:discuss@lists.openscad.org>> wrote: >>>>> OK, I quickly implemented it and it tends to look good. I think my code is readable for you, even you might not have some my lib functions >>>>> >>>>> <H9GcJaPmmg60MwIz.png> >>>>> >>>>> >>>>> >>>>> w1 = 35; >>>>> res1 = intersect( shape1, shape2, w1, w1); >>>>> path3 = Rz(0,concat(mid(res1, 0, 31), >>>>> mid(res1, 64, 88), >>>>> mid(res1, 146, 177), >>>>> mid(res1, 203, 227) >>>>> )); >>>>> >>>>> h = 20; >>>>> th=2; >>>>> max = Max(path3); >>>>> sx=(max[0]-th)/max[0]; >>>>> sy=(max[1]-th)/max[1]; >>>>> >>>>> resA = Tz(h/2, path3); // outer up >>>>> resB = S(sx, sy,1, resA); // inner up >>>>> resC = Tz(-h, resB); // inner down >>>>> resD = Tz(-h, resA); // outer down >>>>> >>>>> // prepare circular walk >>>>> path = [for(i=[0:len(resA)-1])[resA[i],resB[i], resC[i], resD[i]]]; >>>>> >>>>> dx = 15; >>>>> T(dx)sweep(path, close=true); >>>>> Rz(180)T(dx)sweep(path, close=true); >>>>> >>>>> echo($vpr); >>>>> $vpr = [w1, 0, 0]; >>>>> >>>>> >>>>> Am 07.03.2025 um 10:31 schrieb Rudolf via Discuss: >>>>>> not perfect, but I think viable in your case: you can calculate scalex, scaley values for the 2D shape that keeps the wall thickness at least at X and Y axis. Scaling only X,Y coordinates provides you an inner shape with the same number of points and lets you build a sequence of squares in the second step which you can use to do a circular extrude around Z instead of linear extruding along Z. >>>>>> >>>>>> >>>>>> >>>>>> Am 07.03.2025 um 09:21 schrieb Peter Kriens via Discuss: >>>>>>> I am having one more problem and I can't seem to find a good solution. >>>>>>> >>>>>>> I have a closed 3D path. How do I make this into a wall that descents to the z=0? The problem is that the top must have the Z-variances so extrudes seem out of the questions. I want the top of the wall to be flat and be able to parameterize its overall thickness (the current algorithm that uses difference() can create very steep walls when angles are high.) >>>>>>> >>>>>>> <PastedGraphic-7.png><PastedGraphic-9.png> >>>>>>> >>>>>>> >>>>>>> >>>>>>> Is there any function in BOSL2 that can do this? >>>>>>> >>>>>>> Peter >>>>>>> >>>>>>> >>>>>>>> On 5 Mar 2025, at 11:53, Guenther Sohler via Discuss <discuss@lists.openscad.org> <mailto:discuss@lists.openscad.org> wrote: >>>>>>>> >>>>>>>> In PythonSCAD (and potentially soon in OpenSCAD) you could >>>>>>>> >>>>>>>> 1) output mesh on Object A and create a list of edges >>>>>>>> 2) output mesh on Object B and create a list of edges >>>>>>>> 3) union/difference Object A with B , output mesh and create list of edges >>>>>>>> 4) select Set of Edges from 3 which are neither in included in 1) nor 2) >>>>>>>> 5) sum up the lengths of Edges from 4) >>>>>>>> >>>>>>>> my little 2 cents. I use exactly that algorithm for filling the cut line of 2 objects >>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> On Thu, Feb 27, 2025 at 10:28 PM Rudolf via Discuss <discuss@lists.openscad.org <mailto:discuss@lists.openscad.org>> wrote: >>>>>>>>> Hi Peter, >>>>>>>>> >>>>>>>>> Adrian was right, it is not such a big drama to compute the intersection point of two extruded shapes, as long as they are somehow "well-behaved". I extracted the relevant functions and modules from my libraries and wrote your function intersect(shape1, shape2, w1, w2) and some test stuff with generic OpenSCAD. Find the scad file attached. The code is indeed quite neat and easy to understand. It computes the affine intersection of freely translated and rotated 2D-shapes, which are assumed to be endless in both directions. >>>>>>>>> >>>>>>>>> The function calculates all planes of the faces that delimit shape2, intersects each with all lines of shape1 and collects and returns only those points that are situated on a face This means, two function calls are needed to get hands on all intersection points. I leave it up to you to sort the sets together. In most cases you will be fine just using the richer set. >>>>>>>>> >>>>>>>>> I didn't have the time to protect the code against instabilities, mostly singularities from the dot product of two parallel vectors. As usual in OpenSCAD tiny-angle rotations or tiny-value translations get you around, as shown in the test code that produced the second example. >>>>>>>>> >>>>>>>>> Hope this helps you along. I'm curious whether it will bring you forward with the topology stuff in the paper. >>>>>>>>> >>>>>>>>> Rudolf >>>>>>>>> >>>>>>>>> // intersect two 2D shapes at an angle w >>>>>>>>> function intersect(Sh1, Sh2, w1=w1, w2=w2) = >>>>>>>>> let(Sh1 = Rx(w1, Sh1), Sh2 = Rx(w2, Sh2)) >>>>>>>>> let(N1 = Rx(w1, [0,0,1]), N2 = Rx(w2, [0,0,1])) >>>>>>>>> let(L1 = len(Sh1), L2=len(Sh2)) >>>>>>>>> let(sign = L1<L2) >>>>>>>>> let(result = >>>>>>>>> [ >>>>>>>>> for(i = [0:L2-1], j = [0:L1-1]) >>>>>>>>> // define the current face of Sh2 >>>>>>>>> let(P1 = Sh2[i], P2=Sh2[(i+1)%L2]) >>>>>>>>> let(P3 = P1+N2, P4 = P2+N2) >>>>>>>>> let(d = norm(P1-P2)) >>>>>>>>> >>>>>>>>> // calc the intersection of all lines of Sh1 with current face of Sh2 >>>>>>>>> let(A = Sh1[j], B = A+N1) >>>>>>>>> let(I = line_plane_intersection(A, B, P1, P2, P3)) >>>>>>>>> let(dist1 = distance_point_to_line(P1, P3, I)) >>>>>>>>> let(dist2 = distance_point_to_line(P2, P4, I)) >>>>>>>>> // filter points that closely touch the face >>>>>>>>> if(dist1+dist2<=d*1.0001) >>>>>>>>> I >>>>>>>>> ]) >>>>>>>>> result; >>>>>>>>> >>>>>>>>> >>>>>>>>> <nGpKKGbcKaEzok3B.png> >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> <ZcA2AgZ5byJR3asr.png> >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> Am 22.02.2025 um 17:19 schrieb Peter Kriens via Discuss: >>>>>>>>>> I am looking for a way to calculate the 3D path where two shapes are intersecting. In this case, a shape can be limited to a linearly extruded 2D path. >>>>>>>>>> >>>>>>>>>> For example: >>>>>>>>>> >>>>>>>>>> phi = 45; >>>>>>>>>> union() { >>>>>>>>>> rotate([0,phi,0]) rotate([0,0,45]) cube([20,20,80],center=true); >>>>>>>>>> rotate([0,-phi,0]) cylinder(r=14.2,h=80,center=true); >>>>>>>>>> } >>>>>>>>>> >>>>>>>>>> I would like to have the 3D path indicated in red ... >>>>>>>>>> >>>>>>>>>> <PastedGraphic-1.png> >>>>>>>>>> >>>>>>>>>> I am looking for something like: >>>>>>>>>> >>>>>>>>>> function intersect( a, b, phi ) = ... >>>>>>>>>> >>>>>>>>>> Where an and b are 2D paths of the 2 shapes and phi is 1/2 the intersecting angle for an and b. I understand there are 2, I want the one closes to the XY plane. >>>>>>>>>> >>>>>>>>>> I am stuck ... anybody ideas or hints? I am using BOSL2 so any use of the built in functions would be great. >>>>>>>>>> >>>>>>>>>> BTW, this is related to ambiguous cylinders <https://www.youtube.com/watch?v=sQ-Fsv8vVKo>. I want to experiment with different shapes but that requires the formula to be generic. >>>>>>>>>> >>>>>>>>>> Kind regards, >>>>>>>>>> >>>>>>>>>> Peter Kriens >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> _______________________________________________ >>>>>>>>>> OpenSCAD mailing list >>>>>>>>>> To unsubscribe send an email to discuss-leave@lists.openscad.org <mailto:discuss-leave@lists.openscad.org> >>>>>>>>> _______________________________________________ >>>>>>>>> OpenSCAD mailing list >>>>>>>>> To unsubscribe send an email to discuss-leave@lists.openscad.org <mailto:discuss-leave@lists.openscad.org> >>>>>>>> _______________________________________________ >>>>>>>> OpenSCAD mailing list >>>>>>>> To unsubscribe send an email to discuss-leave@lists.openscad.org <mailto:discuss-leave@lists.openscad.org> >>>>>>> >>>>>>> >>>>>>> >>>>>>> _______________________________________________ >>>>>>> OpenSCAD mailing list >>>>>>> To unsubscribe send an email to discuss-leave@lists.openscad.org <mailto:discuss-leave@lists.openscad.org> >>>>>> >>>>>> >>>>>> _______________________________________________ >>>>>> OpenSCAD mailing list >>>>>> To unsubscribe send an email to discuss-leave@lists.openscad.org <mailto:discuss-leave@lists.openscad.org> >>>>> _______________________________________________ >>>>> OpenSCAD mailing list >>>>> To unsubscribe send an email to discuss-leave@lists.openscad.org <mailto:discuss-leave@lists.openscad.org> >>>> _______________________________________________ >>>> OpenSCAD mailing list >>>> To unsubscribe send an email to discuss-leave@lists.openscad.org <mailto:discuss-leave@lists.openscad.org> >>> >>> >>> _______________________________________________ >>> OpenSCAD mailing list >>> To unsubscribe send an email to discuss-leave@lists.openscad.org <mailto:discuss-leave@lists.openscad.org> >> _______________________________________________ >> OpenSCAD mailing list >> To unsubscribe send an email to discuss-leave@lists.openscad.org <mailto:discuss-leave@lists.openscad.org> > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org
R
Rudolf
Wed, Mar 12, 2025 12:37 PM

Peter,

I don't have any problems using high resolutions. The only delicate
thing is combining the right pieces for the intersection path, as you
mentioned. And my code doesn't like, if you try to intersect a plane
with a parallel line. Its easy to treat (by a small rotation), but I
didn't have time to go into the routine (and return a [0,0,0] or
something very far away).

Here a screenshot of nice one that uses 300 Segments. I assembled all
code into a single file and attached it. Feel free to use it, but only
in a non-commercial way.

Just a usage hint. My select() function that automatically combines the
intersection path works well for 45° and a pair of shapes that has a
well matching diameter in x. For other cases, like a somehow rotated
triangle or a view angle of say 15° I manually tweak the intersection
path using the mid() function. Using the view switches makes this an
easy process with visual feedback.

The only lib used is "Naca_sweep.scad" for sweep(), but I think you can
use BOSL's skin() module with adding a single parameter.

Am 11.03.2025 um 19:20 schrieb Peter Kriens via Discuss:

That did work quite well! the vnf_vertex_array seems magically find
its way! Thanks.

 path = smooth_path(
     resample_path(
         path_merge_collinear(top,closed=true)
         ,200,closed=true),
     method="corners", closed=true);
 path_proj=path2d(path);
 inside=offset(path_proj,delta=1.5, same_length=true);
 inside_top = hstack(inside, column(path,2));
 vnf = vnf_vertex_array(
     [path, path3d(path_proj), path3d(inside), inside_top],
     col_wrap=true,
     row_wrap=true);

 vnf_polyhedron(vnf);

BOSL2 is quite magic ... it seems to have a function for everything.

The solution is very sensitive to the input values. Rudolf's solution
tends to create very bizarre paths when I have more than 40 segments
in the circle. These paths then fall apart later in the BOSL2
functions. I'd like to have a smoother outside. There is another
algorithm in the original paperthat I will try out.

Peter Kriens

On 7 Mar 2025, at 17:29, Adrian Mariano via Discuss
discuss@lists.openscad.org wrote:

The BOSL2 offset has a same_length option so that point count will
not change and the points will align when linked into a 3d object.

On Fri, Mar 7, 2025 at 09:44 Rudolf via Discuss
discuss@lists.openscad.org wrote:

 The source code is all public. It is a question of bundling all
 pieces into a single project and the question whether you are on
 BOSL2. I personally don't. As it is Peter's thread he will have
 an opinion about it and might wanna "release" it.

 Just a note concerning my screenshot. It was made with 10°
 Z-rotate, which I introduced when playing with the design.

 Without any rotation you get a symmetric design as expected.

 @Adrian. Using an offset(-d) on the 2D projection of the path is
 more straight forward, but it might reduce your edge count and
 thus bring some trouble when trying to do the rotate extrusion.

 <DGiyEeSR1V9aDaeM.png>

 Am 07.03.2025 um 13:13 schrieb Guenther Sohler via Discuss:
 its a great design. is the source code public ?

 On Fri, Mar 7, 2025 at 12:22 PM Adrian Mariano via Discuss
 <discuss@lists.openscad.org> wrote:

     I think something like this using  BOSL2 methods:  Say path
     is your starting path.  Project to xy plane with
     path_proj=path2d(path).  Compute offset,
     inside=offset(path_proj,r).  Now map back to the top,
     inside_top = hstack(inside, column(path,2)).  Now you have
     all the coordinates of the shape and can create it with
     vnf_vertex_array (or skin), so vnf = vnf_vertex_array([path,
     path3d(path_proj), path3d(inside),
     inside_top],row_wrap=true).   (I think row_wrap is right,
     but maybe col_wrap...)

     On Fri, Mar 7, 2025 at 5:29 AM Rudolf via Discuss
     <discuss@lists.openscad.org> wrote:

         OK, I quickly implemented it and it tends to look good.
         I think my code is readable for you, even you might not
         have some my lib functions

         <H9GcJaPmmg60MwIz.png>


         w1 = 35;
         res1 = intersect( shape1, shape2, w1, w1);
         path3 = Rz(0,concat(mid(res1, 0, 31),
         mid(res1, 64, 88),
         mid(res1, 146, 177),
         mid(res1, 203, 227)
         ));

         h = 20;
         th=2;
         max = Max(path3);
         sx=(max[0]-th)/max[0];
         sy=(max[1]-th)/max[1];

         resA = Tz(h/2, path3);      // outer up
         resB = S(sx, sy,1, resA);  // inner up
         resC = Tz(-h, resB);      // inner down
         resD = Tz(-h, resA);      // outer down

         // prepare circular walk
         path = [for(i=[0:len(resA)-1])[resA[i],resB[i], resC[i],
         resD[i]]];

         dx = 15;
         T(dx)sweep(path, close=true);
         Rz(180)T(dx)sweep(path, close=true);

         echo($vpr);
         $vpr =  [w1, 0, 0];

         Am 07.03.2025 um 10:31 schrieb Rudolf via Discuss:
         not perfect, but I think viable in your case: you can
         calculate scalex, scaley values for the 2D shape that
         keeps the wall thickness at least at X and Y axis.
         Scaling only X,Y coordinates provides you an inner
         shape with the same number of points and lets you build
         a sequence of squares in the second step which you can
         use to do a circular extrude around Z instead of linear
         extruding along Z.


         Am 07.03.2025 um 09:21 schrieb Peter Kriens via Discuss:
         I am having one more problem and I can't seem to find
         a good solution.

         I have a closed 3D path. How do I make this into a
         wall that descents to the z=0? The problem is that the
         top must have the Z-variances so extrudes seem out of
         the questions. I want the top of the wall to be flat
         and be able to parameterize its overall thickness (the
         current algorithm that uses difference() can create
         very steep walls when angles are high.)

         <PastedGraphic-7.png><PastedGraphic-9.png>



         Is there any function in BOSL2 that can do this?

         Peter
         On 5 Mar 2025, at 11:53, Guenther Sohler via Discuss
         <discuss@lists.openscad.org>
         <mailto:discuss@lists.openscad.org> wrote:

         In PythonSCAD (and potentially soon in OpenSCAD) you
         could

         1) output mesh on Object A and create a list of edges
         2) output mesh on Object B and create a list of edges
         3) union/difference Object A with B , output mesh and
         create list of edges
         4) select Set of Edges from 3 which are neither  in
         included in 1) nor 2)
         5) sum up the lengths of Edges from 4)

         my little 2 cents. I use exactly that algorithm for
         filling the cut line of 2 objects





         On Thu, Feb 27, 2025 at 10:28 PM Rudolf via Discuss
         <discuss@lists.openscad.org> wrote:

             Hi Peter,

             Adrian was right, it is not such a big drama to
             compute the intersection point of two extruded
             shapes, as long as they are somehow
             "well-behaved". I extracted the relevant
             functions and modules from my libraries and wrote
             your function *intersect(shape1, shape2, w1, w2)*
             and some test stuff with generic OpenSCAD. Find
             the scad file attached. The code is indeed quite
             neat and easy to understand. It computes the
             affine intersection of freely translated and
             rotated 2D-shapes, which are assumed to be
             endless in both directions.

             The function calculates all planes of the faces
             that delimit shape2, intersects each with all
             lines of shape1 and collects and returns only
             those points that are situated on a face This
             means, two function calls are needed to get hands
             on all intersection points. I leave it up to you
             to sort the sets together. In most cases you will
             be fine just using the richer set.

             I didn't have the time to protect the code
             against instabilities, mostly singularities from
             the dot product of two parallel vectors. As usual
             in OpenSCAD tiny-angle rotations or tiny-value
             translations get you around, as shown in the test
             code that produced the second example.

             Hope this helps you along. I'm curious whether it
             will bring you forward with the topology stuff in
             the paper.

             Rudolf

             // intersect two 2D shapes at an angle w
             function intersect(Sh1, Sh2, w1=w1, w2=w2) =
             let(Sh1 = Rx(w1, Sh1), Sh2 = Rx(w2, Sh2))
             let(N1 = Rx(w1, [0,0,1]), N2 = Rx(w2, [0,0,1]))
             let(L1 = len(Sh1), L2=len(Sh2))
             let(sign = L1<L2)
             let(result =
               [
                 for(i = [0:L2-1], j = [0:L1-1])
                 // define the current face of Sh2
                 let(P1 = Sh2[i], P2=Sh2[(i+1)%L2])
                 let(P3 = P1+N2, P4 = P2+N2)
                 let(d = norm(P1-P2))

                 // calc the intersection of all lines of Sh1
             with current face of Sh2
                 let(A = Sh1[j], B = A+N1)
                   let(I = line_plane_intersection(A, B, P1,
             P2, P3))
             let(dist1 = distance_point_to_line(P1, P3, I))
             let(dist2 = distance_point_to_line(P2, P4, I))
                 // filter points that closely touch the face
             if(dist1+dist2<=d*1.0001)
                   I
               ])
               result;


             <nGpKKGbcKaEzok3B.png>


             <ZcA2AgZ5byJR3asr.png>


             Am 22.02.2025 um 17:19 schrieb Peter Kriens via
             Discuss:
             I am looking for a way to calculate the 3D path
             where two shapes are intersecting. In this case,
             a shape can be limited to a linearly extruded 2D
             path.

             For example:

             phi = 45;
             union() {
             rotate([0,phi,0])  rotate([0,0,45])
             cube([20,20,80],center=true);
             rotate([0,-phi,0])
             cylinder(r=14.2,h=80,center=true);
             }

             I would like to have the 3D path indicated in
             red ...

             <PastedGraphic-1.png>

             I am looking for something like:

             function intersect( a, b, phi ) = ...

             Where an and b are 2D paths of the 2 shapes and
             phi is 1/2 the intersecting angle for an and b.
             I understand there are 2, I want the one closes
             to the XY plane.

             I am stuck ... anybody ideas or hints? I am
             using BOSL2 so any use of the built in functions
             would be great.

             BTW, this is related to ambiguous cylinders
             <https://www.youtube.com/watch?v=sQ-Fsv8vVKo>. I
             want to experiment with different shapes but
             that requires the formula to be generic.

             Kind regards,

             Peter Kriens




             _______________________________________________
             OpenSCAD mailing list
             To unsubscribe send an email todiscuss-leave@lists.openscad.org
             _______________________________________________
             OpenSCAD mailing list
             To unsubscribe send an email to
             discuss-leave@lists.openscad.org

         _______________________________________________
         OpenSCAD mailing list
         To unsubscribe send an email to
         discuss-leave@lists.openscad.org
         _______________________________________________
         OpenSCAD mailing list
         To unsubscribe send an email todiscuss-leave@lists.openscad.org
         _______________________________________________
         OpenSCAD mailing list
         To unsubscribe send an email todiscuss-leave@lists.openscad.org
         _______________________________________________
         OpenSCAD mailing list
         To unsubscribe send an email to
         discuss-leave@lists.openscad.org

     _______________________________________________
     OpenSCAD mailing list
     To unsubscribe send an email to discuss-leave@lists.openscad.org


 _______________________________________________
 OpenSCAD mailing list
 To unsubscribe send an email todiscuss-leave@lists.openscad.org
 _______________________________________________
 OpenSCAD mailing list
 To unsubscribe send an email to discuss-leave@lists.openscad.org

OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email todiscuss-leave@lists.openscad.org

Peter, I don't have any problems using high resolutions. The only delicate thing is combining the right pieces for the intersection path, as you mentioned. And my code doesn't like, if you try to intersect a plane with a parallel line. Its easy to treat (by a small rotation), but I didn't have time to go into the routine (and return a [0,0,0] or something very far away). Here a screenshot of nice one that uses 300 Segments. I assembled all code into a single file and attached it. Feel free to use it, but only in a non-commercial way. Just a usage hint. My select() function that automatically combines the intersection path works well for 45° and a pair of shapes that has a well matching diameter in x. For other cases, like a somehow rotated triangle or a view angle of say 15° I manually tweak the intersection path using the mid() function. Using the view switches makes this an easy process with visual feedback. The only lib used is "Naca_sweep.scad" for sweep(), but I think you can use BOSL's skin() module with adding a single parameter. Am 11.03.2025 um 19:20 schrieb Peter Kriens via Discuss: > That did work quite well! the vnf_vertex_array seems magically find > its way! Thanks. > > path = smooth_path( >     resample_path( >         path_merge_collinear(top,closed=true) >         ,200,closed=true), >     method="corners", closed=true); > path_proj=path2d(path); > inside=offset(path_proj,delta=1.5, same_length=true); > inside_top = hstack(inside, column(path,2)); > vnf = vnf_vertex_array( >     [path, path3d(path_proj), path3d(inside), inside_top], >     col_wrap=true, >     row_wrap=true); > > vnf_polyhedron(vnf); > > > BOSL2 is quite magic ... it seems to have a function for everything. > > > > The solution is very sensitive to the input values. Rudolf's solution > tends to create very bizarre paths when I have more than 40 segments > in the circle. These paths then fall apart later in the BOSL2 > functions. I'd like to have a smoother outside. There is another > algorithm in the original paperthat I will try out. > > Peter Kriens > > > > > >> On 7 Mar 2025, at 17:29, Adrian Mariano via Discuss >> <discuss@lists.openscad.org> wrote: >> >> The BOSL2 offset has a same_length option so that point count will >> not change and the points will align when linked into a 3d object. >> >> On Fri, Mar 7, 2025 at 09:44 Rudolf via Discuss >> <discuss@lists.openscad.org> wrote: >> >> The source code is all public. It is a question of bundling all >> pieces into a single project and the question whether you are on >> BOSL2. I personally don't. As it is Peter's thread he will have >> an opinion about it and might wanna "release" it. >> >> Just a note concerning my screenshot. It was made with 10° >> Z-rotate, which I introduced when playing with the design. >> >> Without any rotation you get a symmetric design as expected. >> >> @Adrian. Using an offset(-d) on the 2D projection of the path is >> more straight forward, but it might reduce your edge count and >> thus bring some trouble when trying to do the rotate extrusion. >> >> <DGiyEeSR1V9aDaeM.png> >> >> Am 07.03.2025 um 13:13 schrieb Guenther Sohler via Discuss: >>> its a great design. is the source code public ? >>> >>> On Fri, Mar 7, 2025 at 12:22 PM Adrian Mariano via Discuss >>> <discuss@lists.openscad.org> wrote: >>> >>> I think something like this using  BOSL2 methods:  Say path >>> is your starting path.  Project to xy plane with >>> path_proj=path2d(path).  Compute offset, >>> inside=offset(path_proj,r).  Now map back to the top, >>> inside_top = hstack(inside, column(path,2)).  Now you have >>> all the coordinates of the shape and can create it with >>> vnf_vertex_array (or skin), so vnf = vnf_vertex_array([path, >>> path3d(path_proj), path3d(inside), >>> inside_top],row_wrap=true).   (I think row_wrap is right, >>> but maybe col_wrap...) >>> >>> On Fri, Mar 7, 2025 at 5:29 AM Rudolf via Discuss >>> <discuss@lists.openscad.org> wrote: >>> >>> OK, I quickly implemented it and it tends to look good. >>> I think my code is readable for you, even you might not >>> have some my lib functions >>> >>> <H9GcJaPmmg60MwIz.png> >>> >>> >>> w1 = 35; >>> res1 = intersect( shape1, shape2, w1, w1); >>> path3 = Rz(0,concat(mid(res1, 0, 31), >>> mid(res1, 64, 88), >>> mid(res1, 146, 177), >>> mid(res1, 203, 227) >>> )); >>> >>> h = 20; >>> th=2; >>> max = Max(path3); >>> sx=(max[0]-th)/max[0]; >>> sy=(max[1]-th)/max[1]; >>> >>> resA = Tz(h/2, path3);      // outer up >>> resB = S(sx, sy,1, resA);  // inner up >>> resC = Tz(-h, resB);      // inner down >>> resD = Tz(-h, resA);      // outer down >>> >>> // prepare circular walk >>> path = [for(i=[0:len(resA)-1])[resA[i],resB[i], resC[i], >>> resD[i]]]; >>> >>> dx = 15; >>> T(dx)sweep(path, close=true); >>> Rz(180)T(dx)sweep(path, close=true); >>> >>> echo($vpr); >>> $vpr =  [w1, 0, 0]; >>> >>> Am 07.03.2025 um 10:31 schrieb Rudolf via Discuss: >>>> >>>> not perfect, but I think viable in your case: you can >>>> calculate scalex, scaley values for the 2D shape that >>>> keeps the wall thickness at least at X and Y axis. >>>> Scaling only X,Y coordinates provides you an inner >>>> shape with the same number of points and lets you build >>>> a sequence of squares in the second step which you can >>>> use to do a circular extrude around Z instead of linear >>>> extruding along Z. >>>> >>>> >>>> Am 07.03.2025 um 09:21 schrieb Peter Kriens via Discuss: >>>>> I am having one more problem and I can't seem to find >>>>> a good solution. >>>>> >>>>> I have a closed 3D path. How do I make this into a >>>>> wall that descents to the z=0? The problem is that the >>>>> top must have the Z-variances so extrudes seem out of >>>>> the questions. I want the top of the wall to be flat >>>>> and be able to parameterize its overall thickness (the >>>>> current algorithm that uses difference() can create >>>>> very steep walls when angles are high.) >>>>> >>>>> <PastedGraphic-7.png><PastedGraphic-9.png> >>>>> >>>>> >>>>> >>>>> Is there any function in BOSL2 that can do this? >>>>> >>>>> Peter >>>>> >>>>> >>>>>> On 5 Mar 2025, at 11:53, Guenther Sohler via Discuss >>>>>> <discuss@lists.openscad.org> >>>>>> <mailto:discuss@lists.openscad.org> wrote: >>>>>> >>>>>> In PythonSCAD (and potentially soon in OpenSCAD) you >>>>>> could >>>>>> >>>>>> 1) output mesh on Object A and create a list of edges >>>>>> 2) output mesh on Object B and create a list of edges >>>>>> 3) union/difference Object A with B , output mesh and >>>>>> create list of edges >>>>>> 4) select Set of Edges from 3 which are neither  in >>>>>> included in 1) nor 2) >>>>>> 5) sum up the lengths of Edges from 4) >>>>>> >>>>>> my little 2 cents. I use exactly that algorithm for >>>>>> filling the cut line of 2 objects >>>>>> >>>>>> >>>>>> >>>>>> >>>>>> >>>>>> On Thu, Feb 27, 2025 at 10:28 PM Rudolf via Discuss >>>>>> <discuss@lists.openscad.org> wrote: >>>>>> >>>>>> Hi Peter, >>>>>> >>>>>> Adrian was right, it is not such a big drama to >>>>>> compute the intersection point of two extruded >>>>>> shapes, as long as they are somehow >>>>>> "well-behaved". I extracted the relevant >>>>>> functions and modules from my libraries and wrote >>>>>> your function *intersect(shape1, shape2, w1, w2)* >>>>>> and some test stuff with generic OpenSCAD. Find >>>>>> the scad file attached. The code is indeed quite >>>>>> neat and easy to understand. It computes the >>>>>> affine intersection of freely translated and >>>>>> rotated 2D-shapes, which are assumed to be >>>>>> endless in both directions. >>>>>> >>>>>> The function calculates all planes of the faces >>>>>> that delimit shape2, intersects each with all >>>>>> lines of shape1 and collects and returns only >>>>>> those points that are situated on a face This >>>>>> means, two function calls are needed to get hands >>>>>> on all intersection points. I leave it up to you >>>>>> to sort the sets together. In most cases you will >>>>>> be fine just using the richer set. >>>>>> >>>>>> I didn't have the time to protect the code >>>>>> against instabilities, mostly singularities from >>>>>> the dot product of two parallel vectors. As usual >>>>>> in OpenSCAD tiny-angle rotations or tiny-value >>>>>> translations get you around, as shown in the test >>>>>> code that produced the second example. >>>>>> >>>>>> Hope this helps you along. I'm curious whether it >>>>>> will bring you forward with the topology stuff in >>>>>> the paper. >>>>>> >>>>>> Rudolf >>>>>> >>>>>> // intersect two 2D shapes at an angle w >>>>>> function intersect(Sh1, Sh2, w1=w1, w2=w2) = >>>>>> let(Sh1 = Rx(w1, Sh1), Sh2 = Rx(w2, Sh2)) >>>>>> let(N1 = Rx(w1, [0,0,1]), N2 = Rx(w2, [0,0,1])) >>>>>> let(L1 = len(Sh1), L2=len(Sh2)) >>>>>> let(sign = L1<L2) >>>>>> let(result = >>>>>>   [ >>>>>>     for(i = [0:L2-1], j = [0:L1-1]) >>>>>>     // define the current face of Sh2 >>>>>>     let(P1 = Sh2[i], P2=Sh2[(i+1)%L2]) >>>>>>     let(P3 = P1+N2, P4 = P2+N2) >>>>>>     let(d = norm(P1-P2)) >>>>>> >>>>>>     // calc the intersection of all lines of Sh1 >>>>>> with current face of Sh2 >>>>>>     let(A = Sh1[j], B = A+N1) >>>>>>       let(I = line_plane_intersection(A, B, P1, >>>>>> P2, P3)) >>>>>> let(dist1 = distance_point_to_line(P1, P3, I)) >>>>>> let(dist2 = distance_point_to_line(P2, P4, I)) >>>>>>     // filter points that closely touch the face >>>>>> if(dist1+dist2<=d*1.0001) >>>>>>       I >>>>>>   ]) >>>>>>   result; >>>>>> >>>>>> >>>>>> <nGpKKGbcKaEzok3B.png> >>>>>> >>>>>> >>>>>> <ZcA2AgZ5byJR3asr.png> >>>>>> >>>>>> >>>>>> Am 22.02.2025 um 17:19 schrieb Peter Kriens via >>>>>> Discuss: >>>>>>> I am looking for a way to calculate the 3D path >>>>>>> where two shapes are intersecting. In this case, >>>>>>> a shape can be limited to a linearly extruded 2D >>>>>>> path. >>>>>>> >>>>>>> For example: >>>>>>> >>>>>>> phi = 45; >>>>>>> union() { >>>>>>> rotate([0,phi,0])  rotate([0,0,45]) >>>>>>> cube([20,20,80],center=true); >>>>>>> rotate([0,-phi,0]) >>>>>>> cylinder(r=14.2,h=80,center=true); >>>>>>> } >>>>>>> >>>>>>> I would like to have the 3D path indicated in >>>>>>> red ... >>>>>>> >>>>>>> <PastedGraphic-1.png> >>>>>>> >>>>>>> I am looking for something like: >>>>>>> >>>>>>> function intersect( a, b, phi ) = ... >>>>>>> >>>>>>> Where an and b are 2D paths of the 2 shapes and >>>>>>> phi is 1/2 the intersecting angle for an and b. >>>>>>> I understand there are 2, I want the one closes >>>>>>> to the XY plane. >>>>>>> >>>>>>> I am stuck ... anybody ideas or hints? I am >>>>>>> using BOSL2 so any use of the built in functions >>>>>>> would be great. >>>>>>> >>>>>>> BTW, this is related to ambiguous cylinders >>>>>>> <https://www.youtube.com/watch?v=sQ-Fsv8vVKo>. I >>>>>>> want to experiment with different shapes but >>>>>>> that requires the formula to be generic. >>>>>>> >>>>>>> Kind regards, >>>>>>> >>>>>>> Peter Kriens >>>>>>> >>>>>>> >>>>>>> >>>>>>> >>>>>>> _______________________________________________ >>>>>>> OpenSCAD mailing list >>>>>>> To unsubscribe send an email todiscuss-leave@lists.openscad.org >>>>>> _______________________________________________ >>>>>> OpenSCAD mailing list >>>>>> To unsubscribe send an email to >>>>>> discuss-leave@lists.openscad.org >>>>>> >>>>>> _______________________________________________ >>>>>> OpenSCAD mailing list >>>>>> To unsubscribe send an email to >>>>>> discuss-leave@lists.openscad.org >>>>> >>>>> >>>>> _______________________________________________ >>>>> OpenSCAD mailing list >>>>> To unsubscribe send an email todiscuss-leave@lists.openscad.org >>>> >>>> _______________________________________________ >>>> OpenSCAD mailing list >>>> To unsubscribe send an email todiscuss-leave@lists.openscad.org >>> _______________________________________________ >>> OpenSCAD mailing list >>> To unsubscribe send an email to >>> discuss-leave@lists.openscad.org >>> >>> _______________________________________________ >>> OpenSCAD mailing list >>> To unsubscribe send an email to discuss-leave@lists.openscad.org >>> >>> >>> _______________________________________________ >>> OpenSCAD mailing list >>> To unsubscribe send an email todiscuss-leave@lists.openscad.org >> _______________________________________________ >> OpenSCAD mailing list >> To unsubscribe send an email to discuss-leave@lists.openscad.org >> >> _______________________________________________ >> OpenSCAD mailing list >> To unsubscribe send an email to discuss-leave@lists.openscad.org > > > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email todiscuss-leave@lists.openscad.org