Place holes on a circle

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

Place holes on a circle

OpenSCAD mailing list-2
Actually I need to place some holes at a circle:

<http://forum.openscad.org/file/t2943/place_holes_on_circle.png>

I did with:

```
diameter = 34.0;

difference () {
    cylinder(h=10, d=diameter + 10);
    cylinder(h=10, d=6);
    translate([0, diameter/2, 0]) {
        cylinder(h=10, d=6);
    }
    rotate (a=120) {
        translate([0, diameter/2, 0]) {
            cylinder(h=10, d=6);
        }  
    }
    rotate (a=-120) {
        translate([0, diameter/2, 0]) {
            cylinder(h=10, d=6);
        }  
    }
}
```

Which results in:

<http://forum.openscad.org/file/t2943/place_holes_on_circle_firsttry.png>

Is there a better way?



--
Sent from: http://forum.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: Place holes on a circle

Gadgetman!
I assume it's slow?

First, you need to translate the differenced cylinders so that they start below the cylinder you're punching holes in, and make them longer so that they poke out part the top. 
That should make it render faster


With a FOR loop you only have one set of commands, repated as many times you want around the rim. 
(Sorry, don't have time to check the correect syntax right now. I have a CAKE that needs to be eaten... )


And finally, to clean it up a bit, use indentation.

ROTATE ()
       TRANSLATE ()
                OBJECT();

Notice that there's no need to use the curly brackets because both ROTATE and TRANSLATE expect an object of some sort to follow. 


Trygve
      

Den 28. august 2020 kl. 14.23.47 +02.00 skrev AndyY via Discuss <[hidden email]>:
Actually I need to place some holes at a circle:


I did with:

```
diameter = 34.0;

difference () {
cylinder(h=10, d=diameter + 10);
cylinder(h=10, d=6);
translate([0, diameter/2, 0]) {
cylinder(h=10, d=6);
}
rotate (a=120) {
translate([0, diameter/2, 0]) {
cylinder(h=10, d=6);
}
}
rotate (a=-120) {
translate([0, diameter/2, 0]) {
cylinder(h=10, d=6);
}
}
}
```

Which results in:


Is there a better way?



--

_______________________________________________
OpenSCAD mailing list


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

Re: Place holes on a circle

nophead
It is faster to do in 2D and then extrude to 3D

diameter = 34.0;
linear_extrude(10)
    difference() {
        circle(d = diameter + 10);

        for(i = [-1 : 1])
           rotate(i * 120)
                translate([0, diameter / 2])
                    circle(d = 6);
    }

On Fri, 28 Aug 2020 at 14:02, <[hidden email]> wrote:
I assume it's slow?

First, you need to translate the differenced cylinders so that they start below the cylinder you're punching holes in, and make them longer so that they poke out part the top. 
That should make it render faster


With a FOR loop you only have one set of commands, repated as many times you want around the rim. 
(Sorry, don't have time to check the correect syntax right now. I have a CAKE that needs to be eaten... )


And finally, to clean it up a bit, use indentation.

ROTATE ()
       TRANSLATE ()
                OBJECT();

Notice that there's no need to use the curly brackets because both ROTATE and TRANSLATE expect an object of some sort to follow. 


Trygve
      

Den 28. august 2020 kl. 14.23.47 +02.00 skrev AndyY via Discuss <[hidden email]>:
Actually I need to place some holes at a circle:


I did with:

```
diameter = 34.0;

difference () {
cylinder(h=10, d=diameter + 10);
cylinder(h=10, d=6);
translate([0, diameter/2, 0]) {
cylinder(h=10, d=6);
}
rotate (a=120) {
translate([0, diameter/2, 0]) {
cylinder(h=10, d=6);
}
}
rotate (a=-120) {
translate([0, diameter/2, 0]) {
cylinder(h=10, d=6);
}
}
}
```

Which results in:


Is there a better way?



--

_______________________________________________
OpenSCAD mailing list

_______________________________________________
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: Place holes on a circle

OpenSCAD mailing list-2
Very slick.

On 2020-08-28 9:17 a.m., nop head wrote:
It is faster to do in 2D and then extrude to 3D

diameter = 34.0;
linear_extrude(10)
    difference() {
        circle(d = diameter + 10);

        for(i = [-1 : 1])
           rotate(i * 120)
                translate([0, diameter / 2])
                    circle(d = 6);
    }

On Fri, 28 Aug 2020 at 14:02, <[hidden email]> wrote:
I assume it's slow?

First, you need to translate the differenced cylinders so that they start below the cylinder you're punching holes in, and make them longer so that they poke out part the top. 
That should make it render faster


With a FOR loop you only have one set of commands, repated as many times you want around the rim. 
(Sorry, don't have time to check the correect syntax right now. I have a CAKE that needs to be eaten... )


And finally, to clean it up a bit, use indentation.

ROTATE ()
       TRANSLATE ()
                OBJECT();

Notice that there's no need to use the curly brackets because both ROTATE and TRANSLATE expect an object of some sort to follow. 


Trygve
      

Den 28. august 2020 kl. 14.23.47 +02.00 skrev AndyY via Discuss <[hidden email]>:
Actually I need to place some holes at a circle:


I did with:

```
diameter = 34.0;

difference () {
cylinder(h=10, d=diameter + 10);
cylinder(h=10, d=6);
translate([0, diameter/2, 0]) {
cylinder(h=10, d=6);
}
rotate (a=120) {
translate([0, diameter/2, 0]) {
cylinder(h=10, d=6);
}
}
rotate (a=-120) {
translate([0, diameter/2, 0]) {
cylinder(h=10, d=6);
}
}
}
```

Which results in:


Is there a better way?



--

_______________________________________________
OpenSCAD mailing list

_______________________________________________
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

-- 
Ron Wheeler
Artifact Software
438-345-3369
[hidden email]

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

Re: Place holes on a circle

JordanBrown
In reply to this post by nophead
AndyY:

Nophead and Trygve gave some good hints for improvement, but your original really wasn't all that bad.

What was it that was concerning you about your result?

The only thing I see to complain about in the render that you got is that the punched-out circles are decagons, and the big circle is still pretty obviously a polygon.  (It's a 30-gon.)

$fa, $fs, and $fn control the number of sides used for a circle.
https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Other_Language_Features#$fa,_$fs_and_$fn

I'd try
$fs = 1;
$fa = 8;
to get a better approximation without going wild.  Mostly, $fs will control the small circles and $fa will control the large one.

The render tends to make circles look more polygonal than they really end up.  Let's do some math.

From the web page:
a_based=360/$fa;
s_based=r*2*PI/$fs;
n=($fn>0?($fn>=3?$fn:3):ceil(max(min(a_based,s_based),5)));
OpenSCAD "circle" radii are measured from the center to the vertices.  The distance from the center to the middle of an edge is r*cos(360/n/2).

For the default values ($fs=2, $fa=12):

Sides
Vertices
Diameter
Edges
Diameter
Error
Error
Percent
Outer
30
34
33.81
-0.19
-0.5%
Inner
10
6
5.71
-0.29
-4.9%

With $fs=1 and $fa=8:

Sides
Vertices
Diameter
Edges
Diameter
Error
Error
Percent
Outer
45
34
33.92
-0.08
-0.2%
Inner
19
6
5.92
-0.08
-1.4%



If you want to reproduce those numbers:
$fs = 1;
$fa = 8;
function v2e(r, n) = r * cos(360/n/2);
for (d=[34,6]) {
    r = d/2;
    a_based = 360/$fa;
    s_based = r*2*PI/$fs;
    n = ($fn>0?($fn>=3?$fn:3):ceil(max(min(a_based,s_based),5)));
    edges = v2e(r, n);
    error = edges-r;
    percent = error / r;
    echo(n=n, vertices=r*2, edges=edges*2, error=error*2, percent=percent*100);
}

Note that the *2 in the final echo is because the calculations are in terms of radius and you specified diameter.



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

Re: Place holes on a circle

Parkinbot
In reply to this post by OpenSCAD mailing list-2
I have a bunch of for_ modules in my main library that provide a simplified
interface to repeated objects

module forN(r=10, N=4, offs=0, M=undef) for($i=[0:(M?M-1:N-1)])
rotate([0,0,offs+$i*360/N])  translate([r,0,0]) children();
module forN(r=10, N=4, offs=0, M=undef) rotN(r, N, offs, M) children();
module forX(dx = 10, N=4) for($x=[0:N-1]) T(-((N-1)/2-$x)*dx) children();
module forY(dy = 10, M=4) for($y=[0:M-1]) Ty(-((M-1)/2-$y)*dy) children();
module forZ(dz = 10, M=4) for($z=[0:M-1]) Tz(-((M-1)/2-$z)*dz) children();
module forXY(dx = 10, N=4, dy = 10, M=4) forX(dx, N) forY(dy, M) children();

with this your code gets:

diameter = 34.0;
linear_extrude(10)
    difference() {
        circle(d = diameter + 10);
        circle(d = 6);
        forN(diameter/2, 3) circle(d = 6);
    }

a centered 3 by 4 pattern of objects gets as simple as:
forXY(10, 3, 15, 4) circle(3);

the $ provides access to the iteration variable:
forX(20, 5) text(str($x));




--
Sent from: http://forum.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: !![SPAM]!! Re: Place holes on a circle

mondo
Hi,

Referring to Andy'Y's original solution, I thought I'd have a look at
it. Bear in mind that I only discovered Openscad a month or so ago, I
found the sort of backwards progression a bit of a nuisance. From here,
I found AngelCad, and thought I'd attempt the 'flange' using that
scripting language, which for me, I can probably still read and
understand in a month or two's time.


double diameter = 34;

solid@ disc()
{
    return cylinder(10,(diameter+10)/2);
}

solid@ hole()
{
   return  cylinder(10,3);
}

solid@ threeholes()
{
    solid@ holer = translate(diameter/2,0,0)*hole();
    return  holer  + rotate_z(120)*holer + rotate_z(-120)*holer;
}

solid@ all()
{
    return disc()-hole()-threeholes();
}

void main()
{
    shape@ obj = all();
    obj.write_xcsg(GetInputFullPath(),secant_tolerance:-.01);
}

To me, that is quite a logical approach - make the disc, make a hole,
make the three holes positioned where you want, then drill 'em in the
disc. A straight forward sequence, that would be as you machined the
solid. By adjusting the secant tolerance, it regulates the number of
steps in forming a circle, for example.

Where's the naughty step?



> _______________________________________________
> 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: Place holes on a circle

OpenSCAD mailing list-2
In reply to this post by nophead
Thank you very much for the help! I'm completly new in 3D CAD. Mostly I used
it for realized models or some printings. This one should be a holder for a
electro magnet.

Can someone give me a hint how I can format source code in this forum??? It
looks ugly in the normal format.

For me this is really a nice solution:

```
$fs = 1;
$fa = 8;
$fn = 64;

diameter = 34.0;
linear_extrude(10) {
    difference() {
        circle(d = diameter + 10);

        for(i = [-1 : 1])
           rotate(i * 120)
                translate([0, diameter / 2])
                    circle(d = 6);
    }
}
```

Thank you very much! I like it.

In addition to that I know the $fn var. But not the other ones. So I have to
read the wiki for further information concerning this two vars.





--
Sent from: http://forum.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: Place holes on a circle

OpenSCAD mailing list-2
In reply to this post by JordanBrown
The holes arround the circle are getting screws for holding the magnet. So if
I have the holes in a little bigger size it does not matter if there are
some errors of the position.

Concerning you post @JordanBrown: This is a very important post for me!
Thank you. I guess the error comes from the calcuation in the OpenSCAD
engine? Which means that this is the error of the exactly position of the
holes. As I wrote in the previous post I immediatelly need to check the vars
($fs/$fa) for further designs. If you have some more internal informations,
I'd like to know it...



--
Sent from: http://forum.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: Place holes on a circle

nophead
The code I posted was via gmail and I simply set the font to Fixed Width to preserve the formatting.

On Fri, 28 Aug 2020 at 20:12, AndyY via Discuss <[hidden email]> wrote:
The holes arround the circle are getting screws for holding the magnet. So if
I have the holes in a little bigger size it does not matter if there are
some errors of the position.

Concerning you post @JordanBrown: This is a very important post for me!
Thank you. I guess the error comes from the calcuation in the OpenSCAD
engine? Which means that this is the error of the exactly position of the
holes. As I wrote in the previous post I immediatelly need to check the vars
($fs/$fa) for further designs. If you have some more internal informations,
I'd like to know it...



--
Sent from: http://forum.openscad.org/

_______________________________________________
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: Place holes on a circle

mondo
In reply to this post by OpenSCAD mailing list-2
Hi Andy, If you are 3d printing, I guess you are aware that holes
generally come out smaller than the size you give, them, depending on
quite few factors, so you can't be that precise, without a bit of
testing. If you are drilling, then holes come out bigger! If you are
designing, then holes come out at exactly the correct size.

On 28/08/2020 20:11, AndyY via Discuss wrote:

> The holes arround the circle are getting screws for holding the magnet. So if
> I have the holes in a little bigger size it does not matter if there are
> some errors of the position.
>
> Concerning you post @JordanBrown: This is a very important post for me!
> Thank you. I guess the error comes from the calcuation in the OpenSCAD
> engine? Which means that this is the error of the exactly position of the
> holes. As I wrote in the previous post I immediatelly need to check the vars
> ($fs/$fa) for further designs. If you have some more internal informations,
> I'd like to know it...
>
>
>
> --
> Sent from: http://forum.openscad.org/
>
> _______________________________________________
> 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: Place holes on a circle

nophead
I get precise 3D printed holes every time, see  https://github.com/nophead/NopSCADlib#Polyholes  for vertical holes and  https://github.com/nophead/NopSCADlib#Horiholes for horizontal holes.

And for holes printed in mid air without support https://github.com/nophead/NopSCADlib#hanging_hole

On Fri, 28 Aug 2020 at 22:16, Ray West <[hidden email]> wrote:
Hi Andy, If you are 3d printing, I guess you are aware that holes
generally come out smaller than the size you give, them, depending on
quite few factors, so you can't be that precise, without a bit of
testing. If you are drilling, then holes come out bigger! If you are
designing, then holes come out at exactly the correct size.

On 28/08/2020 20:11, AndyY via Discuss wrote:
> The holes arround the circle are getting screws for holding the magnet. So if
> I have the holes in a little bigger size it does not matter if there are
> some errors of the position.
>
> Concerning you post @JordanBrown: This is a very important post for me!
> Thank you. I guess the error comes from the calcuation in the OpenSCAD
> engine? Which means that this is the error of the exactly position of the
> holes. As I wrote in the previous post I immediatelly need to check the vars
> ($fs/$fa) for further designs. If you have some more internal informations,
> I'd like to know it...
>
>
>
> --
> Sent from: http://forum.openscad.org/
>
> _______________________________________________
> 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

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

Re: Place holes on a circle

JordanBrown
In reply to this post by OpenSCAD mailing list-2
On 8/28/2020 12:11 PM, AndyY via Discuss wrote:

Concerning you post @JordanBrown: This is a very important post for me! Thank you.


Glad to be of assistance.

I guess the error comes from the calculation in the OpenSCAD engine?


No.  It's that OpenSCAD (and every other tool that generates STL) approximates circles as polygons.

The more sides that you give the polygon, the smaller the difference is between the approximation and a true circle.

The error, as a fraction, is (cos(360/n/2)-1).

If you approximate a circle as a triangle, the error is -50%.  That is, considering the distance from the center to the vertices to be "correct", the distance from the center of the "circle" to the middles of the edges is 50% less than that.

Continuing:
# sides
Error %
3
-50%
4
-29%
6
-13%
10
-5%
15
-2%
30
-0.5%
60
-0.1%
120
-0.03%

The question there is how much inaccuracy you can tolerate, versus the processing costs of the increasing complexity of the figure.

Which means that this is the error of the exactly position of the holes.


No.  The exact position is quite precise, far more precise than you need to care about for most purposes.[*]
[*] There are occasionally rendering issues that are related to precise positioning and sizing of objects, but those are mathematical / computational issues; they have no direct bearing on the practical position of the objects in a physical object.
The errors are in the difference between the diameter that you ask for, and the diameter (in some senses) that you get.

If we assume that your fabrication process is perfect - that your 3D printer will produce exactly the object that you model - then if you ask for a circle with a diameter of 10, and approximate it with three sides, the largest rod that you can put through that hole has a diameter of 5.  If you approximate it with 15 sides, the largest rod you can put through it has a diameter of 9.78.  With 120 sides, it has a diameter of 9.997.

I believe my 3D printer has an X-Y positioning resolution of 0.1mm.  It has a 0.4mm nozzle, and the plastic squishes out a bit.  I don't know exactly how those will translate into dimensional accuracy, but for discussion purposes it doesn't seem unreasonable to guess that my dimensional accuracy is no better than 0.1mm - that is, if I ask for a 10x10x10mm cube, the X and Y sides will be somewhere between 9.9 and 10.1mm.  (It's probably not really that good.)

With 15 sides, the error from the polygon approximation on a 10mm circle is about 0.2mm, or twice the theoretical accuracy of the device.  With 30 sides, the error is about 0.05mm, or half the accuracy of the device.  That's saying that going from 3 sides to 15 is a big win, and going from 15 to 30 is a small win, but more than 30 (actually, more than something in the low 20s)  is pointless because the other errors in the system will swamp this one.

If you're using some other fabrication technology - if, for instance, you are milling and polishing metal - then your system will likely be more accurate and you may have correspondingly tighter restrictions on the modeling errors.

As I wrote in the previous post I immediately need to check the vars ($fs/$fa) for further designs. If you have some more internal informations, I'd like to know it...


$fn is easy.  It says how many sides a circle has, period.

That's easy, but it's not what you really want.  A 10mm circle with 15 sides is awfully close to a perfect circle - you might not be able to see the polygon-ness when printed - but on a 100mm circle it would very much look like a polygon.  On the other hand, if you ask for 100 sides, your 10mm circle will have sides that are only 0.3mm long, not quite imperceptibly small.  No one setting will work for both small and large circles.

$fa and $fs are an attempt to let you define values that will "work" at all sizes.

$fa means "don't bother adding sides if the angle is less than this".
$fs means "don't bother adding sides if each side is less than this".
OpenSCAD uses whichever yields *fewer* sides.

For typical values, $fa controls the behavior on large circles, and $fs controls the behavior on small circles.

Note:  $fn is very useful for a different purpose.  It is how you explicitly ask OpenSCAD for a regular polygon.  If you want an octagon, you can use circle(d=<whatever>, $fn=8) and you will get an octagon, no matter how large the circle is.

Note:  none of this is "internal".  It is all part of how OpenSCAD is defined to model circles.

---

I realized there was an error in my previous tables - I missed that the actual diameter of the big circle was 34+10 = 44, not 34.  Here's corrected tables:

For the default values ($fs=2, $fa=12):

Sides
Vertices
Diameter
Edges
Diameter
Error
Error
Percent
Outer
30
44 43.76
-0.24
-0.5%
Inner
10
6
5.71
-0.29
-4.9%

With $fs=1 and $fa=8:

Sides
Vertices
Diameter
Edges
Diameter
Error
Error
Percent
Outer
45
44
43.89
-0.11
-0.2%
Inner
19
6
5.92
-0.08
-1.4%


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

Re: Place holes on a circle

cacb
In reply to this post by mondo
On 2020-08-28 20:54, Ray West wrote:
> Where's the naughty step?

There is nothing "naughty" about it. This thread shows various examples
on how to model a simple case using scripting languages. Regardless of
language being used, for most people the goal is to express it in a
efficient, but expressive way that feels natural. What feels natural is
highly subjective, so there will be many different solutions, even
within the same language.

Carsten Arnholm

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