Document derivation of the new value for MIN_STEP_CLIPPER

This commit is contained in:
David Kaufman
2025-12-25 23:41:16 -05:00
parent e642409981
commit 9f9ac6c0c2

View File

@@ -199,7 +199,51 @@ private:
void AddPathToProgress(TPaths& progressPaths, const Path pth, MotionType mt = MotionType::mtCutting);
void ApplyStockToLeave(Paths& inputPaths);
private: // constants for fine tuning
private:
// Derivation for MIN_STEP_CLIPPPER (MSC for short in this derivation):
// Diagram:
// - circle C1 from previous pass, radius R
// - circle C2 from current pass MSC away, horizontal
// - line Lprev from previous pass, step over x
// - line Llong from tool position through C1/Lprev intersection to C2
// - line L1 from previous tool position to C1/Lprev intersection
//
// Length of Llong = R + y, where y is the longest protrusion into the cut area
// When selecting MIN_STEP_CLIPPER, we need to ensure that the computed
// value for y > 1 when using stepover x equal to the size of the finishing
// pass. Finishing pass stepover is
// x = stepover/10
// x = 2 * R * stepoverFactor / 10 (Eq1).
//
// Construct right triangle with (R-x) of vertical radius from C1 and
// L1. Third length (horizontal) = a
// (R-x)^2 + a^2 = R^2
// a^2 = 2*R*x - x^2 (Eq2)
// a ~= sqrt(2*R*x) (Eq3; x<<R)
//
// Construct right traingle with (R-x) of vertical radius from C2 and (R-y)
// of Llong. Third length is MSC - a (horizontal).
// (MSC-a)^2 + (R-x)^2 = (R-y)^2
// MSC^2 - 2*a*MSC + a^2 + R^2 - 2*R*x + x^2 = R^2 - 2*R*y + y^2
// MSC^2 - 2*a*MSC + a^2 - 2*R*x + x^2 = -2*R*y + y^2
// MSC^2 - 2*MSC*sqrt(2*R*x) + (2*R*x - x^2) - 2*R*x + x^2 = - 2*R*y + y^2 (substitute Eq2, Eq3)
// MSC^2 - 2*MSC*sqrt(2*R*x) = - 2*R*y + y^2
// MSC^2 - 2*MSC*sqrt(2*R*(2*R*stepoverFactor/10)) = -2*R*y + y^2 (substitute Eq1)
// MSC^2 - 2*R*MSC*sqrt(2*stepoverFactor/5) = -2*R*y + y^2
// -2*R*MSC*sqrt(2*stepoverFactor/5) = -2*R*y (MSC << R, y << R)
// MSC*sqrt(2*stepoverFactor/5) = y
// MSC = y/sqrt(2*stepoverFactor/5) (Eq4)
//
// To ensure we don't evaluate a postive cut area as zero, we need y to
// measure > 1. The endpoints of y may be perturbed by up to sqrt(2)/2 each
// due to integer rounding, so the true value of y must be at least 1+sqrt(2) ~= 2.4.
// StepoverFactor may be as small as 1% = 0.01. Evaluating Eq4 with these values:
//
// MSC > 2.4/sqrt(2*.01/5)
// MSC > 38.
//
// Historically we have used MSC = 16. It might be convenient that MSC is
// many-times divisible by 2, so I have chosen 16*3 (>38) for its new value.
const double MIN_STEP_CLIPPER = 16.0 * 3;
const int MAX_ITERATIONS = 10;
const double AREA_ERROR_FACTOR = 0.05; /* how precise to match the cut area to optimal,