diff --git a/Marlin/src/feature/bedlevel/ubl/ubl_G29.cpp b/Marlin/src/feature/bedlevel/ubl/ubl_G29.cpp
index 72b67e65bd..fefc65756e 100644
--- a/Marlin/src/feature/bedlevel/ubl/ubl_G29.cpp
+++ b/Marlin/src/feature/bedlevel/ubl/ubl_G29.cpp
@@ -1387,17 +1387,8 @@
                   dx = (x_max - x_min) / (g29_grid_size - 1),
                   dy = (y_max - y_min) / (g29_grid_size - 1);
 
-      const vector_3 points[3] = {
-        #if ENABLED(HAS_FIXED_3POINT)
-          { PROBE_PT_1_X, PROBE_PT_1_Y, 0 },
-          { PROBE_PT_2_X, PROBE_PT_2_Y, 0 },
-          { PROBE_PT_3_X, PROBE_PT_3_Y, 0 }
-        #else
-          { x_min, y_min, 0 },
-          { x_max, y_min, 0 },
-          { (x_max - x_min) / 2, y_max, 0 }
-        #endif
-      };
+      xy_float_t points[3];
+      get_three_probe_points(points);
 
       float measured_z;
       bool abort_flag = false;
diff --git a/Marlin/src/gcode/bedlevel/abl/G29.cpp b/Marlin/src/gcode/bedlevel/abl/G29.cpp
index 6aa54b3d2d..00e8ab44d7 100644
--- a/Marlin/src/gcode/bedlevel/abl/G29.cpp
+++ b/Marlin/src/gcode/bedlevel/abl/G29.cpp
@@ -263,20 +263,8 @@ G29_TYPE GcodeSuite::G29() {
       int constexpr abl_points = 3; // used to show total points
     #endif
 
-    // Probe at 3 arbitrary points
-    const float x_min = probe_min_x(), x_max = probe_max_x(), y_min = probe_min_y(), y_max = probe_max_y();
-
-    ABL_VAR vector_3 points[3] = {
-      #if ENABLED(HAS_FIXED_3POINT)
-        { PROBE_PT_1_X, PROBE_PT_1_Y, 0 },
-        { PROBE_PT_2_X, PROBE_PT_2_Y, 0 },
-        { PROBE_PT_3_X, PROBE_PT_3_Y, 0 }
-      #else
-        { x_min, y_min, 0 },
-        { x_max, y_min, 0 },
-        { (x_max - x_min) / 2, y_max, 0 }
-      #endif
-    };
+    vector_3 points[3];
+    get_three_probe_points(points);
 
   #endif // AUTO_BED_LEVELING_3POINT
 
@@ -764,7 +752,7 @@ G29_TYPE GcodeSuite::G29() {
       for (uint8_t i = 0; i < 3; ++i) {
         if (verbose_level) SERIAL_ECHOLNPAIR("Probing point ", int(i), "/3.");
         #if HAS_DISPLAY
-          ui.status_printf_P(0, PSTR(S_FMT" %i/3"), GET_TEXT(MSG_PROBING_MESH)), int(i);
+          ui.status_printf_P(0, PSTR(S_FMT" %i/3"), GET_TEXT(MSG_PROBING_MESH), int(i));
         #endif
 
         // Retain the last probe position
diff --git a/Marlin/src/gcode/calibrate/G33.cpp b/Marlin/src/gcode/calibrate/G33.cpp
index f961302fb5..1931d226af 100644
--- a/Marlin/src/gcode/calibrate/G33.cpp
+++ b/Marlin/src/gcode/calibrate/G33.cpp
@@ -190,7 +190,7 @@ static float std_dev_points(float z_pt[NPP + 1], const bool _0p_cal, const bool
  */
 static float calibration_probe(const xy_pos_t &xy, const bool stow) {
   #if HAS_BED_PROBE
-    return probe_at_point(xy, stow ? PROBE_PT_STOW : PROBE_PT_RAISE, 0, false);
+    return probe_at_point(xy, stow ? PROBE_PT_STOW : PROBE_PT_RAISE, 0, true);
   #else
     UNUSED(stow);
     return lcd_probe_pt(xy);
@@ -222,6 +222,8 @@ static bool probe_calibration_points(float z_pt[NPP + 1], const int8_t probe_poi
 
   if (!_0p_calibration) {
 
+    const float dcr = delta_calibration_radius();
+
     if (!_7p_no_intermediates && !_7p_4_intermediates && !_7p_11_intermediates) { // probe the center
       const xy_pos_t center{0};
       z_pt[CEN] += calibration_probe(center, stow_after_each);
@@ -233,7 +235,7 @@ static bool probe_calibration_points(float z_pt[NPP + 1], const int8_t probe_poi
                   steps  = _7p_9_center ? _4P_STEP / 3.0f : _7p_6_center ? _7P_STEP : _4P_STEP;
       I_LOOP_CAL_PT(rad, start, steps) {
         const float a = RADIANS(210 + (360 / NPP) *  (rad - 1)),
-                    r = delta_calibration_radius * 0.1;
+                    r = dcr * 0.1;
         const xy_pos_t vec = { cos(a), sin(a) };
         z_pt[CEN] += calibration_probe(vec * r, stow_after_each);
         if (isnan(z_pt[CEN])) return false;
@@ -257,7 +259,7 @@ static bool probe_calibration_points(float z_pt[NPP + 1], const int8_t probe_poi
         const int8_t offset = _7p_9_center ? 2 : 0;
         for (int8_t circle = 0; circle <= offset; circle++) {
           const float a = RADIANS(210 + (360 / NPP) *  (rad - 1)),
-                      r = delta_calibration_radius * (1 - 0.1 * (zig_zag ? offset - circle : circle)),
+                      r = dcr * (1 - 0.1 * (zig_zag ? offset - circle : circle)),
                       interpol = FMOD(rad, 1);
           const xy_pos_t vec = { cos(a), sin(a) };
           const float z_temp = calibration_probe(vec * r, stow_after_each);
@@ -287,9 +289,10 @@ static bool probe_calibration_points(float z_pt[NPP + 1], const int8_t probe_poi
 static void reverse_kinematics_probe_points(float z_pt[NPP + 1], abc_float_t mm_at_pt_axis[NPP + 1]) {
   xyz_pos_t pos{0};
 
+  const float dcr = delta_calibration_radius();
   LOOP_CAL_ALL(rad) {
     const float a = RADIANS(210 + (360 / NPP) *  (rad - 1)),
-                r = (rad == CEN ? 0.0f : delta_calibration_radius);
+                r = (rad == CEN ? 0.0f : dcr);
     pos.set(cos(a) * r, sin(a) * r, z_pt[rad]);
     inverse_kinematics(pos);
     mm_at_pt_axis[rad] = delta;
@@ -297,7 +300,7 @@ static void reverse_kinematics_probe_points(float z_pt[NPP + 1], abc_float_t mm_
 }
 
 static void forward_kinematics_probe_points(abc_float_t mm_at_pt_axis[NPP + 1], float z_pt[NPP + 1]) {
-  const float r_quot = delta_calibration_radius / delta_radius;
+  const float r_quot = delta_calibration_radius() / delta_radius;
 
   #define ZPP(N,I,A) (((1.0f + r_quot * (N)) / 3.0f) * mm_at_pt_axis[I].A)
   #define Z00(I, A) ZPP( 0, I, A)
@@ -338,7 +341,7 @@ static void calc_kinematics_diff_probe_points(float z_pt[NPP + 1], abc_float_t d
 }
 
 static float auto_tune_h() {
-  const float r_quot = delta_calibration_radius / delta_radius;
+  const float r_quot = delta_calibration_radius() / delta_radius;
   return RECIPROCAL(r_quot / (2.0f / 3.0f));  // (2/3)/CR
 }
 
@@ -450,12 +453,13 @@ void GcodeSuite::G33() {
 
   SERIAL_ECHOLNPGM("G33 Auto Calibrate");
 
+  const float dcr = delta_calibration_radius();
+
   if (!_1p_calibration && !_0p_calibration) { // test if the outer radius is reachable
     LOOP_CAL_RAD(axis) {
-      const float a = RADIANS(210 + (360 / NPP) *  (axis - 1)),
-                  r = delta_calibration_radius;
-      if (!position_is_reachable(cos(a) * r, sin(a) * r)) {
-        SERIAL_ECHOLNPGM("?(M665 B)ed radius implausible.");
+      const float a = RADIANS(210 + (360 / NPP) *  (axis - 1));
+      if (!position_is_reachable(cos(a) * dcr, sin(a) * dcr)) {
+        SERIAL_ECHOLNPGM("?Bed calibration radius implausible.");
         return;
       }
     }
@@ -522,12 +526,11 @@ void GcodeSuite::G33() {
       #define Z0(I) ZP(0, I)
 
       // calculate factors
-      const float cr_old = delta_calibration_radius;
-      if (_7p_9_center) delta_calibration_radius *= 0.9f;
+      if (_7p_9_center) calibration_radius_factor = 0.9f;
       h_factor = auto_tune_h();
       r_factor = auto_tune_r();
       a_factor = auto_tune_a();
-      delta_calibration_radius = cr_old;
+      calibration_radius_factor = 1.0f;
 
       switch (probe_points) {
         case 0:
diff --git a/Marlin/src/gcode/calibrate/M665.cpp b/Marlin/src/gcode/calibrate/M665.cpp
index 1b37fa8bb6..6234265b3d 100644
--- a/Marlin/src/gcode/calibrate/M665.cpp
+++ b/Marlin/src/gcode/calibrate/M665.cpp
@@ -37,7 +37,6 @@
    *    L = diagonal rod
    *    R = delta radius
    *    S = segments per second
-   *    B = delta calibration radius
    *    X = Alpha (Tower 1) angle trim
    *    Y = Beta (Tower 2) angle trim
    *    Z = Gamma (Tower 3) angle trim
@@ -47,7 +46,6 @@
     if (parser.seen('L')) delta_diagonal_rod        = parser.value_linear_units();
     if (parser.seen('R')) delta_radius              = parser.value_linear_units();
     if (parser.seen('S')) delta_segments_per_second = parser.value_float();
-    if (parser.seen('B')) delta_calibration_radius  = parser.value_float();
     if (parser.seen('X')) delta_tower_angle_trim.a  = parser.value_float();
     if (parser.seen('Y')) delta_tower_angle_trim.b  = parser.value_float();
     if (parser.seen('Z')) delta_tower_angle_trim.c  = parser.value_float();
diff --git a/Marlin/src/inc/Conditionals_post.h b/Marlin/src/inc/Conditionals_post.h
index df728ab07a..4b1ad8a9d0 100644
--- a/Marlin/src/inc/Conditionals_post.h
+++ b/Marlin/src/inc/Conditionals_post.h
@@ -132,10 +132,12 @@
 
 /**
  * SCARA cannot use SLOWDOWN and requires QUICKHOME
+ * Printable radius assumes joints can fully extend
  */
 #if IS_SCARA
   #undef SLOWDOWN
   #define QUICK_HOME
+  #define SCARA_PRINTABLE_RADIUS (SCARA_LINKAGE_1 + SCARA_LINKAGE_2)
 #endif
 
 /**
@@ -1434,6 +1436,7 @@
 #define PLANNER_LEVELING      (HAS_LEVELING && DISABLED(AUTO_BED_LEVELING_UBL))
 #define HAS_PROBING_PROCEDURE (HAS_ABL_OR_UBL || ENABLED(Z_MIN_PROBE_REPEATABILITY_TEST))
 #define HAS_POSITION_MODIFIERS (ENABLED(FWRETRACT) || HAS_LEVELING || ENABLED(SKEW_CORRECTION))
+#define NEEDS_THREE_PROBE_POINTS EITHER(AUTO_BED_LEVELING_UBL, AUTO_BED_LEVELING_3POINT)
 
 #if ENABLED(AUTO_BED_LEVELING_UBL)
   #undef LCD_BED_LEVELING
@@ -1470,37 +1473,37 @@
 #endif
 
 /**
- * Bed Probing rectangular bounds
- * These can be further constrained in code for Delta and SCARA
+ * Bed Probing bounds
  */
+
 #ifndef MIN_PROBE_EDGE
   #define MIN_PROBE_EDGE 0
 #endif
-#ifndef MIN_PROBE_EDGE_LEFT
-  #define MIN_PROBE_EDGE_LEFT MIN_PROBE_EDGE
-#endif
-#ifndef MIN_PROBE_EDGE_RIGHT
-  #define MIN_PROBE_EDGE_RIGHT MIN_PROBE_EDGE
-#endif
-#ifndef MIN_PROBE_EDGE_FRONT
-  #define MIN_PROBE_EDGE_FRONT MIN_PROBE_EDGE
-#endif
-#ifndef MIN_PROBE_EDGE_BACK
-  #define MIN_PROBE_EDGE_BACK MIN_PROBE_EDGE
+
+#if IS_KINEMATIC
+  #undef MIN_PROBE_EDGE_LEFT
+  #undef MIN_PROBE_EDGE_RIGHT
+  #undef MIN_PROBE_EDGE_FRONT
+  #undef MIN_PROBE_EDGE_BACK
+#else
+  #ifndef MIN_PROBE_EDGE_LEFT
+    #define MIN_PROBE_EDGE_LEFT MIN_PROBE_EDGE
+  #endif
+  #ifndef MIN_PROBE_EDGE_RIGHT
+    #define MIN_PROBE_EDGE_RIGHT MIN_PROBE_EDGE
+  #endif
+  #ifndef MIN_PROBE_EDGE_FRONT
+    #define MIN_PROBE_EDGE_FRONT MIN_PROBE_EDGE
+  #endif
+  #ifndef MIN_PROBE_EDGE_BACK
+    #define MIN_PROBE_EDGE_BACK MIN_PROBE_EDGE
+  #endif
 #endif
 
 #if ENABLED(DELTA)
   /**
    * Delta radius/rod trimmers/angle trimmers
    */
-  #define _PROBE_RADIUS (DELTA_PRINTABLE_RADIUS - (MIN_PROBE_EDGE))
-  #ifndef DELTA_CALIBRATION_RADIUS
-    #if HAS_BED_PROBE
-      #define DELTA_CALIBRATION_RADIUS (DELTA_PRINTABLE_RADIUS - _MAX(ABS(probe_offset.x), ABS(probe_offset.y), ABS(MIN_PROBE_EDGE)))
-    #else
-      #define DELTA_CALIBRATION_RADIUS _PROBE_RADIUS
-    #endif
-  #endif
   #ifndef DELTA_ENDSTOP_ADJ
     #define DELTA_ENDSTOP_ADJ { 0, 0, 0 }
   #endif
@@ -1513,24 +1516,6 @@
   #ifndef DELTA_DIAGONAL_ROD_TRIM_TOWER
     #define DELTA_DIAGONAL_ROD_TRIM_TOWER { 0, 0, 0 }
   #endif
-
-  // Probing points may be verified at compile time within the radius
-  // using static_assert(HYPOT2(X2-X1,Y2-Y1)<=sq(DELTA_PRINTABLE_RADIUS),"bad probe point!")
-  // so that may be added to SanityCheck.h in the future.
-  #define PROBE_X_MIN (X_CENTER - (_PROBE_RADIUS))
-  #define PROBE_Y_MIN (Y_CENTER - (_PROBE_RADIUS))
-  #define PROBE_X_MAX (X_CENTER + _PROBE_RADIUS)
-  #define PROBE_Y_MAX (Y_CENTER + _PROBE_RADIUS)
-
-#elif IS_SCARA
-
-  #define SCARA_PRINTABLE_RADIUS (SCARA_LINKAGE_1 + SCARA_LINKAGE_2)
-  #define _PROBE_RADIUS (SCARA_PRINTABLE_RADIUS - (MIN_PROBE_EDGE))
-  #define PROBE_X_MIN (X_CENTER - (SCARA_PRINTABLE_RADIUS) + MIN_PROBE_EDGE_LEFT)
-  #define PROBE_Y_MIN (Y_CENTER - (SCARA_PRINTABLE_RADIUS) + MIN_PROBE_EDGE_FRONT)
-  #define PROBE_X_MAX (X_CENTER +  SCARA_PRINTABLE_RADIUS - (MIN_PROBE_EDGE_RIGHT))
-  #define PROBE_Y_MAX (Y_CENTER +  SCARA_PRINTABLE_RADIUS - (MIN_PROBE_EDGE_BACK))
-
 #endif
 
 #if ENABLED(SEGMENT_LEVELED_MOVES) && !defined(LEVELED_SEGMENT_LENGTH)
@@ -1540,7 +1525,7 @@
 /**
  * Default mesh area is an area with an inset margin on the print area.
  */
-#if HAS_LEVELING
+#if EITHER(MESH_BED_LEVELING, AUTO_BED_LEVELING_UBL)
   #if IS_KINEMATIC
     // Probing points may be verified at compile time within the radius
     // using static_assert(HYPOT2(X2-X1,Y2-Y1)<=sq(DELTA_PRINTABLE_RADIUS),"bad probe point!")
@@ -1551,17 +1536,10 @@
     #define _MESH_MAX_Y (Y_MAX_BED - (MESH_INSET))
   #else
     // Boundaries for Cartesian probing based on set limits
-    #if ANY(MESH_BED_LEVELING, AUTO_BED_LEVELING_UBL, PROBE_MANUALLY)
-      #define _MESH_MIN_X (_MAX(X_MIN_BED + MESH_INSET, X_MIN_POS))  // UBL is careful not to probe off the bed.  It does not
-      #define _MESH_MIN_Y (_MAX(Y_MIN_BED + MESH_INSET, Y_MIN_POS))  // need NOZZLE_TO_PROBE_OFFSET in the mesh dimensions
-      #define _MESH_MAX_X (_MIN(X_MAX_BED - (MESH_INSET), X_MAX_POS))
-      #define _MESH_MAX_Y (_MIN(Y_MAX_BED - (MESH_INSET), Y_MAX_POS))
-    #else
-      #define _MESH_MIN_X (_MAX(X_MIN_BED + MESH_INSET, X_MIN_POS + probe_offset.x))
-      #define _MESH_MIN_Y (_MAX(Y_MIN_BED + MESH_INSET, Y_MIN_POS + probe_offset.y))
-      #define _MESH_MAX_X (_MIN(X_MAX_BED - (MESH_INSET), X_MAX_POS + probe_offset.x))
-      #define _MESH_MAX_Y (_MIN(Y_MAX_BED - (MESH_INSET), Y_MAX_POS + probe_offset.y))
-    #endif
+    #define _MESH_MIN_X (_MAX(X_MIN_BED + MESH_INSET, X_MIN_POS))  // UBL is careful not to probe off the bed.  It does not
+    #define _MESH_MIN_Y (_MAX(Y_MIN_BED + MESH_INSET, Y_MIN_POS))  // need NOZZLE_TO_PROBE_OFFSET in the mesh dimensions
+    #define _MESH_MAX_X (_MIN(X_MAX_BED - (MESH_INSET), X_MAX_POS))
+    #define _MESH_MAX_Y (_MIN(Y_MAX_BED - (MESH_INSET), Y_MAX_POS))
   #endif
 
   // These may be overridden in Configuration.h if a smaller area is desired
@@ -1577,40 +1555,17 @@
   #ifndef MESH_MAX_Y
     #define MESH_MAX_Y _MESH_MAX_Y
   #endif
-
-#endif // MESH_BED_LEVELING || AUTO_BED_LEVELING_UBL
+#else
+  #undef MESH_MIN_X
+  #undef MESH_MIN_Y
+  #undef MESH_MAX_X
+  #undef MESH_MAX_Y
+#endif
 
 #if (defined(PROBE_PT_1_X) && defined(PROBE_PT_2_X) && defined(PROBE_PT_3_X) && defined(PROBE_PT_1_Y) && defined(PROBE_PT_2_Y) && defined(PROBE_PT_3_Y))
   #define HAS_FIXED_3POINT
 #endif
 
-#if EITHER(AUTO_BED_LEVELING_UBL, AUTO_BED_LEVELING_3POINT) && IS_KINEMATIC
-    #define HAS_FIXED_3POINT
-    #define SIN0    0.0
-    #define SIN120  0.866025
-    #define SIN240 -0.866025
-    #define COS0    1.0
-    #define COS120 -0.5
-    #define COS240 -0.5
-    #ifndef PROBE_PT_1_X
-      #define PROBE_PT_1_X (X_CENTER + (_PROBE_RADIUS) * COS0)
-    #endif
-    #ifndef PROBE_PT_1_Y
-      #define PROBE_PT_1_Y (Y_CENTER + (_PROBE_RADIUS) * SIN0)
-    #endif
-    #ifndef PROBE_PT_2_X
-      #define PROBE_PT_2_X (X_CENTER + (_PROBE_RADIUS) * COS120)
-    #endif
-    #ifndef PROBE_PT_2_Y
-      #define PROBE_PT_2_Y (Y_CENTER + (_PROBE_RADIUS) * SIN120)
-    #endif
-    #ifndef PROBE_PT_3_X
-      #define PROBE_PT_3_X (X_CENTER + (_PROBE_RADIUS) * COS240)
-    #endif
-    #ifndef PROBE_PT_3_Y
-      #define PROBE_PT_3_Y (Y_CENTER + (_PROBE_RADIUS) * SIN240)
-    #endif
-#endif
 
 /**
  * Buzzer/Speaker
diff --git a/Marlin/src/inc/SanityCheck.h b/Marlin/src/inc/SanityCheck.h
index 4f53dd1332..91a9c3845c 100644
--- a/Marlin/src/inc/SanityCheck.h
+++ b/Marlin/src/inc/SanityCheck.h
@@ -245,6 +245,8 @@
   #error "NEOPIXEL_RGBW_LED is now NEOPIXEL_LED. Please update your configuration."
 #elif ENABLED(DELTA) && defined(DELTA_PROBEABLE_RADIUS)
   #error "Remove DELTA_PROBEABLE_RADIUS and use MIN_PROBE_EDGE to inset the probe area instead."
+#elif ENABLED(DELTA) && defined(DELTA_CALIBRATION_RADIUS)
+  #error "Remove DELTA_CALIBRATION_RADIUS and use MIN_PROBE_EDGE to inset the probe area instead."
 #elif defined(UBL_MESH_INSET)
   #error "UBL_MESH_INSET is now just MESH_INSET. Please update your configuration."
 #elif defined(UBL_MESH_MIN_X) || defined(UBL_MESH_MIN_Y) || defined(UBL_MESH_MAX_X) || defined(UBL_MESH_MAX_Y)
diff --git a/Marlin/src/lcd/menu/menu_delta_calibrate.cpp b/Marlin/src/lcd/menu/menu_delta_calibrate.cpp
index 5c742ef4f1..289730dd6f 100644
--- a/Marlin/src/lcd/menu/menu_delta_calibrate.cpp
+++ b/Marlin/src/lcd/menu/menu_delta_calibrate.cpp
@@ -85,7 +85,7 @@ void _man_probe_pt(const xy_pos_t &xy) {
 
   void _goto_tower_a(const float &a) {
     xy_pos_t tower_vec = { cos(RADIANS(a)), sin(RADIANS(a)) };
-    _man_probe_pt(tower_vec * delta_calibration_radius);
+    _man_probe_pt(tower_vec * delta_calibration_radius());
   }
   void _goto_tower_x() { _goto_tower_a(210); }
   void _goto_tower_y() { _goto_tower_a(330); }
diff --git a/Marlin/src/libs/vector_3.h b/Marlin/src/libs/vector_3.h
index fe95cfa85f..e065697f05 100644
--- a/Marlin/src/libs/vector_3.h
+++ b/Marlin/src/libs/vector_3.h
@@ -50,6 +50,7 @@ struct vector_3 : xyz_float_t {
   vector_3(const xy_float_t   &in) { set(in.x, in.y); }
   vector_3(const xyz_float_t  &in) { set(in.x, in.y, in.z); }
   vector_3(const xyze_float_t &in) { set(in.x, in.y, in.z); }
+  vector_3() { reset(); }
 
   // Factory method
   static vector_3 cross(const vector_3 &a, const vector_3 &b);
diff --git a/Marlin/src/module/configuration_store.cpp b/Marlin/src/module/configuration_store.cpp
index 84921d8b34..eef20f5f53 100644
--- a/Marlin/src/module/configuration_store.cpp
+++ b/Marlin/src/module/configuration_store.cpp
@@ -37,7 +37,7 @@
  */
 
 // Change EEPROM version if the structure changes
-#define EEPROM_VERSION "V71"
+#define EEPROM_VERSION "V72"
 #define EEPROM_OFFSET 100
 
 // Check the integrity of data offsets.
@@ -223,8 +223,7 @@ typedef struct SettingsDataStruct {
     abc_float_t delta_endstop_adj;                      // M666 XYZ
     float delta_radius,                                 // M665 R
           delta_diagonal_rod,                           // M665 L
-          delta_segments_per_second,                    // M665 S
-          delta_calibration_radius;                     // M665 B
+          delta_segments_per_second;                    // M665 S
     abc_float_t delta_tower_angle_trim;                 // M665 XYZ
   #elif EITHER(X_DUAL_ENDSTOPS, Y_DUAL_ENDSTOPS) || Z_MULTI_ENDSTOPS
     float x2_endstop_adj,                               // M666 X
@@ -724,7 +723,6 @@ void MarlinSettings::postprocess() {
         EEPROM_WRITE(delta_radius);              // 1 float
         EEPROM_WRITE(delta_diagonal_rod);        // 1 float
         EEPROM_WRITE(delta_segments_per_second); // 1 float
-        EEPROM_WRITE(delta_calibration_radius);  // 1 float
         EEPROM_WRITE(delta_tower_angle_trim);    // 3 floats
 
       #elif EITHER(X_DUAL_ENDSTOPS, Y_DUAL_ENDSTOPS) || Z_MULTI_ENDSTOPS
@@ -1534,7 +1532,6 @@ void MarlinSettings::postprocess() {
           EEPROM_READ(delta_radius);              // 1 float
           EEPROM_READ(delta_diagonal_rod);        // 1 float
           EEPROM_READ(delta_segments_per_second); // 1 float
-          EEPROM_READ(delta_calibration_radius);  // 1 float
           EEPROM_READ(delta_tower_angle_trim);    // 3 floats
 
         #elif EITHER(X_DUAL_ENDSTOPS, Y_DUAL_ENDSTOPS) || Z_MULTI_ENDSTOPS
@@ -2375,7 +2372,6 @@ void MarlinSettings::reset() {
     delta_radius = DELTA_RADIUS;
     delta_diagonal_rod = DELTA_DIAGONAL_ROD;
     delta_segments_per_second = DELTA_SEGMENTS_PER_SECOND;
-    delta_calibration_radius = DELTA_CALIBRATION_RADIUS;
     delta_tower_angle_trim = dta;
 
   #elif EITHER(X_DUAL_ENDSTOPS, Y_DUAL_ENDSTOPS) || Z_MULTI_ENDSTOPS
@@ -2939,14 +2935,13 @@ void MarlinSettings::reset() {
         , " Z", LINEAR_UNIT(delta_endstop_adj.c)
       );
 
-      CONFIG_ECHO_HEADING("Delta settings: L<diagonal_rod> R<radius> H<height> S<segments_per_s> B<calibration radius> XYZ<tower angle corrections>");
+      CONFIG_ECHO_HEADING("Delta settings: L<diagonal_rod> R<radius> H<height> S<segments_per_s> XYZ<tower angle corrections>");
       CONFIG_ECHO_START();
       SERIAL_ECHOLNPAIR(
           "  M665 L", LINEAR_UNIT(delta_diagonal_rod)
         , " R", LINEAR_UNIT(delta_radius)
         , " H", LINEAR_UNIT(delta_height)
         , " S", delta_segments_per_second
-        , " B", LINEAR_UNIT(delta_calibration_radius)
         , " X", LINEAR_UNIT(delta_tower_angle_trim.a)
         , " Y", LINEAR_UNIT(delta_tower_angle_trim.b)
         , " Z", LINEAR_UNIT(delta_tower_angle_trim.c)
diff --git a/Marlin/src/module/delta.cpp b/Marlin/src/module/delta.cpp
index 8ef64b09aa..d1dc434e5a 100644
--- a/Marlin/src/module/delta.cpp
+++ b/Marlin/src/module/delta.cpp
@@ -54,8 +54,7 @@ float delta_height;
 abc_float_t delta_endstop_adj{0};
 float delta_radius,
       delta_diagonal_rod,
-      delta_segments_per_second,
-      delta_calibration_radius;
+      delta_segments_per_second;
 abc_float_t delta_tower_angle_trim;
 xy_float_t delta_tower[ABC];
 abc_float_t delta_diagonal_rod_2_tower;
@@ -83,6 +82,24 @@ void recalc_delta_settings() {
   set_all_unhomed();
 }
 
+/**
+ * Get a safe radius for calibration
+ */
+
+#if ENABLED(DELTA_AUTO_CALIBRATION)
+  float calibration_radius_factor = 1;
+#endif
+
+float delta_calibration_radius() {
+  return FLOOR((DELTA_PRINTABLE_RADIUS - (
+    #if HAS_BED_PROBE
+      _MAX(HYPOT(probe_offset.x, probe_offset.y), MIN_PROBE_EDGE)
+    #else
+      MIN_PROBE_EDGE
+    #endif
+  )) * calibration_radius_factor);
+}
+
 /**
  * Delta Inverse Kinematics
  *
diff --git a/Marlin/src/module/delta.h b/Marlin/src/module/delta.h
index f2e602fe14..17cd330686 100644
--- a/Marlin/src/module/delta.h
+++ b/Marlin/src/module/delta.h
@@ -31,8 +31,7 @@ extern float delta_height;
 extern abc_float_t delta_endstop_adj;
 extern float delta_radius,
              delta_diagonal_rod,
-             delta_segments_per_second,
-             delta_calibration_radius;
+             delta_segments_per_second;
 extern abc_float_t delta_tower_angle_trim;
 extern xy_float_t delta_tower[ABC];
 extern abc_float_t delta_diagonal_rod_2_tower;
@@ -44,6 +43,17 @@ extern float delta_clip_start_height;
  */
 void recalc_delta_settings();
 
+/**
+ * Get a safe radius for calibration
+ */
+#if ENABLED(DELTA_AUTO_CALIBRATION)
+  extern float calibration_radius_factor;
+#else
+  constexpr float calibration_radius_factor = 1;
+#endif
+
+float delta_calibration_radius();
+
 /**
  * Delta Inverse Kinematics
  *
diff --git a/Marlin/src/module/probe.h b/Marlin/src/module/probe.h
index 36d3d6618b..953571b6c8 100644
--- a/Marlin/src/module/probe.h
+++ b/Marlin/src/module/probe.h
@@ -60,48 +60,81 @@
 
 #endif
 
-#if HAS_LEVELING && (HAS_BED_PROBE || ENABLED(PROBE_MANUALLY))
-  inline float probe_min_x() {
-    return _MAX(
-      #if IS_KINEMATIC
-        PROBE_X_MIN, MESH_MIN_X
-      #else
-        (X_MIN_BED) + (MIN_PROBE_EDGE_LEFT), (X_MIN_POS) + probe_offset.x
+#if HAS_BED_PROBE || ENABLED(PROBE_MANUALLY)
+  #if IS_KINEMATIC
+    constexpr float printable_radius =
+      #if ENABLED(DELTA)
+        DELTA_PRINTABLE_RADIUS;
+      #elif IS_SCARA
+        SCARA_PRINTABLE_RADIUS;
+      #endif
+    
+    inline float probe_radius() {
+      return printable_radius -
+        #if HAS_BED_PROBE
+          _MAX(MIN_PROBE_EDGE, HYPOT(probe_offset.x, probe_offset.y));
+        #else
+          MIN_PROBE_EDGE;
+        #endif
+    }
+  #endif
+
+  inline float probe_min_x() {
+    return
+      #if IS_KINEMATIC
+        (X_CENTER) - probe_radius();
+      #else
+        _MAX((X_MIN_BED) + (MIN_PROBE_EDGE_LEFT), (X_MIN_POS) + probe_offset.x);
       #endif
-    );
   }
   inline float probe_max_x() {
-    return _MIN(
+    return
       #if IS_KINEMATIC
-        PROBE_X_MAX, MESH_MAX_X
+        (X_CENTER) + probe_radius();
       #else
-        (X_MAX_BED) - (MIN_PROBE_EDGE_RIGHT), (X_MAX_POS) + probe_offset.x
+        _MIN((X_MAX_BED) - (MIN_PROBE_EDGE_RIGHT), (X_MAX_POS) + probe_offset.x);
       #endif
-    );
   }
   inline float probe_min_y() {
-    return _MAX(
+    return 
       #if IS_KINEMATIC
-        PROBE_Y_MIN, MESH_MIN_Y
+        (Y_CENTER) - probe_radius();
       #else
-        (Y_MIN_BED) + (MIN_PROBE_EDGE_FRONT), (Y_MIN_POS) + probe_offset.y
+        _MAX((Y_MIN_BED) + (MIN_PROBE_EDGE_FRONT), (Y_MIN_POS) + probe_offset.y);
       #endif
-    );
   }
   inline float probe_max_y() {
-    return _MIN(
+    return 
       #if IS_KINEMATIC
-        PROBE_Y_MAX, MESH_MAX_Y
+        (Y_CENTER) + probe_radius();
       #else
-        (Y_MAX_BED) - (MIN_PROBE_EDGE_BACK), (Y_MAX_POS) + probe_offset.y
+        _MIN((Y_MAX_BED) - (MIN_PROBE_EDGE_BACK), (Y_MAX_POS) + probe_offset.y);
       #endif
-    );
   }
-#else
-  inline float probe_min_x() { return 0; };
-  inline float probe_max_x() { return 0; };
-  inline float probe_min_y() { return 0; };
-  inline float probe_max_y() { return 0; };
+
+  #if NEEDS_THREE_PROBE_POINTS
+    // Retrieve three points to probe the bed. Any type exposing set(X,Y) may be used.
+    template <typename T>
+    inline void get_three_probe_points(T points[3]) {
+      #if ENABLED(HAS_FIXED_3POINT)
+        points[0].set(PROBE_PT_1_X, PROBE_PT_1_Y);
+        points[1].set(PROBE_PT_2_X, PROBE_PT_2_Y);
+        points[2].set(PROBE_PT_3_X, PROBE_PT_3_Y);
+      #else
+        #if IS_KINEMATIC
+          constexpr float SIN0 = 0.0, SIN120 = 0.866025, SIN240 = -0.866025,
+                          COS0 = 1.0, COS120 = -0.5    , COS240 = -0.5;
+          points[0].set((X_CENTER) + probe_radius() * COS0,   (Y_CENTER) + probe_radius() * SIN0);
+          points[1].set((X_CENTER) + probe_radius() * COS120, (Y_CENTER) + probe_radius() * SIN120);
+          points[2].set((X_CENTER) + probe_radius() * COS240, (Y_CENTER) + probe_radius() * SIN240);
+        #else
+          points[0].set(probe_min_x(), probe_min_y());
+          points[1].set(probe_max_x(), probe_min_y());
+          points[2].set((probe_max_x() - probe_min_x()) / 2, probe_max_y());
+        #endif
+      #endif
+    }
+  #endif
 #endif
 
 #if HAS_Z_SERVO_PROBE
diff --git a/config/examples/delta/Anycubic/Kossel/Configuration.h b/config/examples/delta/Anycubic/Kossel/Configuration.h
index 6c1dc995b2..f4e05e3f96 100644
--- a/config/examples/delta/Anycubic/Kossel/Configuration.h
+++ b/config/examples/delta/Anycubic/Kossel/Configuration.h
@@ -669,8 +669,6 @@
   #endif
 
   #if EITHER(DELTA_AUTO_CALIBRATION, DELTA_CALIBRATION_MENU)
-    // Set the radius for the calibration probe points - max DELTA_PRINTABLE_RADIUS for non-eccentric probes
-    #define DELTA_CALIBRATION_RADIUS DELTA_PRINTABLE_RADIUS - (MIN_PROBE_EDGE)  // (mm)
     // Set the steprate for papertest probing
     #define PROBE_MANUALLY_STEP 0.05      // (mm)
   #endif
diff --git a/config/examples/delta/Dreammaker/Overlord/Configuration.h b/config/examples/delta/Dreammaker/Overlord/Configuration.h
index a76b0201bd..2d13e92971 100644
--- a/config/examples/delta/Dreammaker/Overlord/Configuration.h
+++ b/config/examples/delta/Dreammaker/Overlord/Configuration.h
@@ -636,8 +636,6 @@
   #endif
 
   #if EITHER(DELTA_AUTO_CALIBRATION, DELTA_CALIBRATION_MENU)
-    // Set the radius for the calibration probe points - max DELTA_PRINTABLE_RADIUS for non-eccentric probes
-    #define DELTA_CALIBRATION_RADIUS DELTA_PRINTABLE_RADIUS - (MIN_PROBE_EDGE)  // (mm) Overlord 70mm
     // Set the steprate for papertest probing
     #define PROBE_MANUALLY_STEP 0.05                              // (mm)
   #endif
diff --git a/config/examples/delta/Dreammaker/Overlord_Pro/Configuration.h b/config/examples/delta/Dreammaker/Overlord_Pro/Configuration.h
index 48ca9488ac..78d4f7f143 100644
--- a/config/examples/delta/Dreammaker/Overlord_Pro/Configuration.h
+++ b/config/examples/delta/Dreammaker/Overlord_Pro/Configuration.h
@@ -648,8 +648,6 @@
   #endif
 
   #if EITHER(DELTA_AUTO_CALIBRATION, DELTA_CALIBRATION_MENU)
-    // Set the radius for the calibration probe points - max DELTA_PRINTABLE_RADIUS for non-eccentric probes
-    #define DELTA_CALIBRATION_RADIUS DELTA_PRINTABLE_RADIUS - (MIN_PROBE_EDGE)  // (mm) Overlord Pro 80mm
     // Set the steprate for papertest probing
     #define PROBE_MANUALLY_STEP 0.05                              // (mm)
   #endif
diff --git a/config/examples/delta/FLSUN/auto_calibrate/Configuration.h b/config/examples/delta/FLSUN/auto_calibrate/Configuration.h
index 872c5a7d23..4964566bf1 100644
--- a/config/examples/delta/FLSUN/auto_calibrate/Configuration.h
+++ b/config/examples/delta/FLSUN/auto_calibrate/Configuration.h
@@ -636,8 +636,6 @@
   #endif
 
   #if EITHER(DELTA_AUTO_CALIBRATION, DELTA_CALIBRATION_MENU)
-    // Set the radius for the calibration probe points - max DELTA_PRINTABLE_RADIUS for non-eccentric probes
-    #define DELTA_CALIBRATION_RADIUS 73.5 // (mm)
     // Set the steprate for papertest probing
     #define PROBE_MANUALLY_STEP 0.05      // (mm)
   #endif
diff --git a/config/examples/delta/FLSUN/kossel/Configuration.h b/config/examples/delta/FLSUN/kossel/Configuration.h
index b78cedfa27..f629792e85 100644
--- a/config/examples/delta/FLSUN/kossel/Configuration.h
+++ b/config/examples/delta/FLSUN/kossel/Configuration.h
@@ -636,8 +636,6 @@
   #endif
 
   #if EITHER(DELTA_AUTO_CALIBRATION, DELTA_CALIBRATION_MENU)
-    // Set the radius for the calibration probe points - max DELTA_PRINTABLE_RADIUS for non-eccentric probes
-    #define DELTA_CALIBRATION_RADIUS 63   // (mm)
     // Set the steprate for papertest probing
     #define PROBE_MANUALLY_STEP 0.05      // (mm)
   #endif
diff --git a/config/examples/delta/FLSUN/kossel_mini/Configuration.h b/config/examples/delta/FLSUN/kossel_mini/Configuration.h
index 14487f8029..d678a5c82c 100644
--- a/config/examples/delta/FLSUN/kossel_mini/Configuration.h
+++ b/config/examples/delta/FLSUN/kossel_mini/Configuration.h
@@ -636,8 +636,6 @@
   #endif
 
   #if EITHER(DELTA_AUTO_CALIBRATION, DELTA_CALIBRATION_MENU)
-    // Set the radius for the calibration probe points - max DELTA_PRINTABLE_RADIUS for non-eccentric probes
-    #define DELTA_CALIBRATION_RADIUS 73.5 // (mm)
     // Set the steprate for papertest probing
     #define PROBE_MANUALLY_STEP 0.05      // (mm)
   #endif
diff --git a/config/examples/delta/Geeetech/Rostock 301/Configuration.h b/config/examples/delta/Geeetech/Rostock 301/Configuration.h
index a7ab356a49..bfc0c2d0c6 100644
--- a/config/examples/delta/Geeetech/Rostock 301/Configuration.h	
+++ b/config/examples/delta/Geeetech/Rostock 301/Configuration.h	
@@ -626,8 +626,6 @@
   #endif
 
   #if EITHER(DELTA_AUTO_CALIBRATION, DELTA_CALIBRATION_MENU)
-    // Set the radius for the calibration probe points - max DELTA_PRINTABLE_RADIUS for non-eccentric probes
-    #define DELTA_CALIBRATION_RADIUS 121.5 // (mm)
     // Set the steprate for papertest probing
     #define PROBE_MANUALLY_STEP 0.05      // (mm)
   #endif
diff --git a/config/examples/delta/Hatchbox_Alpha/Configuration.h b/config/examples/delta/Hatchbox_Alpha/Configuration.h
index 2397d24f5c..cdac66f5c1 100644
--- a/config/examples/delta/Hatchbox_Alpha/Configuration.h
+++ b/config/examples/delta/Hatchbox_Alpha/Configuration.h
@@ -641,8 +641,6 @@
   #endif
 
   #if EITHER(DELTA_AUTO_CALIBRATION, DELTA_CALIBRATION_MENU)
-    // Set the radius for the calibration probe points - max DELTA_PRINTABLE_RADIUS for non-eccentric probes
-    #define DELTA_CALIBRATION_RADIUS 121.5 // (mm)
     // Set the steprate for papertest probing
     #define PROBE_MANUALLY_STEP 0.05      // (mm)
   #endif
diff --git a/config/examples/delta/MKS/SBASE/Configuration.h b/config/examples/delta/MKS/SBASE/Configuration.h
index 6585b8eb9c..065b060fd2 100644
--- a/config/examples/delta/MKS/SBASE/Configuration.h
+++ b/config/examples/delta/MKS/SBASE/Configuration.h
@@ -626,8 +626,6 @@
   #endif
 
   #if EITHER(DELTA_AUTO_CALIBRATION, DELTA_CALIBRATION_MENU)
-    // Set the radius for the calibration probe points - max DELTA_PRINTABLE_RADIUS for non-eccentric probes
-    #define DELTA_CALIBRATION_RADIUS 121.5 // (mm)
     // Set the steprate for papertest probing
     #define PROBE_MANUALLY_STEP 0.05      // (mm)
   #endif
diff --git a/config/examples/delta/Tevo Little Monster/Configuration.h b/config/examples/delta/Tevo Little Monster/Configuration.h
index 15849a902e..c99ccba233 100644
--- a/config/examples/delta/Tevo Little Monster/Configuration.h	
+++ b/config/examples/delta/Tevo Little Monster/Configuration.h	
@@ -630,8 +630,6 @@
   #endif
 
   #if EITHER(DELTA_AUTO_CALIBRATION, DELTA_CALIBRATION_MENU)
-    // Set the radius for the calibration probe points - max DELTA_PRINTABLE_RADIUS for non-eccentric probes
-    #define DELTA_CALIBRATION_RADIUS 140  // (mm)
     // Set the steprate for papertest probing
     #define PROBE_MANUALLY_STEP 0.05      // (mm)
   #endif
diff --git a/config/examples/delta/generic/Configuration.h b/config/examples/delta/generic/Configuration.h
index df6026b4a4..cea7a4d957 100644
--- a/config/examples/delta/generic/Configuration.h
+++ b/config/examples/delta/generic/Configuration.h
@@ -626,8 +626,6 @@
   #endif
 
   #if EITHER(DELTA_AUTO_CALIBRATION, DELTA_CALIBRATION_MENU)
-    // Set the radius for the calibration probe points - max DELTA_PRINTABLE_RADIUS for non-eccentric probes
-    #define DELTA_CALIBRATION_RADIUS 121.5 // (mm)
     // Set the steprate for papertest probing
     #define PROBE_MANUALLY_STEP 0.05      // (mm)
   #endif
diff --git a/config/examples/delta/kossel_mini/Configuration.h b/config/examples/delta/kossel_mini/Configuration.h
index d525bcb4b6..de25489cb3 100644
--- a/config/examples/delta/kossel_mini/Configuration.h
+++ b/config/examples/delta/kossel_mini/Configuration.h
@@ -626,8 +626,6 @@
   #endif
 
   #if EITHER(DELTA_AUTO_CALIBRATION, DELTA_CALIBRATION_MENU)
-    // Set the radius for the calibration probe points - max DELTA_PRINTABLE_RADIUS for non-eccentric probes
-    #define DELTA_CALIBRATION_RADIUS 78.0 // (mm)
     // Set the steprate for papertest probing
     #define PROBE_MANUALLY_STEP 0.05      // (mm)
   #endif
diff --git a/config/examples/delta/kossel_pro/Configuration.h b/config/examples/delta/kossel_pro/Configuration.h
index 79853d693b..de8f34876b 100644
--- a/config/examples/delta/kossel_pro/Configuration.h
+++ b/config/examples/delta/kossel_pro/Configuration.h
@@ -612,8 +612,6 @@
   #endif
 
   #if EITHER(DELTA_AUTO_CALIBRATION, DELTA_CALIBRATION_MENU)
-    // Set the radius for the calibration probe points - max DELTA_PRINTABLE_RADIUS for non-eccentric probes
-    #define DELTA_CALIBRATION_RADIUS 110.0 // (mm)
     // Set the steprate for papertest probing
     #define PROBE_MANUALLY_STEP 0.05      // (mm)
   #endif
diff --git a/config/examples/delta/kossel_xl/Configuration.h b/config/examples/delta/kossel_xl/Configuration.h
index 311508e654..68e444c848 100644
--- a/config/examples/delta/kossel_xl/Configuration.h
+++ b/config/examples/delta/kossel_xl/Configuration.h
@@ -630,8 +630,6 @@
   #endif
 
   #if EITHER(DELTA_AUTO_CALIBRATION, DELTA_CALIBRATION_MENU)
-    // Set the radius for the calibration probe points - max DELTA_PRINTABLE_RADIUS for non-eccentric probes
-    #define DELTA_CALIBRATION_RADIUS 121.5 // (mm)
     // Set the steprate for papertest probing
     #define PROBE_MANUALLY_STEP 0.05      // (mm)
   #endif