Skip to content

Commit 8300f36

Browse files
committed
Hangprinter: Generalize IsReachable() to any pseudo-pyramid
This is a clean generalization from 4 to N. Pseudo-pyramid because the vertices in the base of the pseudo-pyramid don't need to be on the same plane. There's no base of the pyramid as such. Better documented and cleaner thanks to @tobbelobb on github.
1 parent e19697e commit 8300f36

File tree

1 file changed

+18
-8
lines changed

1 file changed

+18
-8
lines changed

src/Movement/Kinematics/HangprinterKinematics.cpp

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -444,17 +444,27 @@ static bool isSameSide(float const v0[3], float const v1[3], float const v2[3],
444444
return dot0*dot1 > 0.0F;
445445
}
446446

447-
static bool isInsideTetrahedron(float const point[3], float const tetrahedron[4][3]){
448-
return isSameSide(tetrahedron[0], tetrahedron[1], tetrahedron[2], tetrahedron[3], point) &&
449-
isSameSide(tetrahedron[2], tetrahedron[1], tetrahedron[3], tetrahedron[0], point) &&
450-
isSameSide(tetrahedron[2], tetrahedron[3], tetrahedron[0], tetrahedron[1], point) &&
451-
isSameSide(tetrahedron[0], tetrahedron[3], tetrahedron[1], tetrahedron[2], point);
452-
}
453-
447+
// For each triangle side in a pseudo-pyramid, check if the point is inside the pyramid (Except for the base)
448+
// Also check that any point below the line between two exterior anchors (all anchors are exterior except for the last one)
449+
// is in the "inside part" all the way down to min_Z, however low it may be.
450+
// To further limit the movements in the X and Y axes one can simply set a smaller print radius.
454451
bool HangprinterKinematics::IsReachable(float axesCoords[MaxAxes], AxesBitmap axes) const noexcept /*override*/
455452
{
456453
float const coords[3] = {axesCoords[X_AXIS], axesCoords[Y_AXIS], axesCoords[Z_AXIS]};
457-
return isInsideTetrahedron(coords, anchors);
454+
bool reachable = true;
455+
456+
// Check all the planes defined by triangle sides in the pyramid
457+
for (size_t i = 0; reachable && i < HANGPRINTER_AXES - 1; ++i) {
458+
reachable = reachable && isSameSide(anchors[i], anchors[(i+1) % (HANGPRINTER_AXES - 1)], anchors[HANGPRINTER_AXES - 1], anchors[(i+2) % (HANGPRINTER_AXES - 1)], coords);
459+
}
460+
461+
// For each side of the base, check the plane formed by side and another point bellow them in z.
462+
for (size_t i = 0; reachable && i < HANGPRINTER_AXES - 1; ++i) {
463+
float const lower_point[3] = {anchors[i][0], anchors[i][1], anchors[i][2] - 1};
464+
reachable = reachable && isSameSide(anchors[i], anchors[(i+1) % (HANGPRINTER_AXES - 1)], lower_point, anchors[(i+2) % (HANGPRINTER_AXES - 1)], coords);
465+
}
466+
467+
return reachable;
458468
}
459469

460470
// Limit the Cartesian position that the user wants to move to returning true if we adjusted the position

0 commit comments

Comments
 (0)