// test for intersection with the fiber and a tip-tang line // if there is an intersection in tip-tang, calculate the cc-point and update the interval //C++ TO C# CONVERTER WARNING: 'const' methods are not available in C#: //ORIGINAL LINE: bool cone_CC(const Point& tang, const Point& tip, const Point& base, const Point& p1, const Point& p2, const Fiber& f, Interval& i) const protected bool cone_CC(Point tang, Point tip, Point @base, Point p1, Point p2, Fiber f, Interval i) { double u = 0; double t = 0; if (GlobalMembers.xy_line_line_intersection(f.p1, f.p2, ref u, tang, tip, ref t)) { if ((t >= 0.0) && (t <= 1.0)) { CCPoint cc_tmp = new CCPoint(@base + t * (tip - @base)); cc_tmp.z_projectOntoEdge(p1, p2); cc_tmp.type = CCType.EDGE_CONE; return(i.update_ifCCinEdgeAndTrue(u, cc_tmp, p1, p2, (true))); } } return(false); }
// DROP-CUTTER /// drop cutter against edge p1-p2 at xy-distance d from cl /// translates to cl=(0,0) and rotates edge to be along x-axis /// for call to singleEdgeDropCanonical() // 1) translate the geometry so that in the XY plane cl = (0,0) // 2) rotate the p1-p2 edge so that a new edge u1-u2 lies along the x-axis // 3) call singleEdgeDropCanonical(), implemented in the sub-class. // this returns the x-coordinate of the CC point and cl.z // 4) rotate/translate back to the original geometry // 5) update cl.z if required and if CC lies within the edge // // The edge test can be done in a "dual" geometry. // instead of testing the original cutter against an infinitely thin edge // we can test a virtual CylCutter with radius VR against an infinite ER-radius cylinder around the edge. // This reduces to a 2D problem in the XY plane, where section of the ER-radius cylinder is an ellipse. // in the general case CL lies on an offset ellipse with offset OR. // The general cases only applies for BullCutter(R1,R2) where R1 is the shaft radius // and R2 is the corner radius. // For CylCutter and BallCutter there are simple analytic solutions and an offset ellipse approach is not required. // // The dual problem for each cutter type is: // // CylCutter(R): VR = R, ER = 0, OR=R (the z-position of VR is the same as for CylCutter) // BallCutter(R): VR = 0, ER = R, OR=0 (the z-position of VR is a distance R up from the tip of BallCutter) // BullCutter(R1,R2): VR=R1-R2, ER=R2, OR=R1-R2 (z-position of VR is a distance R2 up from the tip of BullCutter) // // cone: ??? (how is this an ellipse??) // // d is the distance from the p1-p2 line to cl, in the 2D XY plane //C++ TO C# CONVERTER WARNING: 'const' methods are not available in C#: //ORIGINAL LINE: bool singleEdgeDrop(CLPoint& cl, const Point& p1, const Point& p2, double d) const protected bool singleEdgeDrop(CLPoint cl, Point p1, Point p2, double d) { Point v = p2 - p1; // vector along edge, from p1 -> p2 Point vxy = new Point(v.x, v.y, 0.0); // XY projection vxy.xyNormalize(); // normalized XY edge vector // figure out u-coordinates of p1 and p2 (i.e. x-coord in the rotated system) Point sc = cl.xyClosestPoint(p1, p2); Debug.Assert(((cl - sc).xyNorm() - d) < 1E-6); // edge endpoints in the new coordinate system, in these coordinates, CL is at origo Point u1 = new Point((p1 - sc).dot(vxy), d, p1.z); // d, the distance to line, is the y-coord in the rotated system Point u2 = new Point((p2 - sc).dot(vxy), d, p2.z); Tuple <double, double> contact = this.singleEdgeDropCanonical(u1, u2); // the subclass handles this CCPoint cc_tmp = new CCPoint(sc + contact.Item1 * vxy, CCType.EDGE); // translate back into original coord-system cc_tmp.z_projectOntoEdge(p1, p2); // update cl.z if required, and the cc-point lies inside the p1-p2 edge. return(cl.liftZ_if_InsidePoints(contact.Item2, cc_tmp, p1, p2)); }