bool BullCutter::generalEdgePush(const Fiber& f, Interval& i,  const Point& p1, const Point& p2) const {
    //std::cout << " BullCutter::generalEdgePush() \n";
    bool result = false;
    
    if ( isZero_tol( (p2-p1).xyNorm() ) ) { // this would be a vertical edge
        return result;
    }
    
    if ( isZero_tol( p2.z-p1.z ) ) // this would be a horizontal edge
        return result;
    assert( fabs(p2.z-p1.z) > 0.0 ); // no horiz edges allowed hereafter
    
    // p1+t*(p2-p1) = f.p1.z+radius2   =>  
    double tplane = (f.p1.z + radius2 - p1.z ) / (p2.z-p1.z); // intersect edge with plane at z = ufp1.z
    Point ell_center = p1+tplane*(p2-p1);                               
    assert( isZero_tol( fabs(ell_center.z - (f.p1.z+radius2)) ) );
    Point major_dir = (p2-p1);     
    assert( major_dir.xyNorm() > 0.0 );               
    
    major_dir.z = 0;
    major_dir.xyNormalize();
    Point minor_dir = major_dir.xyPerp();
    double theta = atan( (p2.z - p1.z) / (p2-p1).xyNorm() ); 
    double major_length = fabs( radius2/sin(theta) ) ;
    double minor_length = radius2;
    AlignedEllipse e(ell_center, major_length, minor_length, radius1,  major_dir, minor_dir );
    if ( e.aligned_solver( f ) ) { // now we want the offset-ellipse point to lie on the fiber
        Point pseudo_cc  = e.ePoint1(); // pseudo cc-point on ellipse and cylinder
        Point pseudo_cc2 = e.ePoint2();
        CCPoint cc  = pseudo_cc.closestPoint(p1,p2);
        CCPoint cc2 = pseudo_cc2.closestPoint(p1,p2);
        cc.type  = EDGE_POS;
        cc2.type = EDGE_POS;
        Point cl  = e.oePoint1() - Point(0,0,center_height);            
        assert( isZero_tol( fabs(cl.z - f.p1.z)) );
        Point cl2 = e.oePoint2() - Point(0,0,center_height);            
        assert( isZero_tol( fabs(cl2.z - f.p1.z)) );
        double cl_t  = f.tval(cl);
        double cl_t2 = f.tval(cl2);
        if ( i.update_ifCCinEdgeAndTrue( cl_t, cc, p1, p2, true ) )
            result = true;
        if ( i.update_ifCCinEdgeAndTrue( cl_t2, cc2, p1, p2, true ) )
            result = true;
    }
    //std::cout << " BullCutter::generalEdgePush() DONE result= " << result << "\n";
    return result;
}
Exemple #2
0
bool MillingCutter::singleVertexPush(const Fiber& f, Interval& i, const Point& p, CCType cctyp) const {
    bool result = false;
    if ( ( p.z >= f.p1.z ) && ( p.z <= (f.p1.z+ this->getLength()) ) ) { // p.z is within cutter
        Point pq = p.xyClosestPoint(f.p1, f.p2); // closest point on fiber
        double q = (p-pq).xyNorm(); // distance in XY-plane from fiber to p
        double h = p.z - f.p1.z;
        assert( h>= 0.0);
        double cwidth = this->width( h );
        if ( q <= cwidth ) { // we are going to hit the vertex p
            double ofs = sqrt( square( cwidth ) - square(q) ); // distance along fiber 
            Point start = pq - ofs*f.dir;
            Point stop  = pq + ofs*f.dir;
            CCPoint cc_tmp( p, cctyp );
            i.updateUpper( f.tval(stop) , cc_tmp );
            i.updateLower( f.tval(start) , cc_tmp );
            result = true;                
        }             
    }
    return result;
}
Exemple #3
0
// cone is pushed along Fiber f into contact with edge p1-p2
bool ConeCutter::generalEdgePush(const Fiber& f, Interval& i,  const Point& p1, const Point& p2) const {
    bool result = false;
    
    if ( isZero_tol(p2.z-p1.z) ) // guard agains horizontal edge
        return result;
    assert( (p2.z-p1.z) != 0.0 );
    // idea: as the ITO-cone slides along the edge it will pierce a z-plane at the height of the fiber
    // the shaped of the pierced area is either a circle if the edge is steep
    // or a 'half-circle' + cone shape if the edge is shallow (ice-cream cone...)
    // we can now intersect this 2D shape with the fiber and get the CL-points.
    // how to get the CC-point? (point on edge closest to z-axis of cutter? closest to CL?)


    
    // this is where the ITO cone pierces the plane
    // edge-line: p1+t*(p2-p1) = zheight
    // => t = (zheight - p1)/ (p2-p1)  
    double t_tip = (f.p1.z - p1.z) / (p2.z-p1.z);
    if (t_tip < 0.0 )
        t_tip = 0.0;
    Point p_tip = p1 + t_tip*(p2-p1);
    assert( isZero_tol( abs(p_tip.z-f.p1.z) ) ); // p_tip should be in plane of fiber
    
    // this is where the ITO cone base exits the plane
    double t_base = (f.p1.z+center_height - p1.z) / (p2.z-p1.z);
    Point p_base = p1 + t_base*(p2-p1);
    p_base.z = f.p1.z; // project to plane of fiber
    //std::cout << "(t0, t1) (" << t0 << " , " << t1 << ") \n";
    double L = (p_base-p_tip).xyNorm(); 
    
    if ( L <= radius ) { // this is where the ITO-slice is a circle
        // find intersection points, if any, between the fiber and the circle
        // fiber is f.p1 - f.p2
        // circle is centered at p_base and radius
        double d = p_base.xyDistanceToLine(f.p1, f.p2);
        if ( d <= radius ) {
            // we know there is an intersection point.
            // http://mathworld.wolfram.com/Circle-LineIntersection.html
            
            // subtract circle center, math is for circle centered at (0,0)
            double dx = f.p2.x - f.p1.x;
            double dy = f.p2.y - f.p1.y;
            double dr = sqrt( square(dx) + square(dy) );
            double det = (f.p1.x-p_base.x) * (f.p2.y-p_base.y) - (f.p2.x-p_base.x) * (f.p1.y-p_base.y);
            
            // intersection given by:
            //  x = det*dy +/- sign(dy) * dx * sqrt( r^2 dr^2 - det^2 )   / dr^2
            //  y = -det*dx +/- abs(dy)  * sqrt( r^2 dr^2 - det^2 )   / dr^2
            
            double discr = square(radius) * square(dr) - square(det);
            assert( discr > 0.0 ); // this means we have an intersection
            if ( discr == 0.0 ) { // tangent case
                double x_tang =  ( det*dy  )/ square(dr);
                double y_tang = -( det*dx  )/ square(dr);
                Point p_tang(x_tang+p_base.x, y_tang+p_base.y); // translate back from (0,0) system!
                double t_tang = f.tval( p_tang );
                if ( circle_CC( t_tang, p1, p2, f, i) )
                    result = true;
            } else {
                // two intersection points
                double x_pos = (  det*dy + sign(dy)* dx * sqrt( discr ) ) / square(dr);
                double y_pos = ( -det*dx + abs(dy)  * sqrt( discr ) ) / square(dr); 
                Point p_pos(x_pos+p_base.x, y_pos+p_base.y);
                double t_pos = f.tval( p_pos );
                // the same with "-" sign:
                double x_neg = (  det*dy - sign(dy) * dx * sqrt( discr ) ) / square(dr);
                double y_neg = ( -det*dx - abs(dy)  * sqrt( discr ) ) / square(dr); 
                Point p_neg(x_neg+p_base.x, y_neg+p_base.y);
                double t_neg = f.tval( p_neg );
                if ( circle_CC( t_pos, p1, p2, f, i) ) 
                    result = true;
                if ( circle_CC( t_neg, p1, p2, f, i) ) 
                    result = true;
            }
        }
        return result;
    } else {
        // ITO-slice is cone + half-circle        
        // lines from p_tip to tangent points
        assert( L > radius );
        // http://mathworld.wolfram.com/CircleTangentLine.html
        // circle centered at x0, y0, radius a
        // tangent through (0,0)
        // t = +/- acos(  -a*x0 +/- y0*sqrt(x0^2+y0^2-a^2) / (x0^2+y0^2) )
        // translate so p_mid is at (0,0)
        //Point c = p_base - p_mid;
        //double cos1 = (-radius*c.x + c.y*sqrt(square(c.x)+square(c.y)+square(radius)) )/ (square(c.x) + square(c.y) );
        //double cos2 = (-radius*c.x - c.y*sqrt(square(c.x)+square(c.y)+square(radius)) )/ (square(c.x) + square(c.y) );
        
        
        return result;
    }
}