Beginner needs help

classic Classic list List threaded Threaded
17 messages Options
Reply | Threaded
Open this post in threaded view
|

Beginner needs help

stressless
Hi,
I tried hard to put these fillets in place to no avail (see picture).
I am using the "weld" module from osj1961.
Could anyone point me were I screwed up ?
This item will be finally rendered with $fn=60 or 80.
-- - - - - - - - -  
$fn=20;
//rotate([25,35,15]) {
//rotate([90,0,0])cube([50,50,35], center=true); // relay simulation
difference(){
    union() {
        weld(1) {
            translate([0,0,28.3]) cylinder(h= 4, d= 95, center=true); // top rim
        }

        weld(1) {
            cylinder(h=60, r1=42.5,r2=42.5, center=true); // outer shell
       
            weld(3) {
                translate([0,0,-46]) cylinder(h=20, r=10); // bottom extension
            }
        } // weld
   
        rotate([90,0,0]) translate([0,-40,3]) cylinder(h=10,d=6, center=false); // cylinder for screw
    } // union
   
    union() {
        translate([0,0,13])
        //weld(2) {
            cylinder(h=80, r1=40, r2=40, center=true); // inner cavity
        //}
        translate([0,0,-80]) cylinder(h=180, r=3); // thru hole
                rotate([90,0,0]) translate([0,-40,1]) cylinder(h=24,d=2, center=false); // pre-hole for screw

    } //union  
} //difference


//} //rotate

module weld(t=1) {
    union() {
        children(0);
        children(1);
        hull(){
            union(){
                intersection() {
                    minkowski(){
                        intersection(){
                            children(0);
                            children(1);
                        }
                        sphere(r=t);
                    }
                    children(0);
                }
                intersection() {
                    minkowski(){
                        intersection() {
                            children(0);
                            children(1);                  
                        }
                        sphere(r=t);
                    }
                    children(1);
                }
            }
        }
    }
}
- - - - - - - - - - - - -

Thanks in advance for any help.
.
Dan
Reply | Threaded
Open this post in threaded view
|

Re: Beginner needs help

Parkinbot
Your design is almost radial symmetric. I would start it in 2D, do the fillets with offset() and then use rotate_extrude() for extrusion.
Reply | Threaded
Open this post in threaded view
|

Re: Beginner needs help

jdawgaz
re: 2D and doing rotate_extrude()

using this is really helpful: http://daid.eu/~daid/3d/



--
Extra Ham Operator: K7AZJ
Registered Linux User: 275424
Raspberry Pi and Openscad developer

The most exciting phrase to hear in science - the one that heralds new discoveries - is not "Eureka!" but "That's funny...".
- Isaac. Asimov


On Wed, Jan 18, 2017 at 11:19 AM, Parkinbot <[hidden email]> wrote:
Your design is almost radial symmetric. I would start it in 2D, do the
fillets with offset()
<http://forum.openscad.org/how-to-make-round-chamfer-at-2D-object-td19714.html>
and then use rotate_extrude() for extrusion.



--
View this message in context: http://forum.openscad.org/Beginner-needs-help-tp20159p20160.html
Sent from the OpenSCAD mailing list archive at Nabble.com.

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org


_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: Beginner needs help

droftarts
When I copy and paste your code into a new OpenSCAD document, and hit F5, I get 5 "WARNING: Children index (1) out of bounds (1 children)" messages.

The weld function produces a fillet between two parts, so needs two inputs; you're giving it just one in some cases.

You seem to be using the 'weld' function for two tasks; to add a fillet between two objects, and to add a radius to individual objects. The error messages are from where you are doing the latter, which I think is using the 'weld' function incorrectly. It's also causing that part to be bigger than you expect, as it's basically doing a minkowski operation to the part. I imagine the 'weld' function wasn't originally intended to produce radii! You need a different function to do this, and to keep the parts the correct size, minus the radiused edge. Then you can use the weld function correctly, in the form:

weld (2) {
     (top part with radius edge);
     weld (2) {
         (middle part with radius edge);
         (bottom part with radius edge);
     }
}

This will produce the correct shape. Or, alternatively, as others have suggested, draw it in 2D. nophead helped me produce a really nice function that would allow you to produce a 2D drawing with the correct fillets and radii, rather than using lots of circles/squares/union/difference; see this thread: http://forum.openscad.org/Script-to-replicate-hull-and-minkoswki-for-CSG-export-import-into-FreeCAD-td16537.html

Ian
Reply | Threaded
Open this post in threaded view
|

Re: Beginner needs help

stressless
In reply to this post by Parkinbot
Parkinbot wrote
Your design is almost radial symmetric. I would start it in 2D, do the fillets with offset() and then use rotate_extrude() for extrusion.
Thanks Parkinbot. Extruding 2D is the way to go !
I looked at the link you provide but could not figure out how to integrate the offset() into my polygon to make radii/chamfers. I then ended up making chamfers by adding points.
However, I'd love to master the offset(). Could you please give me a couple of examples for a positive and negative radii/chamfer using my code ? Here it is :
// * * * * * * * * * * * * *
// File: .../openscad/learn/cache_3_rotate_extrude_2.scad
$fn=20;
/*
// radial tapping stud with prehole
difference() {
    rotate([90,0,0]) translate([0,10,2.8])
    cylinder(h=7.5,d=6, center=false);
   
        rotate([90,0,0]) translate([0, 10, 0])
    cylinder(h=12 ,d=2, center=false);
}
*/

//rotate_extrude(angle=360, convexity=10)
polygon(
    points= [
                [40,80],   //  0
                [47.5,80], //  1
                [47.5,76], //  2
                [44.5,76], //  3
                [42.5,74], //  4
                [42.5,22], //  5
                [40.5,20], //  6
                [12.5,20], //  7
                [10,18],   //  8
                [10,2],    //  9
                [8,0],     // 10
                [3,0],     // 11
                [3,24],    // 12
                [36,24],   // 13
                [40,28],   // 14
                [40,40],   // 15
            ],
    paths=[[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]],
    convexity=10
);

// * * * * * * * * * * *

Thanks much for your time.
Dan
Reply | Threaded
Open this post in threaded view
|

Re: Beginner needs help

stressless
In reply to this post by jdawgaz
jdawgaz wrote
re: 2D and doing rotate_extrude()
using this is really helpful: http://daid.eu/~daid/3d
--
Extra Ham Operator: K7AZJ
Registered Linux User: 275424
Raspberry Pi and Openscad developer
Thanks jdawgaz,

It looks like an useful tool. I pasted my polygon code into it but nothing happened.
I little user's guidance would help.

Dan
Reply | Threaded
Open this post in threaded view
|

Re: Beginner needs help

stressless
In reply to this post by droftarts
droftarts wrote
When I copy and paste your code into a new OpenSCAD document, and hit F5, I get 5 "WARNING: Children index (1) out of bounds (1 children)" messages.

The weld function produces a fillet between two parts, so needs two inputs; you're giving it just one in some cases.

You seem to be using the 'weld' function for two tasks; to add a fillet between two objects, and to add a radius to individual objects. The error messages are from where you are doing the latter, which I think is using the 'weld' function incorrectly. It's also causing that part to be bigger than you expect, as it's basically doing a minkowski operation to the part. I imagine the 'weld' function wasn't originally intended to produce radii! You need a different function to do this, and to keep the parts the correct size, minus the radiused edge. Then you can use the weld function correctly, in the form:

weld (2) {
     (top part with radius edge);
     weld (2) {
         (middle part with radius edge);
         (bottom part with radius edge);
     }
}

This will produce the correct shape. Or, alternatively, as others have suggested, draw it in 2D. nophead helped me produce a really nice function that would allow you to produce a 2D drawing with the correct fillets and radii, rather than using lots of circles/squares/union/difference; see this thread: http://forum.openscad.org/Script-to-replicate-hull-and-minkoswki-for-CSG-export-import-into-FreeCAD-td16537.html

Ian
Thanks droftarts,
You're right about the weld function. I clearly misuse it.
As for the link you provided, I must humbly admit it is a bit above my head at this stage of my learning...

Dan
Reply | Threaded
Open this post in threaded view
|

Re: Beginner needs help

droftarts
stressless wrote
Thanks droftarts,
You're right about the weld function. I clearly misuse it.
As for the link you provided, I must humbly admit it is a bit above my head at this stage of my learning...

Dan
No problem, we all started somewhere! To get your "radial tapping stud with prehole" correct, you just need to reorder things a little; eg do it in this order:

$fn=100;
// radial tapping stud with prehole
difference() {
    union () {
        rotate_extrude(angle=360, convexity=10) polygon([
            [40,80],   //  0
            [47.5,80], //  1
            [47.5,76], //  2
            [44.5,76], //  3
            [42.5,74], //  4
            [42.5,22], //  5
            [40.5,20], //  6
            [12.5,20], //  7
            [10,18],   //  8
            [10,2],    //  9
            [8,0],     // 10
            [3,0],     // 11
            [3,24],    // 12
            [36,24],   // 13
            [40,28],   // 14
            [40,40]]);   // 15
        rotate([90,0,0]) translate([0,10,2.8]) cylinder(h=7.5,d=6, center=false);
    }
    rotate([90,0,0]) translate([0, 10, 0]) cylinder(h=12 ,d=2, center=false);
}

The function I alluded to simply replaces your fillets with circles. You can ignore the module and the function; they just do the maths! Each point has a circle (the third value in the point list), which can be 0 (for no radius or fillet), positive (for a radius), or negative (for a fillet). The main difficulty is that you need to offset the point by the radius of the circle. Here's your shape using the function:

$fn = 100;

shape1 = [
        [40,80,0],   //  0
        [47.5,80,0], //  1
        [47.5,76,0], //  2
        [44.5,74,-2], //  3
        [40.5,22,2], //  4
        [12,18,-2], //  5
        [8,2,2],     // 6
        [3,0,0],     // 7
        [3,24,0],    // 8
        [36,28,-4],   // 9
        [40,40,0]];   // 10

difference() {
    union () {
        rotate_extrude(angle=360, convexity=10) rounded_polygon(shape1);
        rotate([90,0,0]) translate([0,10,2.8]) cylinder(h=7.5,d=6, center=false);
    }
    rotate([90,0,0]) translate([0, 10, 0]) cylinder(h=12 ,d=2, center=false);
}

module rounded_polygon(points)
    difference() {
        len = len(points);
        union() {
            for(i = [0 : len - 1])
                if(points[i][2] > 0)
                    translate([points[i].x, points[i].y])
                        circle(points[i][2]);

            polygon([for(i  = [0 : len - 1])
                        let(ends = tangent(points[i], points[(i + 1) % len]))
                            for(end = [0, 1])
                                ends[end]]);
        }
        for(i = [0 : len - 1])
            if(points[i][2] < 0)
                translate([points[i].x, points[i].y])
                    circle(-points[i][2]);
     }

function tangent(p1, p2) =
    let(
        r1 = p1[2],
        r2 = p2[2],
        dx = p2.x - p1.x,
        dy = p2.y - p1.y,
        d = sqrt(dx * dx + dy * dy),
        theta = atan2(dy, dx) + acos((r1 - r2) / d),
        xa = p1.x +(cos(theta) * r1),
        ya = p1.y +(sin(theta) * r1),
        xb = p2.x +(cos(theta) * r2),
        yb = p2.y +(sin(theta) * r2)
    )[ [xa, ya], [xb, yb] ];

You can also use "offset (r=1) offset (r=-1) polygon([ ... " (see https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Transformations#offset ) however this will apply the same radius to all corners. It also can't be used if the walls are too thin, or they disappear.

Hope that helps.

Ian

Reply | Threaded
Open this post in threaded view
|

Re: Beginner needs help

stressless
<< Hope that helps. >>

- Sure does ! This is not just help but a whole tutorial. Thanks a bunch for that.

I am still chewing on the let() func. (and why a mod. ?) as in :

           polygon([for(i  = [0 : len - 1])
                        let(ends = tangent(points[i], points[(i + 1) % len]))
                            for(end = [0, 1])
                                ends[end]]);

Hoping to grasp it soon.

Thanks again for your time. All the best.

Dan
Reply | Threaded
Open this post in threaded view
|

Re: Beginner needs help

Ronaldo
2017-01-24 9:12 GMT-02:00 stressless <[hidden email]>:
I am still chewing on the let() func. (and why a mod. ?) as in :

           polygon([for(i  = [0 : len - 1])
                        let(ends = tangent(points[i], points[(i + 1) %
len]))
                            for(end = [0, 1])
                                ends[end]]);

Welcome to list comprehension stuff!


_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: Beginner needs help

droftarts
For the mod, I asked the same questions in the thread the function comes from, which nophead replied to: http://forum.openscad.org/Script-to-replicate-hull-and-minkoswki-for-CSG-export-import-into-FreeCAD-tp16537p16553.html
A little later on I did a small example to help me understand it! http://forum.openscad.org/Script-to-replicate-hull-and-minkoswki-for-CSG-export-import-into-FreeCAD-tp16537p16623.html

Ian
Reply | Threaded
Open this post in threaded view
|

Re: Beginner needs help

stressless
Thanks droftarts. Interesting!  

I didn't see this being documented anywhere. It would be worth putting it in the manual.

Dan

droftarts wrote
For the mod, I asked the same questions in the thread the function comes from, which nophead replied to: http://forum.openscad.org/Script-to-replicate-hull-and-minkoswki-for-CSG-export-import-into-FreeCAD-tp16537p16553.html
A little later on I did a small example to help me understand it! http://forum.openscad.org/Script-to-replicate-hull-and-minkoswki-for-CSG-export-import-into-FreeCAD-tp16537p16623.html

Ian
Reply | Threaded
Open this post in threaded view
|

Re: Beginner needs help

droftarts
It could probably be added to the page of tips and tricks here: https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Tips_and_Tricks

Ian
Reply | Threaded
Open this post in threaded view
|

Re: Beginner needs help

stressless
This post was updated on .
As I was perplexed about the use of MOD (%) in a loop using a list, I did a little testing and research of my own.
Apparently, the syntax (points[(i) % length]) divides the value of Point(i) by the array's length and returns the remainder (oh-la-la).

Here is the way I was recommended to go :
points = [17,1,2,3,4];
length = len (points);
for (i=[0:length-1]) {
    remainder = (points[(i) % length]);
    echo (points[(i) % length],points[(i+1) % length]);
    echo ("remainder : ", remainder);
}
and its console output :
ECHO: 17, 1
ECHO: "remainder : ", 17
ECHO: 1, 2
ECHO: "remainder : ", 1
ECHO: 2, 3
ECHO: "remainder : ", 2
ECHO: 3, 4
ECHO: "remainder : ", 3
ECHO: 4, 17
ECHO: "remainder : ", 4
In the one before last ECHO, we notice the 17 which is Pos 0 of the list.

When we take both '% length' away as so :
points = [17,1,2,3,4];
length = len (points);
for (i=[0:length-1]) {
    remainder = (points[(i) % length]);
    echo (points[(i)],points[(i+1)]);
    echo ("remainder : ", remainder);
}
The console output is as follows :
ECHO: 17, 1
ECHO: "remainder : ", 17
ECHO: 1, 2
ECHO: "remainder : ", 1
ECHO: 2, 3
ECHO: "remainder : ", 2
ECHO: 3, 4
ECHO: "remainder : ", 3
ECHO: 4, undef
ECHO: "remainder : ", 4
In this case, the one before last ECHO says 'undef'

Looking at the tips & Tricks page you mentioned, I noticed this post https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Tips_and_Tricks#Caring_about_undef 
which essentially says this : "Most illegal operations in OpenSCAD return undef. Some return nan. However the program keeps running and undef values may cause unpredictable future behaviour if no precaution is taken".

In short, not using MOD (%) in a loop using a list may cause problems. That's that !

However, the reason why the use of MOD resets the loop to the first item of the list remains a mystery to me. But at least I've learned something, thanks to all the contributors.

Cheers, Dan


Reply | Threaded
Open this post in threaded view
|

Re: Beginner needs help

Ronaldo
If your intention is to use mod (%) to go through a circular list of ´points, you should apply it to the point index and not to the point itself.
As an example, suppose you want to draw the edges of a polygon whose points are in a list pt.

// makes a set of "cylinders" representing the edges of a polygon
module draw_polygon(pt) {
     for(i=[0:len(pt)-1])   // for each point
          hull() { // makes a "cylinder" from point pt[i] to the next
              translate(pt[i]) sphere();
              translate(pt[i+1]) sphere();
         }
}
draw_polygon(pt=[ [0,0,0], [20,0,0], [0,20,0] ]);

This doesn't work as intended because when i==len(pt)-1 the next point would be pt[len(pt)] which does not exist. It should be pt[0].

You may correct this code including a test:

module draw_polygon(pt) {
     for(i=[0:len(pt)-1])   // for each point
          hull() { // makes a "cylinder" from point pt[i] to the next
              translate(pt[i]) sphere();
              if(i==len(pt)-1)
                 translate(pt[0]) sphere();
                 translate(pt[i+1]) sphere();
         }
}

which is cumbersome. Instead, use mod operator:

module draw_polygon(pt) {
     for(i=[0:len(pt)-1])   // for each point
          hull() { // makes a "cylinder" from point pt[i] to the next
              translate(pt[i]) sphere();
              translate(pt[(i+1)%len(pt)]) sphere();
         }
}

Now, when i==len(pt-1) then i+1==len(pt) and so (i+1)%len(pt)==0 as intended.


2017-01-25 16:24 GMT-02:00 stressless <[hidden email]>:
As I was perplexed about the use of MOD (%) in a loop using a list, I did a little testing and research of my own. Apparently, the syntax (points[(i) % length]) divides the value of Point(i) by the array's length and returns the remainder (oh-la-la). Here is the way I was recommended to go : points = [17,1,2,3,4]; length = len (points); for (i=[0:length-1]) { remainder = (points[(i) % length]); echo (points[(i) % length],points[(i+1) % length]); echo ("remainder : ", remainder); } and its console output : ECHO: 17, 1 ECHO: "remainder : ", 17 ECHO: 1, 2 ECHO: "remainder : ", 1 ECHO: 2, 3 ECHO: "remainder : ", 2 ECHO: 3, 4 ECHO: "remainder : ", 3 ECHO: 4, 17 ECHO: "remainder : ", 4 In the one before last ECHO, we notice the 17 which is Pos 0 of the list. When we take both '% length' away as so : points = [17,1,2,3,4]; length = len (points); for (i=[0:length-1]) { remainder = (points[(i) % length]); echo (points[(i)],points[(i+1)]); echo ("remainder : ", remainder); } The console output is as follows : ECHO: 17, 1 ECHO: "remainder : ", 17 ECHO: 1, 2 ECHO: "remainder : ", 1 ECHO: 2, 3 ECHO: "remainder : ", 2 ECHO: 3, 4 ECHO: "remainder : ", 3 ECHO: 4, undef ECHO: "remainder : ", 4 In this case, the one before last ECHO says 'undef' Looking at the tips & Tricks page you mentioned, I noticed this post https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Tips_and_Tricks#Caring_about_undef which essentially says this : "Most illegal operations in OpenSCAD return undef. Some return nan. However the program keeps running and undef values may cause unpredictable future behaviour if no precaution is taken". In short, not using MOD (%) in a loop using a list may cause problems. That's that ! However, the reason why the use of MOD resets the loop to the first item of the list remains a mystery to me. But at least I've learned something, thanks to all the contributors. Cheers, Dan

View this message in context: Re: Beginner needs help
Sent from the OpenSCAD mailing list archive at Nabble.com.

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org



_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: Beginner needs help

stressless
Ronaldo,

Thanks for this. The use of MOD in a circular list of points make sense to me now.
With your example, I also learned a creative way to use hull().
Great !

(and sorry for my messy original message. It went inadvertently in HTML format. Now corrected)

Dan

Ronaldo wrote
draw_polygon(pt=[ [0,0,0], [20,0,0], [0,20,0] ]);

module draw_polygon(pt) {
     for(i=[0:len(pt)-1])   // for each point
          hull() { // makes a "cylinder" from point pt[i] to the next
              translate(pt[i]) sphere();
              translate(pt[(i+1)%len(pt)]) sphere();
         }
}

// Now, when i==len(pt-1) then i+1==len(pt) and so (i+1)%len(pt)==0 as intended.
Reply | Threaded
Open this post in threaded view
|

Re: Beginner needs help

jdawgaz
stressless,

Sorry about the late post, I was camping this past week.

You can find the information about how to use the polygon builder tool, I talked about, in the "Fusion360 and OpenSCAD" thread. http://openscad.rocklinux.narkive.com/kayll2Vq/fusion360-and-openscad#post2

Jerry


--
Extra Ham Operator: K7AZJ
Registered Linux User: 275424
Raspberry Pi and Openscad developer

The most exciting phrase to hear in science - the one that heralds new discoveries - is not "Eureka!" but "That's funny...".
- Isaac. Asimov


On Thu, Jan 26, 2017 at 8:26 AM, stressless <[hidden email]> wrote:
Ronaldo,

Thanks for this. The use of MOD in a circular list of points make sense to
me now.
With your example, I also learned a creative way to use hull().
Great !

(and sorry for my messy original message. It went inadvertently in HTML
format. Now corrected)

Dan


Ronaldo wrote
> draw_polygon(pt=[ [0,0,0], [20,0,0], [0,20,0] ]);
>
> module draw_polygon(pt) {
>      for(i=[0:len(pt)-1])   // for each point
>           hull() { // makes a "cylinder" from point pt[i] to the next
>               translate(pt[i]) sphere();
>               translate(pt[(i+1)%len(pt)]) sphere();
>          }
> }
>
> // Now, when i==len(pt-1) then i+1==len(pt) and so (i+1)%len(pt)==0 as
> intended.





--
View this message in context: http://forum.openscad.org/Beginner-needs-help-tp20159p20242.html
Sent from the OpenSCAD mailing list archive at Nabble.com.

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org


_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org