// general purpose facet-drop which calls xy_normal_length(), normal_length(), // and center_height() on the subclass bool MillingCutter::facetDrop(CLPoint &cl, const Triangle &t) const { // Drop cutter at (cl.x, cl.y) against facet of Triangle t Point normal = t.upNormal(); // facet surface normal if ( isZero_tol( normal.z ) ) // vertical surface return false; //can't drop against vertical surface assert( isPositive( normal.z ) ); if ( ( isZero_tol(normal.x) ) && ( isZero_tol(normal.y) ) ) { // horizontal plane special case CCPoint cc_tmp( cl.x, cl.y, t.p[0].z, FACET); return cl.liftZ_if_inFacet(cc_tmp.z, cc_tmp, t); } else { // general case // plane containing facet: a*x + b*y + c*z + d = 0, so // d = -a*x - b*y - c*z, where (a,b,c) = surface normal double d = - normal.dot(t.p[0]); normal.normalize(); // make length of normal == 1.0 Point xyNormal( normal.x, normal.y, 0.0); xyNormal.xyNormalize(); // define the radiusvector which points from the cc-point to the cutter-center Point radiusvector = this->xy_normal_length*xyNormal + this->normal_length*normal; CCPoint cc_tmp = cl - radiusvector; // NOTE xy-coords right, z-coord is not. cc_tmp.z = (1.0/normal.z)*(-d-normal.x*cc_tmp.x-normal.y*cc_tmp.y); // cc-point lies in the plane. cc_tmp.type = FACET; double tip_z = cc_tmp.z + radiusvector.z - this->center_height; return cl.liftZ_if_inFacet(tip_z, cc_tmp, t); } }
// because this checks for contact with both the tip and the circular edge it is hard to move to the base-class // we either hit the tip, when the slope of the plane is smaller than angle // or when the slope is steep, the circular edge between the cone and the cylindrical shaft bool ConeCutter::facetDrop(CLPoint &cl, const Triangle &t) const { bool result = false; Point normal = t.upNormal(); // facet surface normal if ( isZero_tol( normal.z ) ) // vertical surface return false; //can't drop against vertical surface if ( (isZero_tol(normal.x)) && (isZero_tol(normal.y)) ) { // horizontal plane special case CCPoint cc_tmp( cl.x, cl.y, t.p[0].z, FACET_TIP ); // so any vertex is at the correct height return cl.liftZ_if_inFacet(cc_tmp.z, cc_tmp, t); } else { // define plane containing facet // a*x + b*y + c*z + d = 0, so // d = -a*x - b*y - c*z, where (a,b,c) = surface normal double a = normal.x; double b = normal.y; double c = normal.z; double d = - normal.dot(t.p[0]); normal.xyNormalize(); // make xy length of normal == 1.0 // cylindrical contact point case // find the xy-coordinates of the cc-point CCPoint cyl_cc_tmp = cl - radius*normal; cyl_cc_tmp.z = (1.0/c)*(-d-a*cyl_cc_tmp.x-b*cyl_cc_tmp.y); double cyl_cl_z = cyl_cc_tmp.z - length; // tip positioned here cyl_cc_tmp.type = FACET_CYL; // tip contact with facet CCPoint tip_cc_tmp(cl.x,cl.y,0.0); tip_cc_tmp.z = (1.0/c)*(-d-a*tip_cc_tmp.x-b*tip_cc_tmp.y); double tip_cl_z = tip_cc_tmp.z; tip_cc_tmp.type = FACET_TIP; result = result || cl.liftZ_if_inFacet( tip_cl_z, tip_cc_tmp, t); result = result || cl.liftZ_if_inFacet( cyl_cl_z, cyl_cc_tmp, t); return result; } }