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
- output mesh on Object A and create a list of edges
- output mesh on Object B and create a list of edges
- union/difference Object A with B , output mesh and create list of
edges
- select Set of Edges from 3 which are neither in included in 1)
nor 2)
- 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
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
- output mesh on Object A and create a list of edges
- output mesh on Object B and create a list of edges
- union/difference Object A with B , output mesh and create list
of edges
- select Set of Edges from 3 which are neither in included in 1)
nor 2)
- 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
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
- output mesh on Object A and create a list of edges
- output mesh on Object B and create a list of edges
- union/difference Object A with B , output mesh and create list of edges
- select Set of Edges from 3 which are neither in included in 1) nor 2)
- 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
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
- output mesh on Object A and create a list of edges
- output mesh on Object B and create a list of edges
- union/difference Object A with B , output mesh and create list of edges
- select Set of Edges from 3 which are neither in included in 1) nor 2)
- 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
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
- output mesh on Object A and create a list of edges
- output mesh on Object B and create a list of edges
- union/difference Object A with B , output mesh and create list of
edges
- select Set of Edges from 3 which are neither in included in 1) nor
- 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
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

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:
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
- output mesh on Object A and create a list of edges
- output mesh on Object B and create a list of edges
- union/difference Object A with B , output mesh and create list of edges
- select Set of Edges from 3 which are neither in included in 1) nor 2)
- 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
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
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