On 27.04.2019 10:27, nop head wrote:
BTW, I don't think your pyramid has the correct dimensions, as Adrianv
eluded to, it is not trivial to place the spheres for a non rectangular
or irregular shape. However, I don't see why exact dimensions would be
important to such shapes.
It depends on what one considers 'correct'. Depending on the definition
of 'correct' for this case, I agree that placing the spheres can be
non-trivial.
I loosely designed it using the philosophy you explained earlier: "I
find, in generally, that only dimensions parallel to the axes matter in
my designs."
So, the pyramid was made to give reasonable dimensions on the main axes.
Of course, one could write more elaborate schemes giving different
results, that's the beauty of systems such as OpenSCAD or AngelCAD where
the user has endless possibilities to customize.
Carsten Arnholm
(warning: rerant on the rant)
On Thu, Apr 25, 2019 at 3:45 PM TLC123 torleif.ceder@gmail.com wrote:
My question to the community is: What level of features is sane to be solved
by users and what
belongs in the developer world?
I find all these things you mention intellectually interesting, and I
find minkowski interesting and useful.
However, at the end of the day, all I want to do is round off the
sharp corners on the outside (and inside corners!) of my model so I
don't have to file them off in post processing.
Minkowski drives me crazy because it is extremely slow, AND because I
have to change all the dimensions of my model to keep it dimensionally
accurate. I just want to file off the corner, not add an extra layer
on the outside of my model.
All the OpenSCAD tutorials show doing this with hulls (work work for
me, model is concave), or lots of complex subtractive geometry (it was
hard for me to make this the first time, and you want me to do it
again backwards?), these are just ugly options. Makes me want to go
back to solidworks where I could just select the edge and be done.
Are we making a cad program here or a pretty mathematical abstraction
with no practical application?
When you say this object is the difference between a cube and cylinder I
see that more of a description than an algorithm. The actual algorithm to
do that in user space is very difficult. It takes CGAL seconds to do it
when the cylinder is smooth.
Defining variables twice in the same scope now gives a warning, so if those
are removed it is left with its intended use of overriding defaults with
the command line, or overriding defaults supplied by a library.
Forcing variables to be constants means you know they represent one value
like they would in a maths text and they can't be accidentally changed like
they can in procedural languages and where you potentially have to scan the
entire program to know what the value might be. It means you need to make
up new names for new values and that makes code more readable. For example
in a procedural language you could have a box_width to represent the inside
dimensions of a box and later add the wall thickness and have it represent
the outside dimensions. Somebody actually asked how to do that on this
list. In a declarative language you are forced to give the inside and
outside dimensions different names and that is good.
Yes it is my personal preference but modern languages are moving towards
constant variables because it is safer and better for concurrency and
efficiency. As part of a C compiler all your expressions are rewritten to
have a new variable each time a variable is changed before it is then
allocated to registers and memory.
The CGAL slowness it definitely due to CGAL, not how it is used in
OpenSCAD. I think it uses infinite precision rationals and as soon as we
have rotations and circles most coordinates are irrational. It also doesn't
short circuit facets that are unchanged in a union or difference.
Adrianv likes to define shapes where the vertices before rounding are
specified, even though they don't exist in the final model. So the spheres
of the pyramid need to be placed tangential to all three faces of the
corner, so that the faces of the pyramid are in the same position they
would be if the corners where not rounded. This is what you would get with
Minkowski rounding of a pointed pyramid without any calculation if it ran
fast enough to erode inwards and then offset outwards, but that needs two
Minkowskis and a difference, or three Minkowskis and two differences for
concave corners and is impractically slow with any real world object. So
instead people have to subtract dimensions or place spheres and use hull,
and this is where it gets complicated. All because CGAL is very slow, not
because OpenSCAD can't easily round 3D shapes mathematically.
On Sat, 27 Apr 2019 at 12:36, Carsten Arnholm arnholm@arnholm.org wrote:
On 27.04.2019 10:13, nop head wrote:
I find a declarative language more natural for describing static
geometry. Variables do not need to change because it is a description,
not an algorithm.
These are personal preferences, which is fine. In OpenSCAD users are
describing series of operations using parameters, i.e. describing what I
consider algorithms to generate models, they don't provide explicit
descriptions of the finished product. But this is semantics and not a
big deal in my book.
In some cases you have to use convoluted recursive procedures to build
datastructures in OpenSCAD, those are algorithms as well. Nothing wrong
with recursion, you can use it in AngelCAD to, but there it isn't the
only option on the table.
Having variables that don't change makes code more readable and less
error prone. That is why moving everything to const in C++ is
encouraged.
That is not really what constness in C++ (or AngelCAD) is about. What
makes readable code is debatable. For example, if you do this in OpenSCAD
radius = 1000;
radius = 500;
sphere(radius);
Is it supposed to be legal, and if so what is the correct result? Is the
result consistent with the statement that variables don't change?
If you do instead
radius = 500;
radius = 1000;
sphere(radius);
you get a different result, but considering the idea that the order of
things are not supposed to matter in the OpenSCAD language, the result
seems counterintuitive to me.
In this trivial case it is easy to spot that something is odd, but if it
is part of a larger section of code it is indeed error prone. With error
prone I mean it doesn't match the user expectation, given the language
rules of supposed constness and independence of sequence.
In summary, whatever the rules and syntax of a language, there are
plenty options to write unreadable and confusing code in any language
and OpenSCAD is no exception in this regard.
I don't struggle to code anything I need in OpenSCAD but avoiding CGAL
as much as possible is tedious and makes code less readable. If it was
about 1000 times faster and used 1000 times less memory I could code
directly in 3D rather than decomposing everything into unions of
extruded 2D. And rounding in 3D with minkowski would be practical.
This agrees with my first point earlier. Because of the slowness of CGAL
and/or how it is applied, you end up working around the core feature of
OpenSCAD.
Carsten Arnholm
OpenSCAD mailing list
Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
I don't know that the distinction between algorithm and description is very
clear cut. Certainly saying an object is a difference of a cube and a
cylinder is an algorithm. You have talked recently about how you redesigned
your OpenSCAD to be faster using 2d code with extrusions. I am assuming
that the output didn't change. So what did? You changed to a different
algorithm for producing the same output. An algorithm is, after all, a set
of steps for producing a result.
I think that if you are defining parameters to a model, like the length of
your model, or the width of a part, than immutable variables make perfect
sense. But if you are trying to write a function to compute something
(perhaps the location for where to place those spheres for a hull operation)
then the immutable variables are a nuisance and they force one to write more
cryptic code. You have to use recursion instead of a simple loop. You have
to write chained ternary operators where every possibility is listed in one
statement, where a set of "if" assignment and reassignments would be more
clear. You have to generate a bunch of extra variables, which might waste
memory if the variables are large. Since you can't change "a" after
assigning it you instead make "atemp1" and "atemp2" and "atemp3" and then
combine them to make "a" at the end.
I just tried to do a rounding operation using 3 minkowski calls to see just
how impractical it is. I think it might be OK in some situations to wait an
hour for the minkowski if it was done as a final rounding step and made the
model design dramatically easier. (If my model takes 10 hours to print is
it so bad to have to wait an hour for this?) However, I got
ERROR: CGAL error in CGAL_Nef_polyhedron3(): CGAL ERROR: assertion
violation! Expr: e->incident_sface() != SFace_const_handle() File:
/usr/include/CGAL/Nef_S2/SM_const_decorator.h Line: 326
It does seem that if minkowski were 1000 times faster it would really change
the practical options for how to do rounding. You could round individual
components with 3 minkowski calls and union them together as desired. As
noted above, it is frustrating with minkowski that it makes the model
bigger. I have worked around this several times by designing zero
thickness models that are then expanded with minkowski to the final
thickness. I've run minkowski and then done a difference to remove extra
thickness that was added. It's a nuisance. If minkowski is simpler when
one object is a sphere I wonder if a "round" primitive that rounds its
children could be significantly faster.
--
Sent from: http://forum.openscad.org/
On Sat, Apr 27, 2019 at 09:13:22AM +0100, nop head wrote:
And is more like maths, which is appropriate for describing
geometry. a = a + 1 is nonsense in maths.
It's a bit of a notation issue.
That "a = a + 1" looks a bit like an (maths) equation, but it is not.
In languages like bash and pascal you can see the difference:
the left "a" is a reference to the memory location we call A. The
right one is a reference to the value in that location. In shell programs
the latter is "$a" and the first is "a".
In pascal the assignment is written als := instead of =, to make the
distinction from the = in maths.
But in fact even when you don't write it down that way, these
distinctions happen in (almost) all languages even when not explicitly
evident from the notation.
For example: If in C you write "a+1 = a" which is mathematically the
same as a=a+1, you get the complaint: "not an lvalue" about the
assginment target that is now "a+1".
Roger.
--
** R.E.Wolff@BitWizard.nl ** https://www.BitWizard.nl/ ** +31-15-2049110 **
** Delftechpark 11 2628 XJ Delft, The Netherlands. KVK: 27239233 **
The plan was simple, like my brother-in-law Phil. But unlike
Phil, this plan just might work.
Certainly saying an object is a difference of a cube and a cylinder is an
algorithm.
I don't think we will ever agree. I see that as a description of geometry,
rather than a procedure. Openscad is free to render the scene in any order
it chooses. Wikipedia says "In computer science
https://en.wikipedia.org/wiki/Computer_science, declarative programming is
a programming paradigm https://en.wikipedia.org/wiki/Programming_paradigm—a
style of building the structure and elements of computer programs—that
expresses the logic of a computation
https://en.wikipedia.org/wiki/Computation without describing its control
flow https://en.wikipedia.org/wiki/Control_flow."
I have been a professional programmer for about 30 years and mostly wrote
procedural code. I also designed my own declarative language for describing
things like build systems, OS configurations, or state charts and rendering
make files or C++, etc. That also had variables that only have one value,
although they could have defaults that were overridden, so a bit like
OpenSCAD in that respect. It also built a tree of objects like OpenSCAD
does and then rendered them. The difference being it produced text rather
than graphics and didn't use C syntax. So OpenSCAD works the way I think.
But if you are trying to write a function to compute something (perhaps the
location for where to place those spheres for a hull operation) then the
immutable variables are a nuisance and they force one to write more cryptic
code.
I don't see that at all. I have very few functions that need mutable
variables and I don't find recursion cryptic. It is more like a
mathematical description and a loop is more like a procedure.
You have to write chained ternary operators where every possibility is
listed in one statement, where a set of "if" assignment and reassignments
would be more clear.
The ternary statement can be formatted almost the same as if else. It is
only convention that if else is on multiple lines and ? : is on one line.
You have to generate a bunch of extra variables, which might waste memory
if the variables are large. Since you can't change "a" after assigning it
you instead make "atemp1" and "atemp2" and "atemp3" and then combine them
to make "a" at the end.
The memory used by the script is negligible compared to CGAL. I haven't got
anything with cryptic names like atemp1-3. If I break up expressions I give
them meaningful names but since expressions can occupy multiple lines I
don't split them up unless there are sub-expressions I can factor out to
avoid repetition or give a meaningful name to to make the code clearer.
I have been experimenting with Minkowski rounding of this simple shape.
[image: image.png]
To preserve the original dimensions I use my version of sphere with poles
and equator and I inflate, erode by twice as much and inflate again to
round both the concave and convex corners. This took 45 minutes with $fn =
24. Curiously it stopped LibraOffice starting until it finished rendering.
I think time increases exponentially with $fn.
4 6
8 39
12 120
16 500
20 814
24 2745
[image: image.png]
Minkowski of a convex shape should be as fast as hull because all it needs
to do is take the hull of the the vertices of one shape offset by each of
the vertices of the other shape. For a concave shape it needs to decompose
it into convex shapes, Minkowski each in turn and union the resulting
hulls. The trouble is even union with lots of vertices is very slow with
CGAL. And when you erode inwards the shape is always going to be concave.
On Sat, 27 Apr 2019 at 14:44, Rogier Wolff R.E.Wolff@bitwizard.nl wrote:
On Sat, Apr 27, 2019 at 09:13:22AM +0100, nop head wrote:
And is more like maths, which is appropriate for describing
geometry. a = a + 1 is nonsense in maths.
It's a bit of a notation issue.
That "a = a + 1" looks a bit like an (maths) equation, but it is not.
In languages like bash and pascal you can see the difference:
the left "a" is a reference to the memory location we call A. The
right one is a reference to the value in that location. In shell programs
the latter is "$a" and the first is "a".
In pascal the assignment is written als := instead of =, to make the
distinction from the = in maths.
But in fact even when you don't write it down that way, these
distinctions happen in (almost) all languages even when not explicitly
evident from the notation.
For example: If in C you write "a+1 = a" which is mathematically the
same as a=a+1, you get the complaint: "not an lvalue" about the
assginment target that is now "a+1".
Roger.
--
** R.E.Wolff@BitWizard.nl ** https://www.BitWizard.nl/ ** +31-15-2049110
**
** Delftechpark 11 2628 XJ Delft, The Netherlands. KVK: 27239233 **
The plan was simple, like my brother-in-law Phil. But unlike
Phil, this plan just might work.
OpenSCAD mailing list
Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
On 27 Apr 2019 at 9:13, nop head wrote:
a = a + 1 is nonsense in maths.
And I am extremely grateful that programming <> maths.
It's shorthand for let a become equal to a+1. Would hate to have to write that out all the time.
--
Magic trumps science for most people,
and wishful thinking drives a lot of decision-making.
- Joe Haldeman
It isn't the notation it the fact that in maths you don't let x mean one
thing and then on the next line make it mean some else. x means the same
thing throughout the text. You can have y = x + 1, but not x = x + 1. You
can have sigma with subscripts that make n range from 1 to something but
that is like a for loop, which OpenScad has. There are lots of programming
languages where you you can't mutate variables. It seems that most people
on this list just don't get it.
On Sat, 27 Apr 2019 at 22:10, lar3ry@sasktel.net wrote:
On 27 Apr 2019 at 9:13, nop head wrote:
a = a + 1 is nonsense in maths.
And I am extremely grateful that programming <> maths.
It's shorthand for let a become equal to a+1. Would hate to have to write
that out all the time.
--
Magic trumps science for most people,
and wishful thinking drives a lot of decision-making.
- Joe Haldeman
OpenSCAD mailing list
Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
nophead wrote
Certainly saying an object is a difference of a cube and a cylinder is an
algorithm.
I don't think we will ever agree. I see that as a description of geometry,
rather than a procedure. Openscad is free to render the scene in any order
it chooses. Wikipedia says "In computer science
<https://en.wikipedia.org/wiki/Computer_science>, declarative
programming is
a programming paradigm
<https://en.wikipedia.org/wiki/Programming_paradigm>—a
style of building the structure and elements of computer programs—that
expresses the logic of a computation
<https://en.wikipedia.org/wiki/Computation> without describing its
control
flow <https://en.wikipedia.org/wiki/Control_flow>."
That seems to describe OpenSCAD. But what does that have to do with whether
OpenSCAD files are algorithms? The word algorithm is pretty broad, and it
seems pretty clear that declarative programming is still giving algorithms.
But if you are trying to write a function to compute something (perhaps
the
location for where to place those spheres for a hull operation) then the
immutable variables are a nuisance and they force one to write more
cryptic
code.
I don't see that at all. I have very few functions that need mutable
variables and I don't find recursion cryptic. It is more like a
mathematical description and a loop is more like a procedure.
Writing code into the required form to get tail-recursion in my experience
tends to increase code complexity and make the code more cryptic. I'm not
saying recursion is inherently cryptic, but I think a loop is generally
easier to understand. What if I have an algorithm that requires more than
one pass over the data to produce its output? That may not have an obvious
solution through simple recursion.
You have to write chained ternary operators where every possibility is
listed in one statement, where a set of "if" assignment and reassignments
would be more clear.
The ternary statement can be formatted almost the same as if else. It is
only convention that if else is on multiple lines and ? : is on one line.
The problem is not the ternary operator itself---that's just notation---but
the fact that you have to assign the variable with a single chain of
ternary operators. I ran into a complication recently where I was trying to
determine the parameters to construct and object from user inputs. I needed
to compute parameters h and r from the user inputs, but some user inputs
make it natural to compute r first and compute h from r and others have the
reverse characteristic. In a language where I can have multiple assignments
and if statements I could have divided up the cases and computed each one in
the most natural way. Instead I had to derive more complex formulas for
certain cases so that I could compute one of the variables first from any
user input.
This is the sort of situation I'm talking about.
I've been thinking about a routine to make a box with rounded edges and
interior corners and the major challenge is that when I shrink the boundary,
the number of vertices may change, which makes it hard to assign polyhedron
faces. I think this would be much easier to track and handle if variables
could change.
You have to generate a bunch of extra variables, which might waste memory
if the variables are large. Since you can't change "a" after assigning
it
you instead make "atemp1" and "atemp2" and "atemp3" and then combine them
to make "a" at the end.
The memory used by the script is negligible compared to CGAL. I haven't
got
anything with cryptic names like atemp1-3. If I break up expressions I
give
them meaningful names but since expressions can occupy multiple lines I
don't split them up unless there are sub-expressions I can factor out to
avoid repetition or give a meaningful name to to make the code clearer.
So in the case where if a is set then r=f(a), h=g(r,a) and if b is set then
h=F(b), r=G(h,b), how would you write this? I mean, I suppose you can do
this
r_or_h = !is_undef(a) ? f(a) : F(b),
r = !is_undef(a) ? r_or_h : G(r_or_h,b),
h = !is_undef(a) ? F(r_or_h,a) : r_or_h;
Is there some alternative, because I think that's effective at obscuring a
simple underlying relationship.
--
Sent from: http://forum.openscad.org/
On 27 Apr 2019 at 22:21, nop head wrote:
It isn't the notation it the fact that in maths you don't let x mean one thing and then on the next line
make it mean some else.
Again reinforcing my happiness in using a program instead of math.
There are lots of programming languages where you
can't mutate variables.
And yet they are still called variables. Fascinating.
--
Magic trumps science for most people,
and wishful thinking drives a lot of decision-making.
- Joe Haldeman