Hi,

Guest

P

pca006132

Tue, Jul 2, 2024 5:30 PM

probably useful: https://wiki.freecad.org/Part_Loft_Technical_Details

On Wed, Jul 3, 2024, 12:59 AM larry via Discuss discuss@lists.openscad.org

wrote:

On Tue, 2024-07-02 at 13:06 +0000, jon jonbondy.com via Discuss wrote:

I got there, eventually, after a LOT of flailing. Clearly, I do not

understand the difference between a list of numbers, a function()

that returns a list of numbers, a module() that returns a list of

numbers, and the result of applying polygon() or offset() to any of

the above. It took a lot of trial-and-error to get what I wanted,

all attributable to my lack of understanding the representations

under the hood for each of these objects.

Jon

I'd be interested in the final code, if you are willing to share it.

On 7/2/2024 8:26 AM, Adrian Mariano wrote:

There is no offset() function in native OpenSCAD, only the offset()

module. BOSL2 supplies the offset() function, which you'll want to

use (with closed=true), but does not change the module. It looks

like you have the same point list, differently offset. You

generally only need slices>0 if there is twisting, so you might

check if the larger value makes a different. (If it does, 2 is

probably not large enough.)

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

probably useful: https://wiki.freecad.org/Part_Loft_Technical_Details
On Wed, Jul 3, 2024, 12:59 AM larry via Discuss <discuss@lists.openscad.org>
wrote:
> On Tue, 2024-07-02 at 13:06 +0000, jon jonbondy.com via Discuss wrote:
> > I got there, eventually, after a LOT of flailing. Clearly, I do not
> > understand the difference between a list of numbers, a function()
> > that returns a list of numbers, a module() that returns a list of
> > numbers, and the result of applying polygon() or offset() to any of
> > the above. It took a lot of trial-and-error to get what I wanted,
> > all attributable to my lack of understanding the representations
> > under the hood for each of these objects.
> > Jon
>
> I'd be interested in the final code, if you are willing to share it.
>
> > On 7/2/2024 8:26 AM, Adrian Mariano wrote:
> > > There is no offset() function in native OpenSCAD, only the offset()
> > > module. BOSL2 supplies the offset() function, which you'll want to
> > > use (with closed=true), but does not change the module. It looks
> > > like you have the same point list, differently offset. You
> > > generally only need slices>0 if there is twisting, so you might
> > > check if the larger value makes a different. (If it does, 2 is
> > > probably not large enough.)
> > > >
> > > >
> > > >
> > _______________________________________________
> > 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
>

JB

Jordan Brown

Tue, Jul 2, 2024 5:49 PM

On 7/2/2024 6:06 AM, jon jonbondy.com via Discuss wrote:

Clearly, I do not understand the difference between a list of numbers,

a function() that returns a list of numbers, a module() that returns a

list of numbers, and the result of applying polygon() or offset() to

any of the above.

There are only two data types there: a list of numbers, and a shape.

Unlike other programming languages[*], OpenSCAD has two very different

kinds of data that get passed around. I don't think there's official

terminology, but for this message I'll call them ordinary values and shapes.

Ordinary values (whether numbers, strings, booleans, or arrays of

values) behave like ordinary values in other languages. You can write

constant values in the program, store them in variables, pass them to

functions, return them from functions, et cetera.

```
num = 57;
array = [ 1,2,3 ];
str = "hello";
function add1(x) = x + 1;
y = add1(num); // 58
```

Shapes are geometric shapes, either 2D or 3D. They cannot (yet!) be put

into variables or passed around using ordinary-value mechanisms. They

are created using primitive modules like cube(), sphere(), square(), and

polygon(), and you can manipulate them using transformation modules like

translate(), rotate(), and with boolean modules like union() and

difference(). You can combine them into modules, which then yield a

shape that is the union of the contents.

```
cube(10);
rotate(45) square(10);
translate([10,10,10]) rotate(45) cube(10);
module spherecube() {
cube(10, center=true);
sphere(d=13);
}
```

Going back to your comment:

Clearly, I do not understand the difference between a list of numbers,

a function() that returns a list of numbers, a module() that returns a

list of numbers, and the result of applying polygon() or offset() to

any of the above.

[ Unless otherwise mentioned, the text below refers to core OpenSCAD.

BOSL2 adds some complexity to the picture. ]

A list of numbers, or a function that returns a list of numbers, is just

an expression with a value of a list of numbers. The difference between

a list of numbers and a function that returns a list of numbers is that

the function presumably did some operations on its inputs to create the

list.

Modules do not return ordinary values. Modules generate shapes. It's a

non sequitur to talk about a module returning a list of numbers.

polygon() is a module that accepts a list of numbers (actually, a list

of lists of numbers), and generates a 2D shape.

offset() is a transformation module that accepts a 2D shape as a child,

and generates a modified version of that shape, moving its outside edge

in or out.

Let's put some of those together...

```
poly = [
[0, 0],
[10, 0],
[0, 10]
];
```

A list of lists of numbers. OpenSCAD doesn't know it, but it's a list

of three X-Y coordinates forming a triangle.

```
polygon(poly);
```

Turns that list of numbers into a shape - a triangle,

```
function double(v) = v * 2;
```

Takes its argument, multiplies it by two, and returns it.

```
poly2 = double(poly);
```

Note that multiplying a list by a number yields a list where each

element has been multiplied by the number.

```
translate([20,0]) polygon(poly2);
```

Turn that second list of numbers into a shape (a triangle that's twice

as big), and move it to the right.

```
translate([50,0]) offset(2) polygon(poly2);
```

Creates another polygon, extends its edges out two units (rounding the

corners), and moves it to the right.

All together:

```
poly = [
[0, 0],
[10, 0],
[0, 10]
];
polygon(poly);
function double(v) = v * 2;
poly2 = double(poly);
translate([20,0]) polygon(poly2);
translate([50,0]) offset(2) polygon(poly2);
```

yields:

I said that BOSL2 confuses the issue a bit.

I mentioned above that poly, that list of three X-Y coordinates,

represents a triangle. The only things that OpenSCAD can natively do

with such a list are things like arithmetic and concatenation, and

calling polygon() to turn it into a shape. None of OpenSCAD's native

operations, other than polygon(), "know" that those numbers represent a

geometric figure.

BOSL2, on the other hand, has many functions that either generate those

lists or operate on them. As far as OpenSCAD knows, they are still just

lists of lists of numbers, but BOSL2 "knows" that they represent

geometric figures. As relevant here, it has a *function* named

offset(), that accepts an offset value and a list of coordinates, and

does the same sort of offsetting modification that the native OpenSCAD

offset() *module* does, returning a new list of coordinates.

```
include <bosl2/std.scad>
poly3 = offset(poly, r=3, closed=true);
```

poly is a list of lists of numbers (from above). BOSL2's offset()

function takes that list, and returns a new list, and we put that in

poly3. It's still just a list of lists of numbers, as far as OpenSCAD

knows, but we know better.

```
translate([0,-20,0]) polygon(poly3);
```

Since poly3 is a list of coordinates, we can call polygon() on it and

turn it into an OpenSCAD shape.

It's important to understand that OpenSCAD's offset() module and BOSL2's

offset() function are different things. They do largely the same thing,

but the kind of input they take and yield are very different - the

offset() module, like all transformation modules, takes a shape as a

child and generates a new shape, while the offset() function takes a

list of numbers and returns a new list of numbers. Many BOSL2

operations are available in both forms.

I hope that makes the picture a bit clearer.

[*] Arguably with the exception of UNIX shells, where standard

output/input is sort of dimly like OpenSCAD shapes.

On 7/2/2024 6:06 AM, jon jonbondy.com via Discuss wrote:
>
> Clearly, I do not understand the difference between a list of numbers,
> a function() that returns a list of numbers, a module() that returns a
> list of numbers, and the result of applying polygon() or offset() to
> any of the above.
>
There are only two data types there: a list of numbers, and a shape.
Unlike other programming languages[*], OpenSCAD has two very different
kinds of data that get passed around. I don't think there's official
terminology, but for this message I'll call them ordinary values and shapes.
Ordinary values (whether numbers, strings, booleans, or arrays of
values) behave like ordinary values in other languages. You can write
constant values in the program, store them in variables, pass them to
functions, return them from functions, et cetera.
num = 57;
array = [ 1,2,3 ];
str = "hello";
function add1(x) = x + 1;
y = add1(num); // 58
Shapes are geometric shapes, either 2D or 3D. They cannot (yet!) be put
into variables or passed around using ordinary-value mechanisms. They
are created using primitive modules like cube(), sphere(), square(), and
polygon(), and you can manipulate them using transformation modules like
translate(), rotate(), and with boolean modules like union() and
difference(). You can combine them into modules, which then yield a
shape that is the union of the contents.
cube(10);
rotate(45) square(10);
translate([10,10,10]) rotate(45) cube(10);
module spherecube() {
cube(10, center=true);
sphere(d=13);
}
Going back to your comment:
>
> Clearly, I do not understand the difference between a list of numbers,
> a function() that returns a list of numbers, a module() that returns a
> list of numbers, and the result of applying polygon() or offset() to
> any of the above.
>
[ Unless otherwise mentioned, the text below refers to core OpenSCAD.
BOSL2 adds some complexity to the picture. ]
A list of numbers, or a function that returns a list of numbers, is just
an expression with a value of a list of numbers. The difference between
a list of numbers and a function that returns a list of numbers is that
the function presumably did some operations on its inputs to create the
list.
Modules do not return ordinary values. Modules generate shapes. It's a
non sequitur to talk about a module returning a list of numbers.
polygon() is a module that accepts a list of numbers (actually, a list
of lists of numbers), and generates a 2D shape.
offset() is a transformation module that accepts a 2D shape as a child,
and generates a modified version of that shape, moving its outside edge
in or out.
Let's put some of those together...
poly = [
[0, 0],
[10, 0],
[0, 10]
];
A list of lists of numbers. OpenSCAD doesn't know it, but it's a list
of three X-Y coordinates forming a triangle.
polygon(poly);
Turns that list of numbers into a shape - a triangle,
function double(v) = v * 2;
Takes its argument, multiplies it by two, and returns it.
poly2 = double(poly);
Note that multiplying a list by a number yields a list where each
element has been multiplied by the number.
translate([20,0]) polygon(poly2);
Turn that second list of numbers into a shape (a triangle that's twice
as big), and move it to the right.
translate([50,0]) offset(2) polygon(poly2);
Creates another polygon, extends its edges out two units (rounding the
corners), and moves it to the right.
All together:
poly = [
[0, 0],
[10, 0],
[0, 10]
];
polygon(poly);
function double(v) = v * 2;
poly2 = double(poly);
translate([20,0]) polygon(poly2);
translate([50,0]) offset(2) polygon(poly2);
yields:
I said that BOSL2 confuses the issue a bit.
I mentioned above that poly, that list of three X-Y coordinates,
represents a triangle. The only things that OpenSCAD can natively do
with such a list are things like arithmetic and concatenation, and
calling polygon() to turn it into a shape. None of OpenSCAD's native
operations, other than polygon(), "know" that those numbers represent a
geometric figure.
BOSL2, on the other hand, has many functions that either generate those
lists or operate on them. As far as OpenSCAD knows, they are still just
lists of lists of numbers, but BOSL2 "knows" that they represent
geometric figures. As relevant here, it has a *function* named
offset(), that accepts an offset value and a list of coordinates, and
does the same sort of offsetting modification that the native OpenSCAD
offset() *module* does, returning a new list of coordinates.
include <bosl2/std.scad>
poly3 = offset(poly, r=3, closed=true);
poly is a list of lists of numbers (from above). BOSL2's offset()
function takes that list, and returns a new list, and we put that in
poly3. It's still just a list of lists of numbers, as far as OpenSCAD
knows, but we know better.
translate([0,-20,0]) polygon(poly3);
Since poly3 is a list of coordinates, we can call polygon() on it and
turn it into an OpenSCAD shape.
It's important to understand that OpenSCAD's offset() module and BOSL2's
offset() function are different things. They do largely the same thing,
but the kind of input they take and yield are very different - the
offset() module, like all transformation modules, takes a shape as a
child and generates a new shape, while the offset() function takes a
list of numbers and returns a new list of numbers. Many BOSL2
operations are available in both forms.
I hope that makes the picture a bit clearer.
[*] Arguably with the exception of UNIX shells, where standard
output/input is sort of dimly like OpenSCAD shapes.

Replying to:

Empathy v1.0
2024 ©Harmonylists.com