Convexity & difference()

AM
Thu, Jan 25, 2024 4:50 AM

You might find it instructive to take a look at the code for BOSL2, which
may give you some insight into how you might write more sophisticated code.

It's possible to implement total_animation_steps_up_to and
total_animation_steps without recursion at all:

total_animation_steps = animation_durations *
[for(i=[0:len(animation_durations)-1]) 1];

function total_animation_steps_up_to(partnum) =
partnum==1 ? 0
: [for(i=[0:1:partnum-2]) animation_durations[i]] *
[for(i=[0:1:partnum-2]) 1];

But get_part_number needs recursion. Using 1 based indexing in a 0 based

On Wed, Jan 24, 2024 at 11:35 PM neri-engineering via Discuss <

Well that certainly makes things easier, thanks.  This syntax is
reminiscent of TinyScheme, which I used inside of GIMP image tool.

Sent with Proton Mail https://proton.me/ secure email.

On Wednesday, January 24th, 2024 at 10:04 PM, Father Horton via Discuss <

Also note that you can have multiple assignments in a let statement. Just
separate them with commas. I assume they evaluate left-to-right, though I
don't think I've ever put that to the test.

On Wed, Jan 24, 2024 at 9:50 PM Father Horton fatherhorton@gmail.com
wrote:

Actually you can declare local variables. It's just not obvious how.

From the manual:

function get_square_triangle_perimeter(p1, p2) =  let (hypotenuse = sqrt(p1p1+p2p2))    p1 + p2 + hypotenuse;

On Wed, Jan 24, 2024 at 9:47 PM neri-engineering via Discuss <

It's because in functions you can't declare local variables. So many
times you end up writing helper functions which take the semi-compiled form
of equations/data. This is one of the reasons why recursive functions in
OpenSCAD are difficult to write. It certainly takes some getting used to.
That's why I call it "sorcery". It's good mental gymnastics to keep you
sharp, to prevent the ole Alzheimer's from setting in. We keep our bodies
sharp by working out and we keep our minds sharp by writing recursive
functions in OpenSCAD. Some examples I can give you which demonstrate my
point. With a standard iterative process we would accomplish the following
with simpler code.

// There are 21 steps currently.
animation_durations=[1, // # 1 slipper_back_plate()
1, // # 2 slipper_bearing()
2, // # 3 top_shaft()
1, // # 4 slipper_back_plate_pin()
2, // # 5 spur_gear() & left_slipper_pad()
1, // # 7 slipper_front_plate()
1, // # 8 slipper_spring()
3, // # 9 slipper_nut()
1, // #10 slipper_to_drive_gear_spacer()
1, // #11 drive_gear()
1, // #12 top_shaft_left_spacer() &
// left_top_shaft_bearing()
1, // #13 top_shaft_right_spacer() &
// right_top_shaft_bearing()
2, // #14 top_shaft_end_screw()
2]; // # ending()

// Returns a 1-based part number. Does not start from zero. Identifies
the
// part being "introduced" in its introductory animation.
function get_part_number(tick,index)=
(tick<0)?index:
(get_part_number(tick-animation_durations[index],
index+1));

function total_animation_steps(index,step_count)=
(index>=len(animation_durations))?
step_count:
total_animation_steps(index+1,
step_count+animation_durations[index]);

// Parameter 'partnum' is one-based. Returns the number of animation
steps
// that have preceded the beginning of part intro animation for
specified part.
function total_animation_steps_up_to(partnum,index,step_count)=
(index>=(partnum-1))?
step_count:
total_animation_steps_up_to(partnum,index+1,
step_count+animation_durations[index]);

// The input parameter is 1-based and represents the part #.
function part_animation_steps(partnum)=
animation_durations[partnum-1];

// Value 't' is a value in [0,1), it increases linearly with time to
span the
// entirety of animation.
t=0.34; // For example, we're a bit more than 1/3 of the way through the
anim.

// Parameter 'i' is the animation ticker, zero-based.
i=floor(t*total_animation_steps(0,0)); // Start from 0.
p=get_part_number(i,0);

// Parameter 'w' is like 't', meaning it is in the range 0 <= w < 1, but
it
// is specific to the part intro animation. The part intro animation
begins
// at w=0 and is already over at w=1.
pre_w=(t*total_animation_steps(0,0)
-total_animation_steps_up_to(p,0,0))/part_animation_steps(p);

// First it will print out a one-based index describing the part we're
on.
echo(p);

// Next it will print out which fraction of this part's scene we've done.
echo(pre_w);

Sent with Proton Mail https://proton.me/ secure email.

On Wednesday, January 24th, 2024 at 7:21 PM, Adrian Mariano via Discuss <

I don't understand why it's any trickier to assemble the order of points
with recursive programming. In either case, if you have a growing list (the
result) you compute new values and add them to the end of the list.
Normally I write a recursive function something like

function func(result,info) =
done ? result
: func(concat(result, more_results_based_on_info),
new_info));

The result grows in an obvious way and there is no "trickery" or
"sorcery" involved. It's as straight forward as any other kind of coding,
though it can get annoying if "info" contains many things, and I can't say
anything good about the speed of execution.

On Wed, Jan 24, 2024 at 3:30 PM neri-engineering via Discuss <

With recursive functions it's a bit tricky to figure out the order of
points after they're all assembled. The problem I had was that the
recursive function which called concat() on two lists did it in an order
that resulted in the final list having its points in a reverse order from
what I expected. There is always "trickery" and a fair bit of "sorcery"
involved in getting recursive functions to do the right thing. Anyhow this
reverse order (from what I was assuming) is what caused the
clockwise/counterclockwise polygon traversal situation.

Sent with Proton Mail https://proton.me/ secure email.

On Wednesday, January 24th, 2024 at 2:06 PM, David Phillip Oster via

Thank you for that neri-engineering, and nop head. That’s a fun example.

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

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

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

N
neri-engineering
Thu, Jan 25, 2024 5:07 AM

I'm actually tidying up my OpenSCAD code but I'm moving into CadQuery - that is my next main focus. I need more of the abilities that that tool provides. A completely different paradigm is used there, namely Python, which exposes ability to use a richer language and libs.

I may share my optimized OpenSCAD thread library on this mailing list. Would there be an interest in that? I just managed to squeeze out at least a 5x performance increase in F5 mode because I construct a subtrahend plug out of a single polyhedron.

Sent with Proton Mail secure email.

On Wednesday, January 24th, 2024 at 10:50 PM, Adrian Mariano via Discuss discuss@lists.openscad.org wrote:

You might find it instructive to take a look at the code for BOSL2, which may give you some insight into how you might write more sophisticated code.

It's possible to implement total_animation_steps_up_to and total_animation_steps without recursion at all:

total_animation_steps = animation_durations * [for(i=[0:len(animation_durations)-1]) 1];

function total_animation_steps_up_to(partnum) =
partnum==1 ? 0
: [for(i=[0:1:partnum-2]) animation_durations[i]] * [for(i=[0:1:partnum-2]) 1];
But get_part_number needs recursion. Using 1 based indexing in a 0 based language is a questionable complication. Why not start with part 0?

On Wed, Jan 24, 2024 at 11:35 PM neri-engineering via Discuss discuss@lists.openscad.org wrote:

Well that certainly makes things easier, thanks. This syntax is reminiscent of TinyScheme, which I used inside of GIMP image tool.

Sent with Proton Mail secure email.

On Wednesday, January 24th, 2024 at 10:04 PM, Father Horton via Discuss discuss@lists.openscad.org wrote:

Also note that you can have multiple assignments in a let statement. Just separate them with commas. I assume they evaluate left-to-right, though I don't think I've ever put that to the test.

On Wed, Jan 24, 2024 at 9:50 PM Father Horton fatherhorton@gmail.com wrote:

Actually you can declare local variables. It's just not obvious how.

From the manual:

function

get_square_triangle_perimeter

(

p1

,

p2

)

=

let

(

hypotenuse

=

sqrt

(

p1

p1

p2

p2

))

p1

p2

hypotenuse

;

On Wed, Jan 24, 2024 at 9:47 PM neri-engineering via Discuss discuss@lists.openscad.org wrote:

It's because in functions you can't declare local variables. So many times you end up writing helper functions which take the semi-compiled form of equations/data. This is one of the reasons why recursive functions in OpenSCAD are difficult to write. It certainly takes some getting used to. That's why I call it "sorcery". It's good mental gymnastics to keep you sharp, to prevent the ole Alzheimer's from setting in. We keep our bodies sharp by working out and we keep our minds sharp by writing recursive functions in OpenSCAD. Some examples I can give you which demonstrate my point. With a standard iterative process we would accomplish the following with simpler code.

// There are 21 steps currently.
animation_durations=[1, // # 1 slipper_back_plate()
1, // # 2 slipper_bearing()
2, // # 3 top_shaft()
1, // # 4 slipper_back_plate_pin()
2, // # 5 spur_gear() & left_slipper_pad()
1, // # 7 slipper_front_plate()
1, // # 8 slipper_spring()
3, // # 9 slipper_nut()
1, // #10 slipper_to_drive_gear_spacer()
1, // #11 drive_gear()
1, // #12 top_shaft_left_spacer() &
// left_top_shaft_bearing()
1, // #13 top_shaft_right_spacer() &
// right_top_shaft_bearing()
2, // #14 top_shaft_end_screw()
2]; // # ending()

// Returns a 1-based part number. Does not start from zero. Identifies the
// part being "introduced" in its introductory animation.
function get_part_number(tick,index)=
(tick<0)?index:
(get_part_number(tick-animation_durations[index],
index+1));

function total_animation_steps(index,step_count)=
(index>=len(animation_durations))?
step_count:
total_animation_steps(index+1,
step_count+animation_durations[index]);

// Parameter 'partnum' is one-based. Returns the number of animation steps
// that have preceded the beginning of part intro animation for specified part.
function total_animation_steps_up_to(partnum,index,step_count)=
(index>=(partnum-1))?
step_count:
total_animation_steps_up_to(partnum,index+1,
step_count+animation_durations[index]);

// The input parameter is 1-based and represents the part #.
function part_animation_steps(partnum)=
animation_durations[partnum-1];

// Value 't' is a value in [0,1), it increases linearly with time to span the
// entirety of animation.
t=0.34; // For example, we're a bit more than 1/3 of the way through the anim.

// Parameter 'i' is the animation ticker, zero-based.
i=floor(t*total_animation_steps(0,0)); // Start from 0.
p=get_part_number(i,0);

// Parameter 'w' is like 't', meaning it is in the range 0 <= w < 1, but it
// is specific to the part intro animation. The part intro animation begins
// at w=0 and is already over at w=1.
pre_w=(t*total_animation_steps(0,0)
-total_animation_steps_up_to(p,0,0))/part_animation_steps(p);

// First it will print out a one-based index describing the part we're on.
echo(p);

// Next it will print out which fraction of this part's scene we've done.echo(pre_w);

Sent with Proton Mail secure email.

On Wednesday, January 24th, 2024 at 7:21 PM, Adrian Mariano via Discuss discuss@lists.openscad.org wrote:

I don't understand why it's any trickier to assemble the order of points with recursive programming. In either case, if you have a growing list (the result) you compute new values and add them to the end of the list. Normally I write a recursive function something like

function func(result,info) =
done ? result
: func(concat(result, more_results_based_on_info),
new_info));

The result grows in an obvious way and there is no "trickery" or "sorcery" involved. It's as straight forward as any other kind of coding, though it can get annoying if "info" contains many things, and I can't say anything good about the speed of execution.

On Wed, Jan 24, 2024 at 3:30 PM neri-engineering via Discuss discuss@lists.openscad.org wrote:

With recursive functions it's a bit tricky to figure out the order of points after they're all assembled. The problem I had was that the recursive function which called concat() on two lists did it in an order that resulted in the final list having its points in a reverse order from what I expected. There is always "trickery" and a fair bit of "sorcery" involved in getting recursive functions to do the right thing. Anyhow this reverse order (from what I was assuming) is what caused the clockwise/counterclockwise polygon traversal situation.

Sent with Proton Mail secure email.

On Wednesday, January 24th, 2024 at 2:06 PM, David Phillip Oster via Discuss discuss@lists.openscad.org wrote:

Thank you for that neri-engineering, and nop head. That’s a fun example.

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

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

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

SP
Sanjeev Prabhakar
Thu, Jan 25, 2024 4:47 PM

I'm actually tidying up my OpenSCAD code but I'm moving into CadQuery -
that is my next main focus.

good luck

On Thu, 25 Jan 2024 at 10:37, neri-engineering via Discuss <

I'm actually tidying up my OpenSCAD code but I'm moving into CadQuery -
that is my next main focus.  I need more of the abilities that that tool
provides.  A completely different paradigm is used there, namely Python,
which exposes ability to use a richer language and libs.

I may share my optimized OpenSCAD thread library on this mailing list.
Would there be an interest in that?  I just managed to squeeze out at least
a 5x performance increase in F5 mode because I construct a subtrahend plug
out of a single polyhedron.

Sent with Proton Mail https://proton.me/ secure email.

On Wednesday, January 24th, 2024 at 10:50 PM, Adrian Mariano via Discuss <

You might find it instructive to take a look at the code for BOSL2, which
may give you some insight into how you might write more sophisticated code.

It's possible to implement total_animation_steps_up_to and
total_animation_steps without recursion at all:

total_animation_steps = animation_durations *
[for(i=[0:len(animation_durations)-1]) 1];

function total_animation_steps_up_to(partnum) =
partnum==1 ? 0
: [for(i=[0:1:partnum-2]) animation_durations[i]] *
[for(i=[0:1:partnum-2]) 1];

But get_part_number needs recursion. Using 1 based indexing in a 0 based

On Wed, Jan 24, 2024 at 11:35 PM neri-engineering via Discuss <

Well that certainly makes things easier, thanks. This syntax is
reminiscent of TinyScheme, which I used inside of GIMP image tool.

Sent with Proton Mail https://proton.me/ secure email.

On Wednesday, January 24th, 2024 at 10:04 PM, Father Horton via Discuss <

Also note that you can have multiple assignments in a let statement. Just
separate them with commas. I assume they evaluate left-to-right, though I
don't think I've ever put that to the test.

On Wed, Jan 24, 2024 at 9:50 PM Father Horton fatherhorton@gmail.com
wrote:

Actually you can declare local variables. It's just not obvious how.

From the manual:

function get_square_triangle_perimeter(p1, p2) =  let (hypotenuse = sqrt(p1p1+p2p2))    p1 + p2 + hypotenuse;

On Wed, Jan 24, 2024 at 9:47 PM neri-engineering via Discuss <

It's because in functions you can't declare local variables. So many
times you end up writing helper functions which take the semi-compiled form
of equations/data. This is one of the reasons why recursive functions in
OpenSCAD are difficult to write. It certainly takes some getting used to.
That's why I call it "sorcery". It's good mental gymnastics to keep you
sharp, to prevent the ole Alzheimer's from setting in. We keep our bodies
sharp by working out and we keep our minds sharp by writing recursive
functions in OpenSCAD. Some examples I can give you which demonstrate my
point. With a standard iterative process we would accomplish the following
with simpler code.

// There are 21 steps currently.
animation_durations=[1, // # 1 slipper_back_plate()
1, // # 2 slipper_bearing()
2, // # 3 top_shaft()
1, // # 4 slipper_back_plate_pin()
2, // # 5 spur_gear() & left_slipper_pad()
1, // # 7 slipper_front_plate()
1, // # 8 slipper_spring()
3, // # 9 slipper_nut()
1, // #10 slipper_to_drive_gear_spacer()
1, // #11 drive_gear()
1, // #12 top_shaft_left_spacer() &
// left_top_shaft_bearing()
1, // #13 top_shaft_right_spacer() &
// right_top_shaft_bearing()
2, // #14 top_shaft_end_screw()
2]; // # ending()

// Returns a 1-based part number. Does not start from zero. Identifies
the
// part being "introduced" in its introductory animation.
function get_part_number(tick,index)=
(tick<0)?index:
(get_part_number(tick-animation_durations[index],
index+1));

function total_animation_steps(index,step_count)=
(index>=len(animation_durations))?
step_count:
total_animation_steps(index+1,
step_count+animation_durations[index]);

// Parameter 'partnum' is one-based. Returns the number of animation
steps
// that have preceded the beginning of part intro animation for
specified part.
function total_animation_steps_up_to(partnum,index,step_count)=
(index>=(partnum-1))?
step_count:
total_animation_steps_up_to(partnum,index+1,
step_count+animation_durations[index]);

// The input parameter is 1-based and represents the part #.
function part_animation_steps(partnum)=
animation_durations[partnum-1];

// Value 't' is a value in [0,1), it increases linearly with time to
span the
// entirety of animation.
t=0.34; // For example, we're a bit more than 1/3 of the way through
the anim.

// Parameter 'i' is the animation ticker, zero-based.
i=floor(t*total_animation_steps(0,0)); // Start from 0.
p=get_part_number(i,0);

// Parameter 'w' is like 't', meaning it is in the range 0 <= w < 1,
but it
// is specific to the part intro animation. The part intro animation
begins
// at w=0 and is already over at w=1.
pre_w=(t*total_animation_steps(0,0)
-total_animation_steps_up_to(p,0,0))/part_animation_steps(p);

// First it will print out a one-based index describing the part we're
on.
echo(p);

// Next it will print out which fraction of this part's scene we've
done.
echo(pre_w);

Sent with Proton Mail https://proton.me/ secure email.

On Wednesday, January 24th, 2024 at 7:21 PM, Adrian Mariano via Discuss

I don't understand why it's any trickier to assemble the order of
points with recursive programming. In either case, if you have a growing
list (the result) you compute new values and add them to the end of the
list. Normally I write a recursive function something like

function func(result,info) =
done ? result
: func(concat(result, more_results_based_on_info),
new_info));

The result grows in an obvious way and there is no "trickery" or
"sorcery" involved. It's as straight forward as any other kind of coding,
though it can get annoying if "info" contains many things, and I can't say
anything good about the speed of execution.

On Wed, Jan 24, 2024 at 3:30 PM neri-engineering via Discuss <

With recursive functions it's a bit tricky to figure out the order of
points after they're all assembled. The problem I had was that the
recursive function which called concat() on two lists did it in an order
that resulted in the final list having its points in a reverse order from
what I expected. There is always "trickery" and a fair bit of "sorcery"
involved in getting recursive functions to do the right thing. Anyhow this
reverse order (from what I was assuming) is what caused the
clockwise/counterclockwise polygon traversal situation.

Sent with Proton Mail https://proton.me/ secure email.

On Wednesday, January 24th, 2024 at 2:06 PM, David Phillip Oster via

Thank you for that neri-engineering, and nop head. That’s a fun
example.

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

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

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

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

N
neri-engineering
Sun, Jan 28, 2024 12:11 AM

Indeed the 'let' construct is a life-saver to make code much clearer whereas it would have taken additional recursive helper functions to achieve the same level of clarity. This is an example that is working for me now.

echo(__invol_gear_path_builder(0,3,false));

// Parameter 'i' should be initialized to zero. Some examples:
// segs=3,q=true: [0,2,4,6,8,9,7,5,3,1]
// segs=3,q=false: [0, 4,6,8,9,7,5, 1]
function __invol_gear_path_builder(i,segs,q)=
((i==-1)?[]:
let(even=((i%2)==0),
flip=(even&&(i==((segs+1)*2))),
incr=(flip?1:(even?2:-2)),
omit=((!q)&&((i==2)||(i==3))))
concat(omit?[]:[i], __invol_gear_path_builder(i+incr,segs,q)));

Sent with Proton Mail secure email.

On Wednesday, January 24th, 2024 at 9:50 PM, Father Horton via Discuss discuss@lists.openscad.org wrote:

Actually you can declare local variables. It's just not obvious how.

From the manual:

function

get_square_triangle_perimeter

(

p1

,

p2

)

=

let

(

hypotenuse

=

sqrt

(

p1

p1

p2

p2

))

p1

p2

hypotenuse

;

On Wed, Jan 24, 2024 at 9:47 PM neri-engineering via Discuss discuss@lists.openscad.org wrote:

It's because in functions you can't declare local variables. So many times you end up writing helper functions which take the semi-compiled form of equations/data. This is one of the reasons why recursive functions in OpenSCAD are difficult to write. It certainly takes some getting used to. That's why I call it "sorcery". It's good mental gymnastics to keep you sharp, to prevent the ole Alzheimer's from setting in. We keep our bodies sharp by working out and we keep our minds sharp by writing recursive functions in OpenSCAD. Some examples I can give you which demonstrate my point. With a standard iterative process we would accomplish the following with simpler code.

// There are 21 steps currently.
animation_durations=[1, // # 1 slipper_back_plate()
1, // # 2 slipper_bearing()
2, // # 3 top_shaft()
1, // # 4 slipper_back_plate_pin()
2, // # 5 spur_gear() & left_slipper_pad()
1, // # 7 slipper_front_plate()
1, // # 8 slipper_spring()
3, // # 9 slipper_nut()
1, // #10 slipper_to_drive_gear_spacer()
1, // #11 drive_gear()
1, // #12 top_shaft_left_spacer() &
// left_top_shaft_bearing()
1, // #13 top_shaft_right_spacer() &
// right_top_shaft_bearing()
2, // #14 top_shaft_end_screw()
2]; // # ending()

// Returns a 1-based part number. Does not start from zero. Identifies the
// part being "introduced" in its introductory animation.
function get_part_number(tick,index)=
(tick<0)?index:
(get_part_number(tick-animation_durations[index],
index+1));

function total_animation_steps(index,step_count)=
(index>=len(animation_durations))?
step_count:
total_animation_steps(index+1,
step_count+animation_durations[index]);

// Parameter 'partnum' is one-based. Returns the number of animation steps
// that have preceded the beginning of part intro animation for specified part.
function total_animation_steps_up_to(partnum,index,step_count)=
(index>=(partnum-1))?
step_count:
total_animation_steps_up_to(partnum,index+1,
step_count+animation_durations[index]);

// The input parameter is 1-based and represents the part #.
function part_animation_steps(partnum)=
animation_durations[partnum-1];

// Value 't' is a value in [0,1), it increases linearly with time to span the
// entirety of animation.
t=0.34; // For example, we're a bit more than 1/3 of the way through the anim.

// Parameter 'i' is the animation ticker, zero-based.
i=floor(t*total_animation_steps(0,0)); // Start from 0.
p=get_part_number(i,0);

// Parameter 'w' is like 't', meaning it is in the range 0 <= w < 1, but it
// is specific to the part intro animation. The part intro animation begins
// at w=0 and is already over at w=1.
pre_w=(t*total_animation_steps(0,0)
-total_animation_steps_up_to(p,0,0))/part_animation_steps(p);

// First it will print out a one-based index describing the part we're on.
echo(p);

// Next it will print out which fraction of this part's scene we've done.echo(pre_w);

Sent with Proton Mail secure email.

On Wednesday, January 24th, 2024 at 7:21 PM, Adrian Mariano via Discuss discuss@lists.openscad.org wrote:

I don't understand why it's any trickier to assemble the order of points with recursive programming. In either case, if you have a growing list (the result) you compute new values and add them to the end of the list. Normally I write a recursive function something like

function func(result,info) =
done ? result
: func(concat(result, more_results_based_on_info),
new_info));

The result grows in an obvious way and there is no "trickery" or "sorcery" involved. It's as straight forward as any other kind of coding, though it can get annoying if "info" contains many things, and I can't say anything good about the speed of execution.

On Wed, Jan 24, 2024 at 3:30 PM neri-engineering via Discuss discuss@lists.openscad.org wrote:

With recursive functions it's a bit tricky to figure out the order of points after they're all assembled. The problem I had was that the recursive function which called concat() on two lists did it in an order that resulted in the final list having its points in a reverse order from what I expected. There is always "trickery" and a fair bit of "sorcery" involved in getting recursive functions to do the right thing. Anyhow this reverse order (from what I was assuming) is what caused the clockwise/counterclockwise polygon traversal situation.

Sent with Proton Mail secure email.

On Wednesday, January 24th, 2024 at 2:06 PM, David Phillip Oster via Discuss discuss@lists.openscad.org wrote:

Thank you for that neri-engineering, and nop head. That’s a fun example.

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

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

FH
Father Horton
Sun, Jan 28, 2024 12:55 AM

How crazy do you want to get? If you call parameters by name, you can have
it initialize the value of i for you with a default.

On Sat, Jan 27, 2024 at 6:11 PM neri-engineering <
neri-engineering@protonmail.com> wrote:

Indeed the 'let' construct is a life-saver to make code much clearer
whereas it would have taken additional recursive helper functions to
achieve the same level of clarity.  This is an example that is working for
me now.

echo(__invol_gear_path_builder(0,3,false));

// Parameter 'i' should be initialized to zero.  Some examples:
//  segs=3,q=true:  [0,2,4,6,8,9,7,5,3,1]
//  segs=3,q=false: [0,  4,6,8,9,7,5,  1]
function __invol_gear_path_builder(i,segs,q)=
((i==-1)?[]:
let(even=((i%2)==0),
flip=(even&&(i==((segs+1)*2))),
incr=(flip?1:(even?2:-2)),
omit=((!q)&&((i==2)||(i==3))))
concat(omit?[]:[i],
__invol_gear_path_builder(i+incr,segs,q)));

Sent with Proton Mail https://proton.me/ secure email.

On Wednesday, January 24th, 2024 at 9:50 PM, Father Horton via Discuss <

Actually you can declare local variables. It's just not obvious how.

From the manual:

function get_square_triangle_perimeter(p1, p2) =  let (hypotenuse = sqrt(p1p1+p2p2))    p1 + p2 + hypotenuse;

On Wed, Jan 24, 2024 at 9:47 PM neri-engineering via Discuss <

It's because in functions you can't declare local variables. So many
times you end up writing helper functions which take the semi-compiled form
of equations/data. This is one of the reasons why recursive functions in
OpenSCAD are difficult to write. It certainly takes some getting used to.
That's why I call it "sorcery". It's good mental gymnastics to keep you
sharp, to prevent the ole Alzheimer's from setting in. We keep our bodies
sharp by working out and we keep our minds sharp by writing recursive
functions in OpenSCAD. Some examples I can give you which demonstrate my
point. With a standard iterative process we would accomplish the following
with simpler code.

// There are 21 steps currently.
animation_durations=[1, // # 1 slipper_back_plate()
1, // # 2 slipper_bearing()
2, // # 3 top_shaft()
1, // # 4 slipper_back_plate_pin()
2, // # 5 spur_gear() & left_slipper_pad()
1, // # 7 slipper_front_plate()
1, // # 8 slipper_spring()
3, // # 9 slipper_nut()
1, // #10 slipper_to_drive_gear_spacer()
1, // #11 drive_gear()
1, // #12 top_shaft_left_spacer() &
// left_top_shaft_bearing()
1, // #13 top_shaft_right_spacer() &
// right_top_shaft_bearing()
2, // #14 top_shaft_end_screw()
2]; // # ending()

// Returns a 1-based part number. Does not start from zero. Identifies the
// part being "introduced" in its introductory animation.
function get_part_number(tick,index)=
(tick<0)?index:
(get_part_number(tick-animation_durations[index],
index+1));

function total_animation_steps(index,step_count)=
(index>=len(animation_durations))?
step_count:
total_animation_steps(index+1,
step_count+animation_durations[index]);

// Parameter 'partnum' is one-based. Returns the number of animation steps
// that have preceded the beginning of part intro animation for specified
part.
function total_animation_steps_up_to(partnum,index,step_count)=
(index>=(partnum-1))?
step_count:
total_animation_steps_up_to(partnum,index+1,
step_count+animation_durations[index]);

// The input parameter is 1-based and represents the part #.
function part_animation_steps(partnum)=
animation_durations[partnum-1];

// Value 't' is a value in [0,1), it increases linearly with time to span
the
// entirety of animation.
t=0.34; // For example, we're a bit more than 1/3 of the way through the
anim.

// Parameter 'i' is the animation ticker, zero-based.
i=floor(t*total_animation_steps(0,0)); // Start from 0.
p=get_part_number(i,0);

// Parameter 'w' is like 't', meaning it is in the range 0 <= w < 1, but
it
// is specific to the part intro animation. The part intro animation
begins
// at w=0 and is already over at w=1.
pre_w=(t*total_animation_steps(0,0)
-total_animation_steps_up_to(p,0,0))/part_animation_steps(p);

// First it will print out a one-based index describing the part we're on.
echo(p);

// Next it will print out which fraction of this part's scene we've done.
echo(pre_w);

Sent with Proton Mail https://proton.me/ secure email.

On Wednesday, January 24th, 2024 at 7:21 PM, Adrian Mariano via Discuss <

I don't understand why it's any trickier to assemble the order of points
with recursive programming. In either case, if you have a growing list (the
result) you compute new values and add them to the end of the list.
Normally I write a recursive function something like

function func(result,info) =
done ? result
: func(concat(result, more_results_based_on_info),
new_info));

The result grows in an obvious way and there is no "trickery" or
"sorcery" involved. It's as straight forward as any other kind of coding,
though it can get annoying if "info" contains many things, and I can't say
anything good about the speed of execution.

On Wed, Jan 24, 2024 at 3:30 PM neri-engineering via Discuss <

With recursive functions it's a bit tricky to figure out the order of
points after they're all assembled. The problem I had was that the
recursive function which called concat() on two lists did it in an order
that resulted in the final list having its points in a reverse order from
what I expected. There is always "trickery" and a fair bit of "sorcery"
involved in getting recursive functions to do the right thing. Anyhow this
reverse order (from what I was assuming) is what caused the
clockwise/counterclockwise polygon traversal situation.

Sent with Proton Mail https://proton.me/ secure email.

On Wednesday, January 24th, 2024 at 2:06 PM, David Phillip Oster via

Thank you for that neri-engineering, and nop head. That’s a fun example.

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

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

N
neri-engineering
Sun, Jan 28, 2024 4:10 AM

Are you American? Your ways involve "taking swipes at people" without fully comprehending how something is used. If you can belittle someone else, even in the case where that person you are belittling specifically chose the methodology for his approach with a very good reason, then all the better for you. In the same way the American two year old temper tantrum baby is destroying the world around itself, internationally, by taking swipes at people everywhere, because it is going through its "terrible twos", but in this case it's more like two centuries of the Roman fucking Empire version 2.0, the original of which had Jesus of Nazareth put to death. These religious retards, who pretend to praise this man but are secretly worshiping the killers of this man, are especially to blame for this problem.

Yet another reason I'm moving away from OpenSCAD. It's because many of the participants on this list are mental fucking retards.

Now I could go into how similar the Roman Catholic Church is to the GPL license, both in its monopolistic, forceful, and contaminating strategy and by whom it was invented, but I will save my fingers and breath and focus instead on doing good work.

Sent with Proton Mail secure email.

On Saturday, January 27th, 2024 at 6:55 PM, Father Horton via Discuss discuss@lists.openscad.org wrote:

How crazy do you want to get? If you call parameters by name, you can have it initialize the value of i for you with a default.

On Sat, Jan 27, 2024 at 6:11 PM neri-engineering neri-engineering@protonmail.com wrote:

Indeed the 'let' construct is a life-saver to make code much clearer whereas it would have taken additional recursive helper functions to achieve the same level of clarity. This is an example that is working for me now.

echo(__invol_gear_path_builder(0,3,false));

// Parameter 'i' should be initialized to zero. Some examples:
// segs=3,q=true: [0,2,4,6,8,9,7,5,3,1]
// segs=3,q=false: [0, 4,6,8,9,7,5, 1]
function __invol_gear_path_builder(i,segs,q)=
((i==-1)?[]:
let(even=((i%2)==0),
flip=(even&&(i==((segs+1)*2))),
incr=(flip?1:(even?2:-2)),
omit=((!q)&&((i==2)||(i==3))))
concat(omit?[]:[i], __invol_gear_path_builder(i+incr,segs,q)));

Sent with Proton Mail secure email.

On Wednesday, January 24th, 2024 at 9:50 PM, Father Horton via Discuss discuss@lists.openscad.org wrote:

Actually you can declare local variables. It's just not obvious how.

From the manual:

function

get_square_triangle_perimeter

(

p1

,

p2

)

=

let

(

hypotenuse

=

sqrt

(

p1

p1

p2

p2

))

p1

p2

hypotenuse

;

On Wed, Jan 24, 2024 at 9:47 PM neri-engineering via Discuss discuss@lists.openscad.org wrote:

It's because in functions you can't declare local variables. So many times you end up writing helper functions which take the semi-compiled form of equations/data. This is one of the reasons why recursive functions in OpenSCAD are difficult to write. It certainly takes some getting used to. That's why I call it "sorcery". It's good mental gymnastics to keep you sharp, to prevent the ole Alzheimer's from setting in. We keep our bodies sharp by working out and we keep our minds sharp by writing recursive functions in OpenSCAD. Some examples I can give you which demonstrate my point. With a standard iterative process we would accomplish the following with simpler code.

// There are 21 steps currently.
animation_durations=[1, // # 1 slipper_back_plate()
1, // # 2 slipper_bearing()
2, // # 3 top_shaft()
1, // # 4 slipper_back_plate_pin()
2, // # 5 spur_gear() & left_slipper_pad()
1, // # 7 slipper_front_plate()
1, // # 8 slipper_spring()
3, // # 9 slipper_nut()
1, // #10 slipper_to_drive_gear_spacer()
1, // #11 drive_gear()
1, // #12 top_shaft_left_spacer() &
// left_top_shaft_bearing()
1, // #13 top_shaft_right_spacer() &
// right_top_shaft_bearing()
2, // #14 top_shaft_end_screw()
2]; // # ending()

// Returns a 1-based part number. Does not start from zero. Identifies the
// part being "introduced" in its introductory animation.
function get_part_number(tick,index)=
(tick<0)?index:
(get_part_number(tick-animation_durations[index],
index+1));

function total_animation_steps(index,step_count)=
(index>=len(animation_durations))?
step_count:
total_animation_steps(index+1,
step_count+animation_durations[index]);

// Parameter 'partnum' is one-based. Returns the number of animation steps
// that have preceded the beginning of part intro animation for specified part.
function total_animation_steps_up_to(partnum,index,step_count)=
(index>=(partnum-1))?
step_count:
total_animation_steps_up_to(partnum,index+1,
step_count+animation_durations[index]);

// The input parameter is 1-based and represents the part #.
function part_animation_steps(partnum)=
animation_durations[partnum-1];

// Value 't' is a value in [0,1), it increases linearly with time to span the
// entirety of animation.
t=0.34; // For example, we're a bit more than 1/3 of the way through the anim.

// Parameter 'i' is the animation ticker, zero-based.
i=floor(t*total_animation_steps(0,0)); // Start from 0.
p=get_part_number(i,0);

// Parameter 'w' is like 't', meaning it is in the range 0 <= w < 1, but it
// is specific to the part intro animation. The part intro animation begins
// at w=0 and is already over at w=1.
pre_w=(t*total_animation_steps(0,0)
-total_animation_steps_up_to(p,0,0))/part_animation_steps(p);

// First it will print out a one-based index describing the part we're on.
echo(p);

// Next it will print out which fraction of this part's scene we've done.echo(pre_w);

Sent with Proton Mail secure email.

On Wednesday, January 24th, 2024 at 7:21 PM, Adrian Mariano via Discuss discuss@lists.openscad.org wrote:

I don't understand why it's any trickier to assemble the order of points with recursive programming. In either case, if you have a growing list (the result) you compute new values and add them to the end of the list. Normally I write a recursive function something like

function func(result,info) =
done ? result
: func(concat(result, more_results_based_on_info),
new_info));

The result grows in an obvious way and there is no "trickery" or "sorcery" involved. It's as straight forward as any other kind of coding, though it can get annoying if "info" contains many things, and I can't say anything good about the speed of execution.

On Wed, Jan 24, 2024 at 3:30 PM neri-engineering via Discuss discuss@lists.openscad.org wrote:

With recursive functions it's a bit tricky to figure out the order of points after they're all assembled. The problem I had was that the recursive function which called concat() on two lists did it in an order that resulted in the final list having its points in a reverse order from what I expected. There is always "trickery" and a fair bit of "sorcery" involved in getting recursive functions to do the right thing. Anyhow this reverse order (from what I was assuming) is what caused the clockwise/counterclockwise polygon traversal situation.

Sent with Proton Mail secure email.

On Wednesday, January 24th, 2024 at 2:06 PM, David Phillip Oster via Discuss discuss@lists.openscad.org wrote:

Thank you for that neri-engineering, and nop head. That’s a fun example.

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

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

L
larry
Sun, Jan 28, 2024 6:11 AM

On Sun, 2024-01-28 at 04:10 +0000, neri-engineering via Discuss wrote:

Are you American?  Your ways involve "taking swipes at people"
without fully comprehending how something is used.  If you can
belittle someone else, even in the case where that person you are
belittling specifically chose the methodology for his approach with a
very good reason, then all the better for you.  In the same way the
American two year old temper tantrum baby is destroying the world
around itself, internationally, by taking swipes at people
everywhere, because it is going through its "terrible twos", but in
this case it's more like two centuries of the Roman fucking Empire
version 2.0, the original of which had Jesus of Nazareth put to
death.  These religious retards, who pretend to praise this man but
are secretly worshiping the killers of this man, are especially to
blame for this problem.

Yet another reason I'm moving away from OpenSCAD.  It's because many
of the participants on this list are mental fucking retards.

Now I could go into how similar the Roman Catholic Church is to the
GPL license, both in its monopolistic, forceful, and contaminating
strategy and by whom it was invented, but I will save my fingers
and breath and focus instead on doing good work.

All of that was uncalled-for. You were not being belittled in any
response. I am not an American, nor am I religious, but I find the
content and the attitude of your post to be offensive and small-minded.

Don't bother replying, as I won't see it. You are going directly into
my killfile.

Sent with Proton Mail secure email.

On Saturday, January 27th, 2024 at 6:55 PM, Father Horton via

How crazy do you want to get? If you call parameters by name, you
can have it initialize the value of i for you with a default.

On Sat, Jan 27, 2024 at 6:11 PM neri-engineering
neri-engineering@protonmail.com wrote:

Indeed the 'let' construct is a life-saver to make code much
clearer whereas it would have taken additional recursive helper
functions to achieve the same level of clarity. This is an
example that is working for me now.

echo(__invol_gear_path_builder(0,3,false));

// Parameter 'i' should be initialized to zero. Some examples:
// segs=3,q=true: [0,2,4,6,8,9,7,5,3,1]
// segs=3,q=false: [0, 4,6,8,9,7,5, 1]
function __invol_gear_path_builder(i,segs,q)=
((i==-1)?[]:
let(even=((i%2)==0),
flip=(even&&(i==((segs+1)*2))),
incr=(flip?1:(even?2:-2)),
omit=((!q)&&((i==2)||(i==3))))
concat(omit?[]:[i],
__invol_gear_path_builder(i+incr,segs,q)));

Sent with Proton Mail secure email.

On Wednesday, January 24th, 2024 at 9:50 PM, Father Horton via

Actually you can declare local variables. It's just not obvious
how.

From the manual:

function get_square_triangle_perimeter(p1, p2) =
let (hypotenuse = sqrt(p1p1+p2p2))
p1 + p2 + hypotenuse;

On Wed, Jan 24, 2024 at 9:47 PM neri-engineering via Discuss

It's because in functions you can't declare local variables.
So many times you end up writing helper functions which take
the semi-compiled form of equations/data. This is one of the
reasons why recursive functions in OpenSCAD are difficult to
write. It certainly takes some getting used to. That's why I
call it "sorcery". It's good mental gymnastics to keep you
sharp, to prevent the ole Alzheimer's from setting in. We
keep our bodies sharp by working out and we keep our minds
sharp by writing recursive functions in OpenSCAD. Some
examples I can give you which demonstrate my point. With a
standard iterative process we would accomplish the following
with simpler code.

// There are 21 steps currently.
animation_durations=[1, // # 1 slipper_back_plate()
1, // # 2 slipper_bearing()
2, // # 3 top_shaft()
1, // # 4 slipper_back_plate_pin()
2, // # 5 spur_gear() & left_slipper_pad()
1, // # 7 slipper_front_plate()
1, // # 8 slipper_spring()
3, // # 9 slipper_nut()
1, // #10 slipper_to_drive_gear_spacer()
1, // #11 drive_gear()
1, // #12 top_shaft_left_spacer() &
// left_top_shaft_bearing()
1, // #13 top_shaft_right_spacer() &
// right_top_shaft_bearing()
2, // #14 top_shaft_end_screw()
2]; // # ending()

// Returns a 1-based part number. Does not start from zero.
Identifies the
// part being "introduced" in its introductory animation.
function get_part_number(tick,index)=
(tick<0)?index:
(get_part_number(tick-animation_durations[index],
index+1));

function total_animation_steps(index,step_count)=
(index>=len(animation_durations))?
step_count:
total_animation_steps(index+1,
step_count+animation_durations[index]);

// Parameter 'partnum' is one-based. Returns the number of
animation steps
// that have preceded the beginning of part intro animation
for specified part.
function
total_animation_steps_up_to(partnum,index,step_count)=
(index>=(partnum-1))?
step_count:
total_animation_steps_up_to(partnum,index+1,
step_count+animation_durations[index]);

// The input parameter is 1-based and represents the part #.
function part_animation_steps(partnum)=
animation_durations[partnum-1];

// Value 't' is a value in [0,1), it increases linearly with
time to span the
// entirety of animation.
t=0.34; // For example, we're a bit more than 1/3 of the way
through the anim.

// Parameter 'i' is the animation ticker, zero-based.
i=floor(t*total_animation_steps(0,0)); // Start from 0.
p=get_part_number(i,0);

// Parameter 'w' is like 't', meaning it is in the range 0 <=
w < 1, but it
// is specific to the part intro animation. The part intro
animation begins
// at w=0 and is already over at w=1.
pre_w=(t*total_animation_steps(0,0)
-
total_animation_steps_up_to(p,0,0))/part_animation_steps(p);

// First it will print out a one-based index describing the
part we're on.
echo(p);

// Next it will print out which fraction of this part's scene
we've done.
echo(pre_w);

Sent with Proton Mail secure email.

On Wednesday, January 24th, 2024 at 7:21 PM, Adrian Mariano

I don't understand why it's any trickier to assemble the
order of points with recursive programming. In either case,
if you have a growing list (the result) you compute new
values and add them to the end of the list. Normally I
write a recursive function something like

function func(result,info) =
done ? result
: func(concat(result, more_results_based_on_info),
new_info));

The result grows in an obvious way and there is no
"trickery" or "sorcery" involved. It's as straight forward
as any other kind of coding, though it can get annoying if
"info" contains many things, and I can't say anything good

On Wed, Jan 24, 2024 at 3:30 PM neri-engineering via

With recursive functions it's a bit tricky to figure out
the order of points after they're all assembled. The
problem I had was that the recursive function which
called concat() on two lists did it in an order that
resulted in the final list having its points in a reverse
order from what I expected. There is always "trickery"
and a fair bit of "sorcery" involved in getting recursive
functions to do the right thing. Anyhow this reverse
order (from what I was assuming) is what caused the
clockwise/counterclockwise polygon traversal situation.

Sent with Proton Mail secure email.

On Wednesday, January 24th, 2024 at 2:06 PM, David
wrote:

Thank you for that neri-engineering, and nop head.
That’s a fun example.

To unsubscribe send an email to

To unsubscribe send an email to

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

J
jon
Sun, Jan 28, 2024 11:34 AM

I believe that you misunderstood what Father Horton was trying to say.
The "crazy" was intended as "complex" or "challenging" or "intricate".
Like "how complex do you want to get".  No one was attacking you.

On 1/27/2024 11:10 PM, neri-engineering via Discuss wrote:

Are you American?  Your ways involve "taking swipes at people" without
fully comprehending how something is used.  If you can belittle
someone else, even in the case where that person you are belittling
specifically chose the methodology for his approach with a very good
reason, then all the better for you. In the same way the American two
year old temper tantrum baby is destroying the world around itself,
internationally, by taking swipes at people everywhere, because it is
going through its "terrible twos", but in this case it's more like two
centuries of the Roman fucking Empire version 2.0, the original of
which had Jesus of Nazareth put to death.  These religious retards,
who pretend to praise this man but are secretly worshiping the killers
of this man, are especially to blame for this problem.

Yet another reason I'm moving away from OpenSCAD.  It's because many
of the participants on this list are mental fucking retards.

Now I could go into how similar the Roman Catholic Church is to the
GPL license, both in its monopolistic, forceful, and contaminating
strategy and by whom it was invented, but I will save my fingers and
breath and focus instead on doing good work.

Sent with Proton Mail https://proton.me/ secure email.

On Saturday, January 27th, 2024 at 6:55 PM, Father Horton via Discuss

How crazy do you want to get? If you call parameters by name, you can
have it initialize the value of i for you with a default.

On Sat, Jan 27, 2024 at 6:11 PM neri-engineering
neri-engineering@protonmail.com wrote:

`````` Indeed the 'let' construct is a life-saver to make code much
clearer whereas it would have taken additional recursive helper
functions to achieve the same level of clarity. This is an
example that is working for me now.

echo(__invol_gear_path_builder(0,3,false));

// Parameter 'i' should be initialized to zero. Some examples:
// segs=3,q=true: [0,2,4,6,8,9,7,5,3,1]
// segs=3,q=false: [0, 4,6,8,9,7,5, 1]
function __invol_gear_path_builder(i,segs,q)=
((i==-1)?[]:
let(even=((i%2)==0),
flip=(even&&(i==((segs+1)*2))),
incr=(flip?1:(even?2:-2)),
omit=((!q)&&((i==2)||(i==3))))
concat(omit?[]:[i],
__invol_gear_path_builder(i+incr,segs,q)));

Sent with Proton Mail <https://proton.me/> secure email.

On Wednesday, January 24th, 2024 at 9:50 PM, Father Horton via
``````
`````` Actually you can declare local variables. It's just not obvious how.

From the manual:

functionget_square_triangle_perimeter(p1,p2)=
let(hypotenuse=sqrt(p1*p1+p2*p2))
p1+p2+hypotenuse;

On Wed, Jan 24, 2024 at 9:47 PM neri-engineering via Discuss

It's because in functions you can't declare local variables.
So many times you end up writing helper functions which take
the semi-compiled form of equations/data. This is one of the
reasons why recursive functions in OpenSCAD are difficult to
write. It certainly takes some getting used to. That's why I
call it "sorcery". It's good mental gymnastics to keep you
sharp, to prevent the ole Alzheimer's from setting in. We
keep our bodies sharp by working out and we keep our minds
sharp by writing recursive functions in OpenSCAD. Some
examples I can give you which demonstrate my point. With a
standard iterative process we would accomplish the following
with simpler code.

// There are 21 steps currently.
animation_durations=[1, // # 1 slipper_back_plate()
1, // # 2 slipper_bearing()
2, // # 3 top_shaft()
1, // # 4 slipper_back_plate_pin()
2, // # 5 spur_gear() & left_slipper_pad()
1, // # 7 slipper_front_plate()
1, // # 8 slipper_spring()
3, // # 9 slipper_nut()
1, // #10 slipper_to_drive_gear_spacer()
1, // #11 drive_gear()
1, // #12 top_shaft_left_spacer() &
// left_top_shaft_bearing()
1, // #13 top_shaft_right_spacer() &
// right_top_shaft_bearing()
2, // #14 top_shaft_end_screw()
2]; // # ending()

// Returns a 1-based part number. Does not start from zero.
Identifies the
// part being "introduced" in its introductory animation.
function get_part_number(tick,index)=
(tick<0)?index:
(get_part_number(tick-animation_durations[index],
index+1));

function total_animation_steps(index,step_count)=
(index>=len(animation_durations))?
step_count:
total_animation_steps(index+1,
step_count+animation_durations[index]);

// Parameter 'partnum' is one-based. Returns the number of
animation steps
// that have preceded the beginning of part intro animation
for specified part.
function total_animation_steps_up_to(partnum,index,step_count)=
(index>=(partnum-1))?
step_count:
total_animation_steps_up_to(partnum,index+1,
step_count+animation_durations[index]);

// The input parameter is 1-based and represents the part #.
function part_animation_steps(partnum)=
animation_durations[partnum-1];

// Value 't' is a value in [0,1), it increases linearly with
time to span the
// entirety of animation.
t=0.34; // For example, we're a bit more than 1/3 of the way
through the anim.

// Parameter 'i' is the animation ticker, zero-based.
i=floor(t*total_animation_steps(0,0)); // Start from 0.
p=get_part_number(i,0);

// Parameter 'w' is like 't', meaning it is in the range 0
<= w < 1, but it
// is specific to the part intro animation. The part intro
animation begins
// at w=0 and is already over at w=1.
pre_w=(t*total_animation_steps(0,0)
-total_animation_steps_up_to(p,0,0))/part_animation_steps(p);

// First it will print out a one-based index describing the
part we're on.
echo(p);

// Next it will print out which fraction of this part's
scene we've done.
echo(pre_w);

Sent with Proton Mail <https://proton.me/> secure email.

On Wednesday, January 24th, 2024 at 7:21 PM, Adrian Mariano
``````
``````     I don't understand why it's any trickier to assemble the
order of points with recursive programming. In either case,
if you have a growing list (the result) you compute new
values and add them to the end of the list. Normally I
write a recursive function something like

function func(result,info) =
done ? result
: func(concat(result, more_results_based_on_info),
new_info));

The result grows in an obvious way and there is no
"trickery" or "sorcery" involved. It's as straight forward
as any other kind of coding, though it can get annoying if
"info" contains many things, and I can't say anything good

On Wed, Jan 24, 2024 at 3:30 PM neri-engineering via

With recursive functions it's a bit tricky to figure
out the order of points after they're all assembled.
The problem I had was that the recursive function which
called concat() on two lists did it in an order that
resulted in the final list having its points in a
reverse order from what I expected. There is always
"trickery" and a fair bit of "sorcery" involved in
getting recursive functions to do the right thing.
Anyhow this reverse order (from what I was assuming) is
what caused the clockwise/counterclockwise polygon
traversal situation.

Sent with Proton Mail <https://proton.me/> secure email.

On Wednesday, January 24th, 2024 at 2:06 PM, David
wrote:
``````
``````         Thank you for that neri-engineering, and nop head.
That’s a fun example.
``````
``````         _______________________________________________
To unsubscribe send an email to
``````
``````     _______________________________________________
To unsubscribe send an email to discuss-leave@lists.openscad.org
``````

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

--
This email has been checked for viruses by AVG antivirus software.
www.avg.com

FH
Father Horton
Sun, Jan 28, 2024 12:05 PM

This is correct.

On Sun, Jan 28, 2024 at 5:34 AM jon jon@jonbondy.com wrote:

I believe that you misunderstood what Father Horton was trying to say.
The "crazy" was intended as "complex" or "challenging" or "intricate".
Like "how complex do you want to get".  No one was attacking you.
On 1/27/2024 11:10 PM, neri-engineering via Discuss wrote:

Are you American?  Your ways involve "taking swipes at people" without
fully comprehending how something is used.  If you can belittle someone
else, even in the case where that person you are belittling specifically
chose the methodology for his approach with a very good reason, then all
the better for you.  In the same way the American two year old temper
tantrum baby is destroying the world around itself, internationally, by
taking swipes at people everywhere, because it is going through its
"terrible twos", but in this case it's more like two centuries of the Roman
fucking Empire version 2.0, the original of which had Jesus of Nazareth put
to death.  These religious retards, who pretend to praise this man but are
secretly worshiping the killers of this man, are especially to blame for
this problem.

Yet another reason I'm moving away from OpenSCAD.  It's because many of
the participants on this list are mental fucking retards.

Now I could go into how similar the Roman Catholic Church is to the GPL
license, both in its monopolistic, forceful, and contaminating strategy
and by whom it was invented, but I will save my fingers and breath and
focus instead on doing good work.

Sent with Proton Mail https://proton.me/ secure email.

On Saturday, January 27th, 2024 at 6:55 PM, Father Horton via Discuss

How crazy do you want to get? If you call parameters by name, you can have
it initialize the value of i for you with a default.

On Sat, Jan 27, 2024 at 6:11 PM neri-engineering <
neri-engineering@protonmail.com> wrote:

Indeed the 'let' construct is a life-saver to make code much clearer
whereas it would have taken additional recursive helper functions to
achieve the same level of clarity. This is an example that is working for
me now.

echo(__invol_gear_path_builder(0,3,false));

// Parameter 'i' should be initialized to zero. Some examples:
// segs=3,q=true: [0,2,4,6,8,9,7,5,3,1]
// segs=3,q=false: [0, 4,6,8,9,7,5, 1]
function __invol_gear_path_builder(i,segs,q)=
((i==-1)?[]:
let(even=((i%2)==0),
flip=(even&&(i==((segs+1)*2))),
incr=(flip?1:(even?2:-2)),
omit=((!q)&&((i==2)||(i==3))))
concat(omit?[]:[i],
__invol_gear_path_builder(i+incr,segs,q)));

Sent with Proton Mail https://proton.me/ secure email.

On Wednesday, January 24th, 2024 at 9:50 PM, Father Horton via Discuss <

Actually you can declare local variables. It's just not obvious how.

From the manual:

function get_square_triangle_perimeter(p1, p2) =  let (hypotenuse = sqrt(p1p1+p2p2))    p1 + p2 + hypotenuse;

On Wed, Jan 24, 2024 at 9:47 PM neri-engineering via Discuss <

It's because in functions you can't declare local variables. So many
times you end up writing helper functions which take the semi-compiled form
of equations/data. This is one of the reasons why recursive functions in
OpenSCAD are difficult to write. It certainly takes some getting used to.
That's why I call it "sorcery". It's good mental gymnastics to keep you
sharp, to prevent the ole Alzheimer's from setting in. We keep our bodies
sharp by working out and we keep our minds sharp by writing recursive
functions in OpenSCAD. Some examples I can give you which demonstrate my
point. With a standard iterative process we would accomplish the following
with simpler code.

// There are 21 steps currently.
animation_durations=[1, // # 1 slipper_back_plate()
1, // # 2 slipper_bearing()
2, // # 3 top_shaft()
1, // # 4 slipper_back_plate_pin()
2, // # 5 spur_gear() & left_slipper_pad()
1, // # 7 slipper_front_plate()
1, // # 8 slipper_spring()
3, // # 9 slipper_nut()
1, // #10 slipper_to_drive_gear_spacer()
1, // #11 drive_gear()
1, // #12 top_shaft_left_spacer() &
// left_top_shaft_bearing()
1, // #13 top_shaft_right_spacer() &
// right_top_shaft_bearing()
2, // #14 top_shaft_end_screw()
2]; // # ending()

// Returns a 1-based part number. Does not start from zero. Identifies
the
// part being "introduced" in its introductory animation.
function get_part_number(tick,index)=
(tick<0)?index:
(get_part_number(tick-animation_durations[index],
index+1));

function total_animation_steps(index,step_count)=
(index>=len(animation_durations))?
step_count:
total_animation_steps(index+1,
step_count+animation_durations[index]);

// Parameter 'partnum' is one-based. Returns the number of animation
steps
// that have preceded the beginning of part intro animation for
specified part.
function total_animation_steps_up_to(partnum,index,step_count)=
(index>=(partnum-1))?
step_count:
total_animation_steps_up_to(partnum,index+1,
step_count+animation_durations[index]);

// The input parameter is 1-based and represents the part #.
function part_animation_steps(partnum)=
animation_durations[partnum-1];

// Value 't' is a value in [0,1), it increases linearly with time to
span the
// entirety of animation.
t=0.34; // For example, we're a bit more than 1/3 of the way through the
anim.

// Parameter 'i' is the animation ticker, zero-based.
i=floor(t*total_animation_steps(0,0)); // Start from 0.
p=get_part_number(i,0);

// Parameter 'w' is like 't', meaning it is in the range 0 <= w < 1, but
it
// is specific to the part intro animation. The part intro animation
begins
// at w=0 and is already over at w=1.
pre_w=(t*total_animation_steps(0,0)
-total_animation_steps_up_to(p,0,0))/part_animation_steps(p);

// First it will print out a one-based index describing the part we're
on.
echo(p);

// Next it will print out which fraction of this part's scene we've done.
echo(pre_w);

Sent with Proton Mail https://proton.me/ secure email.

On Wednesday, January 24th, 2024 at 7:21 PM, Adrian Mariano via Discuss <

I don't understand why it's any trickier to assemble the order of points
with recursive programming. In either case, if you have a growing list (the
result) you compute new values and add them to the end of the list.
Normally I write a recursive function something like

function func(result,info) =
done ? result
: func(concat(result, more_results_based_on_info),
new_info));

The result grows in an obvious way and there is no "trickery" or
"sorcery" involved. It's as straight forward as any other kind of coding,
though it can get annoying if "info" contains many things, and I can't say
anything good about the speed of execution.

On Wed, Jan 24, 2024 at 3:30 PM neri-engineering via Discuss <

With recursive functions it's a bit tricky to figure out the order of
points after they're all assembled. The problem I had was that the
recursive function which called concat() on two lists did it in an order
that resulted in the final list having its points in a reverse order from
what I expected. There is always "trickery" and a fair bit of "sorcery"
involved in getting recursive functions to do the right thing. Anyhow this
reverse order (from what I was assuming) is what caused the
clockwise/counterclockwise polygon traversal situation.

Sent with Proton Mail https://proton.me/ secure email.

On Wednesday, January 24th, 2024 at 2:06 PM, David Phillip Oster via

Thank you for that neri-engineering, and nop head. That’s a fun example.

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