Splines for drawing fan blades?

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

Splines for drawing fan blades?

braddo
This post has NOT been accepted by the mailing list yet.
Hey all, I'm trying to draw a sort of fan and am currently doing it in a brute force way which isn't working as I would like. Well it works but rendering is taking too long. I'm quite sure there's a way that's not only more efficient for rendering but also would allow for more design flexibility.

Below is the code I'm currently using, basically creating a symmetrical foil by changing the scaling factor of cylinders as rotated through an arc.

I'm thinking a surface spline could do this better, but don't really know how to use that approach. Have searched and found libraries like nSplines() which seem crazy powerful, but I can't figure out how one would choose the points for the matrix (or what the columns of the matrix are intended to represent).

Meanwhile, it would be cool to be able to control the edge of these little fan blades as well, making sort of a yin/yang shape.

Anybody have a suggestion or a link to a tutorial that could get me started?

Thanks!

CoreR = 12;
Triple = 59;
BladeLen = 20;

module Blades(){
for(i=[0,120,240]){
                rotate([0,i,0])
                for(j=[-1:.01:1]){
                        rotate([0,Triple*j,0])
                                translate([0,0,20]) rotate([0,j*1.4,0])  // want the edges to be parallel
                                scale([4*cos(j*90)+.5,4*cos(j*90)+.5,1])
                                cylinder(center=true, r=0.75,h=BladeLen);
                }
        }
}

Blades();
Reply | Threaded
Open this post in threaded view
|

Re: Splines for drawing fan blades?

MichaelAtOz
Administrator
Bump, as it didn't make it to the mailing list.
braddo wrote
Hey all, I'm trying to draw a sort of fan and am currently doing it in a brute force way which isn't working as I would like. Well it works but rendering is taking too long. I'm quite sure there's a way that's not only more efficient for rendering but also would allow for more design flexibility.

Below is the code I'm currently using, basically creating a symmetrical foil by changing the scaling factor of cylinders as rotated through an arc.

I'm thinking a surface spline could do this better, but don't really know how to use that approach. Have searched and found libraries like nSplines() which seem crazy powerful, but I can't figure out how one would choose the points for the matrix (or what the columns of the matrix are intended to represent).

Meanwhile, it would be cool to be able to control the edge of these little fan blades as well, making sort of a yin/yang shape.

Anybody have a suggestion or a link to a tutorial that could get me started?

Thanks!

CoreR = 12;
Triple = 59;
BladeLen = 20;

module Blades(){
for(i=[0,120,240]){
                rotate([0,i,0])
                for(j=[-1:.01:1]){
                        rotate([0,Triple*j,0])
                                translate([0,0,20]) rotate([0,j*1.4,0])  // want the edges to be parallel
                                scale([4*cos(j*90)+.5,4*cos(j*90)+.5,1])
                                cylinder(center=true, r=0.75,h=BladeLen);
                }
        }
}

Blades();
Admin - email* me if you need anything,
or if I've done something stupid...
* click on my MichaelAtOz label, there is a link to email me.

Unless specifically shown otherwise above, my contribution is in the Public Domain; to the extent possible under law, I have waived all copyright and related or neighbouring rights to this work.
Obviously inclusion of works of previous authors is not included in the above.


The TPP is no simple “trade agreement.” Fight it! http://www.ourfairdeal.org/ time is running out!
Reply | Threaded
Open this post in threaded view
|

Re: Splines for drawing fan blades?

Neon22
In reply to this post by braddo
You might want to persevere with @parkinbots nspline library.
Specifically the example here: http://www.thingiverse.com/thing:1208001

I wrote some more about it here:
- http://forum.openscad.org/Trying-to-incorporate-equation-based-shapes-td3116.html#a16625

Have a read and see if you can work out what's going on.

First thing to sort out is all the names are mangled.
- Rudolf uses linux and all uppercase letters are autoconverted to lowercase.
- Also the zip file contains mangled long hash style filenames.

Look inside each one and make sure you rename them to match the following files(taken from the boat propeller file):
use <Naca4.scad> 
use <Shortcuts.scad>
use <Naca_sweep.scad>
use <splines.scad>

You know its working when the boat propeller appears.


One of the hased files is the boat propeller scad file.
Inside you will see these things:
- module axis -
- module boat_prop with a function called gen_dat inside it
- A variable called A which holds the shapes
and these global variables:
N = 100;         // refinement
R_axis = 100;   // radius of axle
r_bore = 50;    // radius of axle bore
size = .1;      // sizing factor
slices = false;  // set true to view interpolation slices
ty = 50;        // common y-distancing of blades

So what's going on and how do you control it:
1. if you set slices to true you will see the NACA airfoils spread out along a single one of the propeller blades. There are 4 but the last one is not visible as its scaled vey small.

2. The functoin gen_dat takes teh A variable and uses it to make teh data to build each blade.

3. The A variable holds the shape definition
// core data to be interpolated by nSpline()
//       transform data             airfoil nacaXYZZ  
//--------------------------------------------------
A = [ // Tx    Ty   Tz   Rz   Ry  |   L    X    ZZ
        [0,    ty,   60, -25,   0,  300,  .12,  .1],
        [-50,  ty,  200, -50,   0,  600,  .2,  .08],
        [-100, ty,  500, -75,   0,  700,  .1,  .06],
        [00,   ty,  660, -82,  10,   10,  .01,  .1],
    ];
As indicated in the comment the first 5 values translate and rotate the shape into the proper position.
The second set of three values (L,X,ZZ) define teh airfoil shape.
Rather than use the NACA number @parkinbot has put in the bvalues that are extracted from eth NACA number directly. (see more about NACA numbers in my post referenced at top of this post)

So
- you can change these three values and get different airfoils.
- you can use different Translate, roatte values to get different overall blade shape
- you can alter the shl value (270 degrees) to get other numbers of blades...

Good luck
Reply | Threaded
Open this post in threaded view
|

Re: Splines for drawing fan blades?

Parkinbot
A simpler approach letting you design your own fan would be: http://www.thingiverse.com/thing:1016047

@Neon22: Thanks for exploring and explaining the design. I know it is a bit sophisticated, but it lets you do so much. Meanwhile I have corrected the upper/lowercase mismatch. Sorry for that. Please let me know if there is some problem left.

Rudolf

Reply | Threaded
Open this post in threaded view
|

Re: Splines for drawing fan blades?

Neon22
@parkinbot its a very nice layout you have.
Its the sort of thing that would be good to see slightly simplified and formalised for OpenSCAD2 maybe.

The idea of defining a structure containing shapes and transforms is useful.
Also the trick in splines of splining across however many items you put in the array is very clever.

So if you want a three point spline or 100 points - its the same function applied the same way.


I like your http://www.thingiverse.com/thing:1016047 but I'd humbly suggest:

- some explanation of Repeller vs Propeller. One is not quite the inverse of the other (still need to negate twist etc. so perhaps explain what it is reversing. Maybe its just CCW vs CW.
(https://en.wikipedia.org/wiki/Repeller suggests this is unusual usage of the term)

- I would not have used the same name with just a change of case for two modules - even though one only calls the other. I'd humbly suggest using a different name. Like in your other airfoil code you used airfoil_data() and airfoil().
Maybe Propeller is the internal module and Prop_CW and Prop_CCW are the upper level modules ??

- Only users of your shortcuts will relise the D() examples are differencing the propeller from a Ring and that this code is to round the propeller tips. Its obvious once you know, but on initial examination its not clear. Nice trick BTW.
Reply | Threaded
Open this post in threaded view
|

Re: Splines for drawing fan blades?

Parkinbot
Neon22 wrote
- some explanation of Repeller vs Propeller. One is not quite the inverse of the other (still need to negate twist etc. so perhaps explain what it is reversing. Maybe its just CCW vs CW.
(https://en.wikipedia.org/wiki/Repeller suggests this is unusual usage of the term)
Good point. I followed your suggestion. Not everyone (writing a wiki entry) had latin in school. Indeed one is the kinematic inversion of the other like electrical generator vs. motor.

- I would not have used the same name with just a change of case for two modules - even though one only calls the other. I'd humbly suggest using a different name. Like in your other airfoil code you used airfoil_data() and airfoil().
Maybe Propeller is the internal module and Prop_CW and Prop_CCW are the upper level modules ??
Well, naming and programming styles are a big mess. That's why I hate to read foreign code. For instance I don't like variable names like thisIsTheHeightOfMyFirstShape=1. This makes code unreadable for me as the structure disappears within line breaks and monster names. Thus I am using short cuts and short names, but a lot of functions and modules with local variables. When I share code, I usually spend some amount of time to comment it, give examples for the API and even offer help() modules echoing the prototypes and default values to the console, but I am not prepared to start renaming or even refactor the code. Or writing tons of explanations why I used which construction. If someone wants to reuse it, he will have to spend time playing with it anyway ;-)  

- Only users of your shortcuts will relise the D() examples are differencing the propeller from a Ring and that this code is to round the propeller tips. Its obvious once you know, but on initial examination its not clear. Nice trick BTW.
Not a trick, but bad programming. I should have used intersection() with a cylinder (executes faster). I guess typing D(){Ri(r1, r2, h);... } was faster ;-)
In the mean time OpenSCAD also allows for a I() shortcut - which I haven't implemented yet. This might change my programming a lot :-)
Reply | Threaded
Open this post in threaded view
|

Re: Splines for drawing fan blades?

braddo
This post has NOT been accepted by the mailing list yet.
In reply to this post by braddo
So, I finally figured out how to use the Sweep function! I should have been looking at the Horn example rather than the boatprop.

I got my job partially done but am having a problem now...

I made a few shapes which I now want to cut by subtracting from another object (to make a ducted fan).

The difference() operation seems to sort of work, but the edges remaining are not rendering in preview mode, and nothing shows up after a render operation.

Does this give any clue to what might be going wrong? I can post the code as well, ... below, sorry I don't see a "code" insert mechanism on this forum:

(I commented out the difference operation)

use <splines.scad>
use <Naca_sweep.scad> 

Angle=119;
Inner = 10;
Outer = 60;
Fatness = 8;
BladeTrim = 4*25.4/2;


A = [//x,   y, z,      r, angle   // data outer skin
      [0,   0, Inner,     -0.5 + 2* Inner* sin(Angle/2),   0],
      [0,   0, (Outer-Inner)/2, 2* (Outer-Inner)/2* sin(Angle/2),   0],
      [0,   0, Outer,     0.5 + 2* Outer* sin(Angle/2), 0],
  ];
 

B = nSpline(A,100);    // outer skin
B1 = nSpline(A1,100);  // inner skin

C = gen_dat(B, 100);   // generate data
C1 = gen_dat(B1, 100); // generate data

Blades();
module Blades(){
// difference(){
                for(i=[0,120,240]){
                        rotate([0,i,0]) sweep(C);
                }
// rotate([90,0,0])
// difference(){
// cylinder(center=true, r=800, h=400);
// cylinder(center=true, r=BladeTrim, h=401);
// }
// }
}

//function circle_(r, N) = [
//  for(i=[0:N-1]) let(w = i*360/N)
//    [r*sin(w), r*cos(w)]];


function circle_(L=1, N) = [
  for(i=[-1:1/N:1]) for(j=[-1,1]) [L*i, j*L/Fatness*cos(i*90)]
];

//function circle_(L,N) = [[1,1],[5,1],[1,5],[5,5]];
   
function gen_dat(S, N) =
   [ for (i=[0:len(S)-1])
       let(dat = Ry_(S[i][4], vec3D(circle_(S[i][3], N))))
        T_(S[i][0], S[i][1], S[i][2], dat)];
 
 
Reply | Threaded
Open this post in threaded view
|

Re: Splines for drawing fan blades?

Parkinbot
Don't see exactly what you want to do. But let me remark some points.

It is always better to start with some small N, like N=10. This saves time.

gen_dat() uses a 2D shape function like circle_() or airfoil_data() to generate a series of parametrized polygons and a trajectory function to place those shapes in 3D. sweep() knits this series together into a 3D shape. It should be clear that this does has some constraints on the data.

The data must be 'nice' enough to describe a non-self-intersecting 3D shape. This means:
1. each polygon must behave well to be 'knitable'
   - no self intersection !!
   - convex shape at best (like circle) or at minimum some half-symmetry (like airfoil), because I used a lazy triangulation for the two cap faces (I will update this one day - promised). You can try skin() instead of sweep() if that is not the case.
   - a common number of vertices. You can try skin() instead of sweep() if that is not the case.
   - the right sense: CCW

2. The trajectory function must be 'nice'.
 - 2D shapes are not allowed to intersect in 3D when being swept. If this is unavoidable, split the data and union two (or more) sweeps.

3. My code does not test those things (OpenSCAD currently has no error scheme for reporting problems), but it should be clear from general sweep() semantics.

Using thrown together view (f12) will reveal problems. Magenta shaped triangles have wrong sense.

Reply | Threaded
Open this post in threaded view
|

Re: Splines for drawing fan blades?

braddo
This post has NOT been accepted by the mailing list yet.
Well, I think my attempt is very mild and adheres to all of your constraints. Sorry there is some junk in the file which might make it seem more complex than it is. Basically I have three "football" shapes moving up in the z direction then have rotated that thing around one axis to get three copies. That all works great. What's not working is I now want to trim the edges so that this thing fits inside a cylinder. The difference doesn't seem compatible with what Ive drawn.
Reply | Threaded
Open this post in threaded view
|

Re: Splines for drawing fan blades?

Parkinbot
are you sure your 2D-shape is not self-intersecting? Try this:

polygon(circle_(1, 20));




Reply | Threaded
Open this post in threaded view
|

Re: Splines for drawing fan blades?

Parkinbot
Use this code instead:

function circle_(L=1, N) = [
  for(j=[1,-1], i=[-1:1/N:1])  [j*L*i, j*L/Fatness*cos(i*90)]
];

and look at your radius. You use 800, this has no effect. Try this:

module Blades(){
  intersection(){
     for(i=[0,120,240])
       rotate([0,i,0]) sweep(C);
  rotate([90,0,0]) cylinder(center=true, r=40, h=400);
  }
}

Reply | Threaded
Open this post in threaded view
|

Re: Splines for drawing fan blades?

braddo
This post has NOT been accepted by the mailing list yet.
Oh I just found my stupid indexing error and came to post but you guys already found it... thanks!

Brad
Reply | Threaded
Open this post in threaded view
|

Re: Splines for drawing fan blades?

braddo
This post has NOT been accepted by the mailing list yet.
Also, intersection is a far better way to trim the blades to fit into a cylinder - I forever forget about it.