Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - raymw

Pages: [1] 2 3
1
General Discussion / Re: Turtle graphics
« on: 2022-03-07, 18:26:37 »
I've added a bit more complexity to the original code. It can produce interesting stl files 3d prints, or can, if the values are not correct, produce equally interesting errors.
With careful choice of parameters you can create a multi spiral sided pot, with a screw-on lid, for example. I have just added a facility to reverse the direction of the spiral at various heights. The values I have in the example code works, produces a water tight pot, other values may throw errors, at the moment it is almost trial and error. to choose workable values. I will add some images, if possible.
Code: [Select]
// turtle tube

double rfd = PI/180;  //rads from degrees

void settings (thing &out it)
{
    it.le = 20;  // length of rod 
    it.w = 1.5;    // width of rod
    it.h = 1.5;    // height of rod
    it.rot = false; // rotate rectangular rods by 45 degree, to remove horizontal overhangs
    it.range = 200;   // number of rods
    it.a =61;    // angle between rods
   // it.b = 0.7*it.h/(360/it.a);  // vertical angle
    it.b = 0.5*it.h/(360/it.a); // smaller vertical angle to allow for reversal of direction.
    it.base = true;// false if base not needed
    it.flat = false ; // true for flat base
    it.round = true; // set to true if wanted rounded adges instead of square (diamete =w)
    it.blob = 2;  // diameter of blob at corners (0 to ignore)
    it.rev = false;  // set true if you want spiral (if any) reversed
    it.cut = 0 ; // if a positive value, it cuts off the top of 'cylinder', at cut.height
    it.dir =24 ;  // if a positive value, it reverses direction every dir number of rods
    it.ar = 59 ;  // 'reverse direction' angle
    ////////////////////////////////////
   
return;

 
class thing
{
   double le, w, h, a, b, blob, bang, cang, cut, dir, dirc, ar = 0;   
   int range = 0;
   bool base, round, rot, flat, rev = true;
}
   
solid@ part(thing it)
{       
           solid@ stroke = translate(it.le/2,0,0)*cuboid(it.le,it.w,it.h,true);
           
           if (it.rot == true)
           {
                 @stroke = rotate_x(rad:rfd*45)* stroke; // angle to make 3d printable - 45 deg overhangs
           }
    if (it.round==true)
    {       
           @stroke  = rotate_y (rad:PI/2)*cylinder(it.le,it.w/2);               
    }       
return stroke;
}     
   
solid@ ball(double blob)

return sphere(r:blob/2);
}
     
   
solid@ draw( thing it, pos3d@ now, pos3d@ &out last)
{

   solid@ ans=
      translate(now.x(),now.y(),now.z())*
      rotate_z(rad:rfd*it.cang)*
      part(it);
   // calc 'last' for next 'now'
        @last = now + pos3d(cos(rfd*it.cang)*it.le,sin(rfd*it.cang)*it.le,it.bang );
   // put sphere at corner if needed
       if (it.blob >0 )
       {           
          @ans =ans +  translate(last.x(),last.y(),last.z())*ball(it.blob);
       }   
return ans;
}
 
void main()
{
    thing it;
    settings(it); //get values
    pos3d@ now = {0,0,0};
    pos3d@ last= {it.le,0,0};
    array <pos2d@> points;
    solid@ obj;
    double tempa = it.a;
 
  if (it.base == true)
  {
     it.flat=true;
  }   
       @obj = part(it);  // this is to become the set of lines
     int count=0;   
       while( count < it.range )
       {       
           it.bang=0;  // flatten bottom ( b, vertical angle =0) and make polygon
             
             if (it.flat==true)
             {
               if (count <= 360/it.a)
               {                   
                       points.push_back(pos2d(last.x(),last.y()));
               }               
                 if (count>((360/it.a)))   
                 {
                       it.bang=it.bang+it.b;  // now add vertical angle
                 }
                    if (count>=it.range-(360/it.a)-1)  // to give flat top   
                    {
                          it.bang=0;  // vertical angle 0 for last few
                    }
            }
           
            if (it.flat == false)
            {
               it.bang=it.bang+it.b;
            }
              it.cang=it.cang+it.a;
              @now = last;
              @obj = obj+draw(it,now,last);
              // change direction
              if (it.dir >=1)
              {
                  it.dirc=it.dirc+1;           
                    if (it.dir== it.dirc)
                    {
                       tempa=it.a;
                       it.a=it.ar;
                       it.ar=tempa;
                       it.dirc=0;
                    }
              }
             
        count++;
      }       
           if (it.rot==true)
           {
            // get rotaton position of base
             @obj= translate(0,0,(sqrt((it.w *it.w) + (it.h*it.h))*0.5)-it.w/2)*obj;
           
            }
           @obj= translate(0,0,it.w/2)*obj;
       
               if (it.base==true)  // make solid base
              {
               polygon@ solid_base = polygon (points);
               @obj=obj + linear_extrude(solid_base,height:it.h);
                if (it.rev == true)
                {
                  @obj= mirror(1,0,0)*obj;
                }
                   if (it.cut>0)  // cut off top using 500 cube centred
                   {
                     @obj = obj-translate(0,0,it.cut+250)*cube(500,true);
                   }
     }
       
  // assume no overlap
              cout<< "aproximate height " << (it.range /(360/it.a))*it.h << endl;
             obj.write_xcsg(GetInputFullPath(),secant_tolerance:0.0010);
}
       

2
General Discussion / Re: drawing lines
« on: 2022-02-26, 14:35:01 »

Progress is slow, but so far it is getting to where I want it to be.
Code: [Select]

// AngelCAD code.

#include "aclib/fonts/LiberationSerif_Regular.as"

shape2d@ resistor(r v){   // on 100 grid
   
    string name = v.nam;
    as_font@ font = LiberationSerif_Regular();
    shape2d@ wire= rectangle (1,100,true);
    shape2d@ body= rectangle (15,50,true);
    shape2d@ t1 = translate(0,50)*circle(2);
    shape2d@ mk= translate(0,34)*square(4,true); //mark t1 end
    shape2d@ t2 = translate(0,-50)*circle(2);
    shape2d@ txt2d = translate(50,50)*font.text("  "+name,v.ltext);
return wire+body +t1 +t2 +mk + txt2d;
}


class r  // resistor class
{
double res, amp, t1v, t2v =0;
pos2d@ t1 = {0,0};
pos2d@ t2 = {0,0};
string nam = "xx";
int ltext=20;  // default text length
//amp=(t1v-t2v)/res;
//t1v=t2v + amp*res;
}


shape2d@ drawr(r v)
{
  shape2d@ resp;
   if (v.t1.y()>v.t2.y())
   {
   @resp = translate(v.t1.x(),v.t1.y()-50)*resistor(v); //t2.y < t1.y
   }
    if (v.t2.y() > v.t1.y()) // vertical, t1y<t2y
    {
    @resp = translate(v.t1.x(),v.t1.y() +50)*rotate_z(180)*resistor(v);
    }
     if (v.t1.x() < v.t2.x()) // horizontal t1 to left of t2
     {
     @resp = translate(v.t2.x()-50,v.t2.y())*rotate_z(90)*resistor(v);
     }
      if (v.t2.x() < v.t1.x()) // horizontal, t1 to right of t2
      {
      @resp = translate(v.t1.x()-50,v.t2.y())*rotate_z(270)*resistor(v);
      }
   
return resp;
}   

void main()
{
   // set up resistor network
   r r1;
   r r2 ;
   r r3 ;
   r r4;
   r r5;
   
  r1.nam="R1";
  r2.nam= "R2";
  r3.nam="R3";
  r4.nam="R4";
  r5.nam="R5";
 
  r1.res=20;
  r2.res=10;
  r3.res=20;
  r4.res=10;
  r5.res=10;
 
  @r1.t1= {0,200};
  @r1.t2= {0,100};
  @r2.t1= {0,100};
  @r2.t2= {0,0};
  @r3.t1= {0,100};
  @r3.t2= {100,100};
  @r4.t1= {100,200};
  @r4.t2= {100,100};
  @r5.t1= {100,100};
  @r5.t2= {100,0};
 
  //  draw network
    shape2d@ net= drawr(r1);
    @net = net +drawr(r2);
     @net = net +drawr(r3);
      @net = net +drawr(r4);
       @net = net +drawr(r5);
   
 shape2d@ obj = net;
   obj.write_xcsg(GetInputFullPath(),secant_tolerance:-1.0);
}
I've started by making the resistor components a standard size, and only allowing horizontal or vertical orientation. The small square marks the T1 end of the resistor. This will allow any network to be configured, using a resistor of zero ohms to act as a busbar, if necessary, allowing any number of connections to a 'star point' to be made. Once I've discovered how to rotate and move text  it could be tidied up a bit, but in the meantime, I can cout the results of calculations for each component. Probably it will need to do some verification, to ensure the connections are at the correct locations, but I may be even able to generate the locations given  just a list of connections.

3
General Discussion / text manipulation
« on: 2022-02-25, 16:17:30 »
Having looked at the 3d text sign example on git hub, I was thinking it would be straightforward to create 2d text
Code: [Select]
#include "aclib/fonts/LiberationSerif_Bold.as"

shape@ main_shape()
{
   
  array<string> name = { "text"};
       

   // Create font object used for text generation
   as_font@ font = LiberationSerif_Bold();
     shape2d@ txt2d = font.text(name,length:5);
     shape2d@ txtf= translate (20,20)*txt2d;
    return  txtf;
}

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

However, I am unable to position the text other than bl at origin, and i would like to have a consistant height for the text (not length), which may involve finding the length of the string, which seems to be different than in c++.  (strlen() in c++). So, how do I set the height, and move the text around?

4
General Discussion / Re: drawing lines
« on: 2022-02-18, 20:54:11 »
Thanks. Having corrected my errors, line drawing is far to slow, using my method. I think that I will try to draw the components in my normal cad package, and import the dxf, if necessary. Each node and component will need labeling, and it is probably easier to do that outside of AngelCad, and then import the dxf, and use Angel ad to perform the calculations, and possibly write the results back to the dxf. I can't try it at the moment, the numerous electricity supply interruptions we've had today, has crashed my cad program, and it is asking for a registration code, but otherwise not responding.

5
General Discussion / Re: drawing lines
« on: 2022-02-17, 23:41:00 »
I would prefer  dxf output, since I can annotate it in another program. I'm not getting much success, however.

This simple test works fine, wrt rotate.
Code: [Select]
shape@ main_shape()
{
  shape@ tt = rotate_z(45)*square(50);
return tt;
}

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

However, having spent some time trying various options, then guesses, This fails at the rotate on line 19 - apart from the rotate it is OK, afaik.
Code: [Select]
double rfd = PI/180;  //rads from degrees

shape@ horz (double leng)
{
   shape@ lin= translate (leng/2,0)*rectangle(leng,0.01,center:true);
return lin;
}


shape@ aline(double p1x,double p1y,double p2x,double p2y)
{
 double len= sqrt(((p1x-p2x)*(p1x-p2x))+ ((p1y-p2y)*(p1y-p2y)));
          cout << "length " << len <<  "  ";
  shape@ lin = horz(len);
    double ang = sin(rfd*(p2y-p1y)/len);
          cout <<  " sin of angle " << ang/rfd ;
    shape@ angled = rotate_z(deg:ang)*lin;  //  how to rotate 2d ?
return angled;
}
 
void main()
{
      shape@ obj =  aline(1,1,25,25);  // should be 45 deg line from 1,1
      obj.write_xcsg(GetInputFullPath(),secant_tolerance:-1.0);
}



6
General Discussion / drawing lines
« on: 2022-02-16, 22:19:21 »
stuck on producing lines in dxf
Code: [Select]
shape@ aline()
{
  shape@ ll= line2d(pos2d(1,2),pos2d(4,5));
return ll; 
 }
 
void main()
{
   shape@ obj = aline();
   obj.write_xcsg(GetInputFullPath(),secant_tolerance:-1.0);
}
Tried everything I can find, even tried a 'cast', but to no avail. The  AngelCAD sample: tutorial_primitives_2d.as does not include lines.
My intention is to be able to apply basic symbols/ text to dxf drawings of electrical circuits, for example.

7
General Discussion / Turtle graphics
« on: 2022-02-12, 19:33:31 »
I was around when Logo and turtle graphics were first popular, but more or less ignored them. Recently I saw a Utube video (numberphile) where it was explained hor turtle graphics could produce SierpiƄski Triangles, and I thought that maybe using AngelCAD could possibly do something similar but in 3d, for 3d printing. I've not used AngelCAD for sometime, and it is a struggle getting back into the flow, so to speak. I ran some simple tests, and decided that I would not be able to plot a meaningful triangle using my PC, in any reasonable amount of time.

However, with significant help from Carsten, I managed to produce something based loosely on turtle graphics, and I've put the code below. It sort of can print various patterned tubes, with or without a base. ( a vase, if you like), but if you water tight, you will need to adjust the various values. However, for the variables I've set, it fails after about 1250 iterations (i.e. in my code 'range' set to more than 1250) , however that may be a limitation in my particular PC. I started by generating a tube, then decided to add a base, and give a few other options, which can readily alter the appearance of the whole object. If the angle is not a factor of 360, then you will get a sort of spiral shape, as in the values I've shown. There are still a number of features that could be added - I've just added a print out of the approximate height, but with a bit of effort that could be more precisely calculated, and that value used to calculate 'range' .

Code: [Select]
double rfd = PI/180;  //rads from degrees

void settings (thing &out it)
{
    it.le = 20;  // length of rod
    it.w = 2;    // width of rod
    it.h = 2;    // height of rod
    it.rot = false; // rotate rods by 45 degree, to remove horizontal overhangs
    it.range = 1250;   // number of rods
    it.a = 50;    // angle between rods
    it.b = it.h/(360/it.a);  // vertical angle
    it.base = true; // false if base not needed
    it.round = false; // set to true if wanted rounded adges instead of square (diamete =w)
    it.blob = 0;  // diameter of blob at corners (0 to ignore)
   
    ////////////////////////////////////
    it.bang=0;
    it.cang=0;
return;

 
class thing
{
   double le, w, h, a, b, blob, bang, cang = 0;   
   int range = 0;
   bool base, round, rot = true;
}
   
solid@ part(thing it)
{       
           solid@ stroke = cuboid(it.le,it.w,it.h,false);
           
           if (it.rot == true)
           {
                 @stroke = rotate_x(rad:rfd*45)* stroke; // angle to make printable
           }
    if (it.round==true)
    {       
           @stroke  = rotate_y(rad:PI/2)*cylinder(it.le,it.w/2);               
    }       
return stroke;
}     
   
solid@ ball(double blob)

return sphere(r:blob/2);
}
     
   
solid@ draw( thing it, pos3d@ now, pos3d@ &out last)
{

   solid@ ans=
      translate(now.x(),now.y(),now.z())*
      rotate_z(rad:rfd*it.cang)*
      part(it);
   // calc 'last' for next 'now'
        @last = now + pos3d(cos(rfd*it.cang)*it.le,sin(rfd*it.cang)*it.le,it.bang );
   // put sphere at corner if needed
       if (it.blob >0 )
       {           
          @ans =ans +  translate(last.x(),last.y(),last.z())*ball(it.blob);
       }   
return ans;
}
 
void main()
{
    thing it;
    settings(it); //get values
    pos3d@ now = {0,0,0};
    pos3d@ last= {it.le,0,0};
    array <pos2d@> points;
    solid@ obj;
 
       @obj = part(it);  // this is to become the set of lines
     int count=0;   
       while( count < it.range )
       {       
           it.bang=0;  // flatten bottom ( b, vertical angle =0) and make polygon
              if (count <= 360/it.a)
              {
               points.push_back(pos2d(last.x(),last.y()));
              }               
                 if (count>((360/it.a)))   
                 {
                 it.bang=it.bang+it.b;  // now add vertical angle
                 }
                    if (count>=it.range-(360/it.a)-1)  // to give flat top   
                     {
                     it.bang=0;  // vertical angle 0 for last few
                     }
           it.cang=it.cang+it.a;
              @now = last;
              @obj = obj+draw(it,now,last);
        count++;
      }       
           if (it.round==true)
           {
           @obj= translate(0,0,it.w/2)*obj;
           }
               if (it.base==true)  // make solid base
              {
               polygon@ solid_base = polygon (points);
               @obj=obj + linear_extrude(solid_base,height:it.h);
              }
         // assume no overlap
              cout<< "aproximate height " << (it.range /(360/it.a))*it.h << endl;
      obj.write_xcsg(GetInputFullPath(),secant_tolerance:-1.0);
}

I've put the values you can change at the top of the program listing, in the settings function, but of course, you can do what you like with the rest of it. If you want to play with it, then set range to 590, to get a quick fstl, which will give you an idea of the patterns you can get.

8
exactly as posted (without the fillet operational) it takes 1 minute and 27 seconds in openscad on my machine, and in angelcad, it produces a couple of lines -  UNEXPECTED face loop with size != 1.
UNEXPECTED face loop with size != 1. (and other messages as well), and a broken model. This is what I was getting at, what runs in openscad slowly, may not run at all in angelcad. I initially ran it in angelcad, with the fillet, since that took far to long in openscad. It did not run properly in angel cad, so I commented out the fillet code, and it still did not run in angel cad. I've just run this commented code, exactly as shown in the forum, and on my pc it takes 1 minute and 27 seconds in openscad. Your machine must be a bit faster, but it still does not run in Angel cad. It would be nice to know what causes the unexpected face loop, but I eventually got a result in openscad that was good enough. 

9
The threading stuff is in  NopSCADlib and comes from https://github.com/nophead/NopSCADlib as you said.
The fillet was found on https://www.thingiverse.com/thing:2461392  there is a slight error in the code, I corrected it and reported it to the author, not sure if he fixed it, (I've attached that file*, but you can comment that out in my example). The problem is, that If I can't get things to work, then I try another way, and tend to forget the details of the original problem, which is probably not much help to you.

* for some reason, it couldn't get the path to the zip file for the attachment, so it's all below

Code: [Select]



/*
Created by Kevin Gravier
https://www.thingiverse.com/mrkmg/about

My take on a top and bottom fillet for a 3d shape.

Available Modules:

topBottomFillet(b, t, r, s, e)
b = z of bottom of 3d object
t = z of top of 3d object
r = radius of fillet
s = steps of filler (smaller is smoother)
e = enabled (pass e = 0 to disable fillet for faster preview)

topFillet(t, r, s, e)
t = z of top of 3d object
r = radius of fillet
s = steps of filler (smaller is smoother)
e = enabled (pass e = 0 to disable fillet for faster preview)

bottomFillet(b, r, s, e)
b = z of bottom of 3d object
r = radius of fillet
s = steps of filler (smaller is smoother)
e = enabled (pass e = 0 to disable fillet for faster preview)

*/

enable = 1;
/*
// Example, hard edges
translate([0, 20, 0])
topBottomFillet(b = 0, t = 10, r = 2, s = 20, e = enable)
linear_extrude(10, scale = 1.2)
difference() {
    union() {
        square([10, 10], true);
        translate([-15, 0]) circle(15);
    }
    translate([-15, 0]) circle(8);
    translate([-15, 0]) square([13, 13], center = true);
}

// Example, soft edges
use <fillets2d.scad>;
translate([0, -20, 0])
topBottomFillet(b = 0, t = 10, r = 1, s = 10, e = enable)
linear_extrude(10)
rounding2d(1)
fillet2d(1)
difference() {
    union() {
        square([10, 10], true);
        translate([-15, 0]) circle(15);
    }
    translate([-15, 0]) circle(8);
    translate([-15, 0]) square([13, 13], center = true);
}


// Example, text
translate([-60, 40])
rotate([0, 0, -90])
topBottomFillet(b = 0, t = 3, r = .5, s = 5, e = enable)
linear_extrude(3)
text("Fillets!", size = 20);

*/
// Library

function filletDepth(r, d, i) = r * cos(asin(d * i / r));

module topBottomFillet(b = 0, t = 2, r = 1, s = 4, e = 1) {
    if (e == 1) {       
        topFilletPeice(t = t, r = r, s = s) children(0);
        bottomFilletPeice(b = b, r = r, s = s) children(0);
       
        render()
        difference() {
            children(0);
           
            translate([0, 0, t - r])
            linear_extrude(r + 1)
            offset(delta = 1e5)
            projection()
            children(0);
           
            translate([0, 0, b - 1])
            linear_extrude(r + 1)
            offset(delta = 1e5)
            projection()
            children(0);
           
        }
    }
    if (e == 0) children(0);
}

module topFillet(t = 2, r = 1, s = 4, e = 1) {
    if (e == 1) {
        topFilletPeice(t = t, r = r, s = s) children(0);
       
        render()
        difference() {
            children(0);
            translate([0, 0, t-r])
            linear_extrude(r + 1)
            offset(delta = 1e5)
            projection()
            children(0);
        }
    }
    if (e == 0) children(0);
}

module bottomFillet(b = 0, r = 1, s = 4, e = 1) {
    if (e == 1) {
        bottomFilletPeice(b = b, r = r, s = s) children(0);
       
        render()
        difference() {
            children(0);
            translate([0, 0, b -  1])
            linear_extrude(r + 1)
            offset(delta = 1e5)
            projection()
            children(0);
        }
    }
    if (e == 0) children(0);
}

module topFilletPeice(t = 2, r = 1, s = 4) {
    d = r/s;
       
    for (i = [0:s]) {
        x = filletDepth(r, d, i);
        z = d * (s - i + 1);                 
        translate([0, 0, t - z])
        linear_extrude(d)
        offset(delta = -r + x)
        projection(true)
        translate([0, 0, -t + z])
        children(0);
    }
}

module bottomFilletPeice(b = 0, r =1, s = 4) {
    d = r/s;
       
    for (i = [0:s]) {
        x = filletDepth(r, d, i);
        z = d * (s - i);
        translate([0, 0, b + z])
        linear_extrude(d)
        offset(delta = -r + x)
        projection(true)
        translate([0, 0, b - z])
        children(0);
    }
}

10
This is not what i wanted to show, since it does not work in angel cad, but does very slowly in openscad, but I had to comment out the fillet, I gave up waiting. There are a number of near misses with curves. If you've not got nophead'  library, then even if you comment out the 'male_metric_thread' line, it still won't work in angelcad, but it did more or less yesterday, iirc, because I experimented with the secant_tolerance values, smoothing out the curves.

Code: [Select]
//twist nut 8mm blank
include<NopSCADlib/utils/thread.scad>
include<rw/fillets3d.scad>

//module male_metric_thread(d, pitch, length, center = true, top = -1, bot = -1, solid = true, colour = undef) { //! Create male thread with metric profile example for variable names


//bottomFillet(b=0,r=1.5,s=8,e=enable)
translate([0,0,10])
difference(){
    union(){
      translate ([0,0, 5])  sphere( 12);
  scale([1.5,1,1])translate ([0,0,-5])  rotate ([90,0,0]) cylinder(h=3,d=15,center=true);
  cylinder (h=20,d=16,center=true);
  //  translate([0,0,10])cylinder (h=3,d=13);
    }
male_metric_thread(8,1.25,21);
 translate([0,0,-2])rotate([0,6,0])cylinder (h=21,d=8.2,center=true);   
   
  translate([0,0,-60])  cube([100,100,100],true); //chop off bottom
   
   
}


$fn=80;
//topBottomFillet(b = 0, t = 10, r = 1, s = 10, e = enable)

11
This runs considerably faster than rendering within openscad, seconds instead of many minutes in the few tests I've done. Would it be possible to parse the openscad script, and extract the $fn=80; (or similar values) and prefill the 'args' with a suitable value for secant_tolerance?

13
General Discussion / Re: Threads - ISO
« on: 2020-09-13, 14:15:35 »
Hi Carsten,
The line in my code ' @mynut= mynut -translate(14,11,0)* cylinder(50,4); //this line'
is from before I used your threading code, I was simply 'drilling' a plain hole, and tapping it when printed. I was thinking it should not be required, as I thought your code removed the core of the thread, but if that line is altered too much, or removed, then the script does not work, It also fails if the depth of countersink (the h values in the cones) is altered or the secant_tolerance value. It becomes a bit of a juggling act. It just happened that my original 12.2 od was OK, but 12.0 od  is not.

So, if you change the value for the diameter of the cylinder in ' //this line' e.g. to 5.35,  (10.7mm being  the tapping drill size for 12mm bolt), it looks OK, change to 5.355 it throws an exception, and I get other errors by altering that value. Comment out that line, then  sometimes it completes OK, sometimes a blank screen, sometimes an image with red. It seems to be almost random behavior.

This type of  problem seems to be getting quite common with what I am doing, and seem to be not too repeatable. If you do not get this happening then either, my installation is faulty, I have pc memory problems, or your version/setup is different than mine.

14
General Discussion / Threads - ISO
« on: 2020-09-12, 15:34:18 »
I've been recently printing using pet-g. I find it has good mechanical properties for what I want, or at least better than abs or pla. It can be ground, filed and machined, without too many problems. I was thinking of using it for jigs and fixtures, clamps, etc, and was wondering about trying some rule of thumb tests. I designed a T nut, with a 12mm thread. Knowing that holes came out undersize, I changed the od to 12.2, it printed, but still a bit tight on the 12mm stud, so I ran a tap down through. I think the fit could be improved by using a 12mm od thread, as it should be, but I found it would not accept exactly 12mm. I based the code on Carsten's example. Here's my code. the '//this line' comment, was left from when I was originally going to tap a plain hole, but if it is removed, or changed to the root diameter, the code fails. I think, because of the countersinks interacting with the thread ends, it causes confusion in the rendering, changing the secant_tolerance dramatically effects the result.

Code: [Select]
// AngelCAD code.


double to_rad(double deg) { return PI*deg/180.0; } // from degrees to radians


   
   shape2d@ ISO_thread(double Dmaj, double pitch)
{
   double P = pitch;
   // basic thread profile https://en.wikipedia.org/wiki/ISO_metric_screw_thread
   double H = P*cos(to_rad(30));
   double delta = 0.01*P;

   // establish coordinates in profile
   double x1 = delta;;
   double x2 = P/8;
   double x3 = P/2 - P/16;
   double x4 = P/2 + P/16;
   double x5 = P - P/8;
   double x6 = P - delta;

   double y1 = 0;
   double y2 = H/4 - P/16;
   double y3 = H/4;
   double y4 = H - H/8;

   // build the thread profile, points CCW
   pos2d@[] points = { pos2d(x1,y1),  // p0
                       pos2d(x6,y1),  // p1
                       pos2d(x6,y2),  // p2
                       pos2d(x5,y3),  // p3
                       pos2d(x4,y4),  // p4
                       pos2d(x3,y4),  // p5
                       pos2d(x2,y3),  // p6
                       pos2d(x1,y2)   // p7
                     };
   shape2d@ profile = polygon(points);

   // put the profile in place, ready for rotation around Y
   @profile = translate(0.5*Dmaj-H+H/8,P/2)*rotate_z(deg:-90)*profile;

   return profile;
}
   
   
   solid@ ISO_screw(double Dmaj, double pitch)
{
   // EXPERIMENTAL: non-zero pitch and multiple revolutions
   // rotate profile around Y, 13 revolutions, then make it upright
   double revs = 15;
   shape2d@ thread_profile = ISO_thread(Dmaj:Dmaj,pitch:pitch);
   solid@ threads = translate(0,0,pitch*revs)*rotate_x(deg:90)*rotate_extrude(thread_profile,deg:360*revs,pitch:-pitch);

   //make a cylinder inside the threads, then cut the ends by intersecting with a large diameter cylinder

   double H = pitch*cos(to_rad(30));
   double Dmin = Dmaj + 2*(H/8 - H + 0.8*H/4);
   double Rmin = 0.5*Dmin;
   solid@ rod  = cylinder(r:Rmin,h:pitch*revs);
   solid@ screw = intersection3d(union3d(rod,threads),translate(0,0,0.5*pitch)*cylinder(h:pitch*revs*0.9,r:100));

   solid@ cutter = cone(h:pitch*revs*1.3,r1:Dmaj*1.35,r2:1);
   return translate(0,0,-5)*intersection3d(screw,cutter);
}


 
shape@ main_shape()
{
   // t nut with 10mm hole
   solid@ mynut = cuboid(28,22,8);
   @mynut = mynut + translate (0,4,0)*cuboid(28,14,15);
   // hole
   @mynut= mynut -translate(14,11,0)* cylinder(50,4); //this line
   solid@ bolt = ISO_screw(12.05,1.75) ;
  // add countersinks
   solid@ cs = translate(14,11,4)*cone (17.3,0,10);
   solid@ uc =  translate(14,11,-6.3)*cone(17.3,10,0);
   return mynut- translate( 14,11,0)* bolt -cs - uc;
   }
   

 void main()
{
   shape@ obj = main_shape();
   obj.write_xcsg(GetInputFullPath(),secant_tolerance:0.05);
}

15
General Discussion / Re: console mesages
« on: 2020-09-09, 16:08:14 »
I've not heard of polyfix, but will try it. Anyway, I found the problem area, and resolved it, but not before I'd produced a print that fell apart when I lifted it from the print bed. (It looked OK in the slicer.)
Code: [Select]
// AngelCAD code.

// makes a spoked handwheel

double bore =8.2;// bore
double shaft=20;//shaft od
double shaftlen=40;//shaft length
double borelen=25;//bore length
double rimod=50;// rim od
double rimid=38;//rim id
double rimthick=8;// rim thickness
double spokes=5;//no of spokes
double fixloc=8;//fix location from boss end
double fixdiam=2;//fix diam
double grips=12;//number of grips
double round =3.5;// diameter of fillet


solid@ rim(double h,double d2,double d1, double rc)
{
// get tube
  solid@ arim= cylinder (h,d2/2) - cylinder(h,d1/2);
//fillet inside
 return arim;
}


solid@ aspoke(double t,double d, double n, double ch)
// get spoke
{
   double thick = (t-ch)*0.5; //spoke width
// make quarter spoke with rounded edge
// use offset, radius ch/2 of square for profile, then extrude
    solid@ spr= linear_extrude(offset2d(square(thick),r:ch/2),(d+(t))/2);
    solid@ spk = translate(0,-(thick/2),thick+ch/2)*rotate_y(90)*spr;
// rotate and add spokes
     array <solid@> total;
     for (int j=1;j<n+1;j++)
     {
        solid@ rotsp = rotate_z(j*360/n)* spk;
        total.push_back(rotsp);
     }
     return union3d(total);
}
 
 solid@ grip(double t,double d, double n)
// puts n balls on circle of diameter d. ball diameter is t
{
  array <solid@> balls;
 
 for (int j=1;j<=n;j++)
   {
    solid@ rotb = rotate_z(j*360/n)*translate(d/2,0,t/2)*sphere((t)*0.8/2);
    balls.push_back(rotb);
   }
   return union3d(balls);
}
 
  shape2d@ corner_poly(double filletdiam,double bigdiameter)
 {
 // generates polygon for rounding corners of tubes
     double  r= filletdiam/2;
     double br= bigdiameter/2;
     shape2d@  block = square(2*r);
     @block = block - translate(0,2*r)*circle(r);
     @block = block - translate(0,0)*circle(r);
     @block = block - translate(2*r,0)*circle(r);
     @block = block - translate(2*r,2*r)*circle(r);
     return translate(br,0)*translate(-r,-r)*block;
     return block;
 }
 
 
 solid@ round_over(double filletdiam, double circlediam)
 {// makes the profile to be subtracted from square ends
    shape2d@ poly = corner_poly(filletdiam,circlediam);
    solid@ curv = rotate_extrude(poly,360,0);
    @curv = rotate_x(90)*translate(0,filletdiam,0)*curv ;
    return translate(0,0,-filletdiam)*curv;
 }
 

 
 solid@ rwboss(double sl,double sd,double bl, double bo,double fixl, double fixd, double ch)
 // calc centre boss with fix hole
{
   solid@ shf=cylinder(sl,sd/2)-translate(0,0, sl-bl)*cylinder( bl, bo/2);
 //fixing  hole
    solid@ fix = rotate_y(90)*cylinder(sd*8,fixd/2);
    return shf  - translate(-sd*3,0,sl-fixl)*fix ;
 

   
shape@ main_shape()
{
  solid@ os=rim(rimthick,rimod,rimid, round);
  solid@ gripper =translate(0,0,0)*grip(rimthick,rimod,grips); 
  // fillet bottom of rim
  @os=os + gripper;
  @os = os - round_over(round,rimod);
  @os = os - round_over(round,rimid);
 
  //fillet top of rim
  @os = os - translate(0,0,rimthick)*round_over(round,rimod);;
  @os = os - translate(0,0,rimthick)*round_over(round,rimid);;
  @os=os + gripper;
// get shaft
   solid@ shft = rwboss(shaftlen,shaft, borelen,bore,fixloc,fixdiam,round);
   @shft= shft -round_over(round,shaft);
// bigger radius at shaft end   
   @shft = shft - translate(0,0,shaftlen)* round_over(round*2,shaft);
// get spokes
  solid@ spk = aspoke(rimthick,rimid,spokes,round);
 
 return os + spk + shft ;
 
}

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

The above code works. Previous version  problem was caused by the gripper balls diameter, and the order the handwheel was assembled. If the spheres were big, they did not merge properly with the rounded edge of the rim, and although everything looked fine in meshlab, and on the slicer, it looked good enough to print, but the object was not watertight. The spheres need to be less than the flat area of the rim to be certain it builds correctly, but in some situations they can be a bit larger. I'm pretty sure there are other combinations that fail, too.

Pages: [1] 2 3