private void CalculatePoints() { // Unrotated tooth tip is on the X axis ToothTip = Involutes.CreatePt(PitchCircleDiameter / 2, 0); // Navigate down the slope of the tooth face FaceEnd = Involutes.CreatePt( PitchCircleDiameter / 2 - ToothFaceLength * Math.Cos(UndercutAngle), -ToothFaceLength * Math.Sin(UndercutAngle)); // Now find the centre of the undercut circle UnderCutCentre = Involutes.CreatePt (FaceEnd.X - CutDiameter * Math.Sin(UndercutAngle) / 2, FaceEnd.Y + CutDiameter * Math.Cos(UndercutAngle) / 2); // Find the coordinates of the back tip corner of // the next tooth in an anticlockwise direction BackTip = Involutes.CreatePt(ToothTip.X * Math.Cos(GapAngle), ToothTip.X * Math.Sin(GapAngle)); // Find the coordinates of the tangent to the // undercut circle of a line drawn from the // back of the tooth tip double tipToEndAngle = Math.Asin(CutDiameter / (2 * Involutes.DistanceBetween(BackTip, UnderCutCentre))); double tiptoCtrAngle = Math.Atan2(BackTip.Y - UnderCutCentre.Y, BackTip.X - UnderCutCentre.X); BackAngle = tiptoCtrAngle + Math.PI / 2 - tipToEndAngle; OneToothProfile = ComputeOnePitch(); }
private void CalculatePoints() { List <PointF> points = new List <PointF>(); double innerRadius = InnerDiameter / 2; double cutterRadius = CutDiameter / 2; // Calculate the cutter centre for the tooth // of the ratchet gear at the innermost end double m = -ToothDepth / (innerRadius * ToothAngle); double xs = Math.Sqrt(cutterRadius * cutterRadius / (1 + m * m)); double ys = m * xs; PointF cutterCentre = Involutes.CreatePt(innerRadius + xs, ys); // Find the start angle and the end angle for the curve. The curve starts // at the X axis and heads towards negative Y. The end angle is where the // curve becomes tangential to a radial from the centre of the ratchet. // If the cutter centre lies outside the pitch circle, then the ratchet // will not be able to have a tooth at right angles to the direction // of rotation, and the ratchet is able to skip teeth under high torque. // Nonetheless, we calculate the tooth shape and return a warning. double radiusOfCutterCentre = Involutes.DistanceBetween(PointF.Empty, cutterCentre); double cutterCentreAngle = Math.Asin(-ys / radiusOfCutterCentre); double tangentAngle = cutterCentreAngle + Math.Asin(cutterRadius / radiusOfCutterCentre); double endAngle = Math.PI - Math.Atan2(-ys, xs); double startAngle = 3 * Math.PI / 2 - tangentAngle; points.Add(Involutes.RotateAboutOrigin (-ToothAngle, PointAtAngle(ToothAngle - tangentAngle))); // Add the points for the cutter curve points.AddRange(Involutes.CirclePoints (endAngle, startAngle, Involutes.AngleStep, cutterRadius, cutterCentre) .Reverse()); // Check that the radius of the cutter was not too great to // provide a latch at right angles to the radial from the centre // of the ratchet. double actualInnerRadius = Involutes.DistanceBetween(PointF.Empty, cutterCentre) - cutterRadius; double actualOuterRadius = Involutes.DistanceBetween(PointF.Empty, points[0]); if (Involutes.DistanceBetween(PointF.Empty, points[1]) > actualOuterRadius) { Information += "Cutter diameter too great for locking ratchet. Setting it to zero.\r\n"; CutDiameter = 0; CalculatePoints(); return; } // Now add the slope for (double angle = 0; angle < ToothAngle - tangentAngle; angle += Involutes.AngleStep) { points.Add(PointAtAngle(angle)); } OneToothProfile = Involutes.LinearReduction(points, (float)MaxError); Information += $"Actual inner diameter: {2 * actualInnerRadius:N2}, " + $"actual outer diameter: {2 * actualOuterRadius:N2}\r\n"; }