jbuckmccready / CavalierContours

2D polyline library for offsetting, combining, etc.
MIT License
417 stars 78 forks source link

bulge factor #17

Closed grotius-cnc closed 4 years ago

grotius-cnc commented 4 years ago

Thank you for your excellent work !

I have a little issue going on.

Why must the bulge factor between -1 and 1? I have arc's with higher bulge value's. This higher or lower value occur's when the arc center goes inside the arc segment.

This is the terminal output of your script : bulge should always be between -1 and 1"' failed.

In some cases an arc has a bulge factor of 7 or -7. See this example : http://people.fsv.cvut.cz/www/chourpav/Lisp/Chapter%2011.htm , and then figure 11.5

So far, i think i am correct. please correct me if this is not the case.

Can you provide a example how to calculate the bulge factor for an arc of 270 degrees with a output between -1 and 1? Thank you !

Another tiny thing to consider : island.addVertex(it3->x, it3->y, 0); Can you provide a : islands.clear(); to empty the vector?

This is my output so far. https://forum.linuxcnc.org/media/kunena/attachments/23278/cadcam_pocket_with_islands1.png

grotius-cnc commented 4 years ago

Hi, I got a solution to increase the input values for a bulge higher then 1 and lower then -1. If the arc value passed bulge value 1 or lower then -1, then we split up the arc's in two arcs. 2 arc's. The output is perfect !

For your code, you could integrate a preprocess function like this:

std::vector arc_bulge(std::vector::iterator it){

//https://github.com/jbuckmccready/CavalierContours/issues/17

//bulge neg=g2
//bulge pos=g3
double pi_angle_arc=0;
double pi_angle_start=0;
double pi_angle_end=0;
std::vector<double> bulge; //bulge[0]=bulge value, bulge[1]=0 (one arc), bulge[1]=1 (two arcs)
double r=it->radius;
POINT a=it->start;
POINT b=it->end;
POINT c=it->center;

if(it->d>0){ //g2, d=determinant
    pi_angle_start = atan2(b.y-c.y, b.x-c.x);
    pi_angle_end = atan2(a.y-c.y, a.x-c.x);
}
if(it->d<0){ //g3
    pi_angle_start = atan2(a.y-c.y, a.x-c.x);
    pi_angle_end  = atan2(b.y-c.y, b.x-c.x);
}
if(it->d==0){
    bulge.push_back(0); //draw straight line
    bulge.push_back(0);
}

if(pi_angle_end<pi_angle_start){pi_angle_end+=2*M_PI;}
pi_angle_arc=pi_angle_end-pi_angle_start;

if(pi_angle_arc>M_PI){ //split up in 2 arcs
    double half_pi_angle_arc=pi_angle_arc/2;
    double bulges=tan(half_pi_angle_arc/4);
    if(it->d<0){
        bulge.push_back(abs(bulges));
        bulge.push_back(1);
    }
    if(it->d>0){
        bulge.push_back(-abs(bulges));
        bulge.push_back(1);
    }

} else {
    if(it->d<0){
        bulge.push_back(abs(tan(pi_angle_arc/4))); //keep it as 1 arc
        bulge.push_back(0);
    }
    if(it->d>0){
        bulge.push_back(-abs(tan(pi_angle_arc/4))); //keep it as 1 arc
        bulge.push_back(0);
    }
}

return bulge;

}

Thank you !

The preview output : https://pasteboard.co/JgHxPRB.png

jbuckmccready commented 4 years ago

@grotius-cnc Thanks for the input, see issue #9 on the bulge greater than 1.

This issue has come up multiple times so I will look into adding a utility function for splitting the arcs, similar to what you posted above.

As for adding a clear method, I'll look into adding that as well, for now you can just call the vector clear method, e.g. polyline.vertexes().clear() (vertexes() just returns a reference to a std::vector).

grotius-cnc commented 4 years ago

Thank you,

I got a cadcam program in development, here you have a wetransfer link: https://we.tl/t-rON0PElPpB

Currently it can open inkscape, librecad and freecad dxf drawings and can do contour recognize, your code is in the program, just take a look.

I think its more usefull then qtquick.

Plus it has no Qt dependenies. So you can port it to a other platform without much work.

It has also true spline, bezier, ellipse, polygon, arc and line primitives that work with your algoritme.

In previous cadcam program attempts i did much of the cad workout. So i have to stitch it all together, and get something better then sheetcam hopely, and open source, cross platform.

You have done great work so far !

Up to the nesting algoritme. Have a nice day !

A printed circuit output with your algoritme with perfect output :

https://forum.linuxcnc.org/media/kunena/attachments/23278/printed_circuit_contour_offset.png

jbuckmccready commented 4 years ago

@grotius-cnc That's awesome! Do you mind creating a github, gitlab, or some other hosted git repo for your cadcam project that I could browse online?

grotius-cnc commented 4 years ago

Hi,

The output of your algoritme is very good !

When we test huge dxf data input for your algoritme, is easy to put in one contour each time to produce the output more stepwise.

i just uploaded and tested the project for you : https://github.com/grotius-cnc/CadCam_pockets Let me know how you think about it.