discuss@lists.openscad.org

OpenSCAD general discussion Mailing-list

View all threads

simple question

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.