Skip to content

Commit bc0ab4d

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 7b65487 commit bc0ab4d

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
@@ -419,17 +419,27 @@ static bool isSameSide(float const v0[3], float const v1[3], float const v2[3],
419419
return dot0*dot1 > 0.0F;
420420
}
421421

422-
static bool isInsideTetrahedron(float const point[3], float const tetrahedron[4][3]){
423-
return isSameSide(tetrahedron[0], tetrahedron[1], tetrahedron[2], tetrahedron[3], point) &&
424-
isSameSide(tetrahedron[2], tetrahedron[1], tetrahedron[3], tetrahedron[0], point) &&
425-
isSameSide(tetrahedron[2], tetrahedron[3], tetrahedron[0], tetrahedron[1], point) &&
426-
isSameSide(tetrahedron[0], tetrahedron[3], tetrahedron[1], tetrahedron[2], point);
427-
}
428-
422+
// For each triangle side in a pseudo-pyramid, check if the point is inside the pyramid (Except for the base)
423+
// Also check that any point below the line between two exterior anchors (all anchors are exterior except for the last one)
424+
// is in the "inside part" all the way down to min_Z, however low it may be.
425+
// To further limit the movements in the X and Y axes one can simply set a smaller print radius.
429426
bool HangprinterKinematics::IsReachable(float axesCoords[MaxAxes], AxesBitmap axes) const noexcept /*override*/
430427
{
431428
float const coords[3] = {axesCoords[X_AXIS], axesCoords[Y_AXIS], axesCoords[Z_AXIS]};
432-
return isInsideTetrahedron(coords, anchors);
429+
bool reachable = true;
430+
431+
// Check all the planes defined by triangle sides in the pyramid
432+
for (size_t i = 0; reachable && i < HANGPRINTER_AXES - 1; ++i) {
433+
reachable = reachable && isSameSide(anchors[i], anchors[(i+1) % (HANGPRINTER_AXES - 1)], anchors[HANGPRINTER_AXES - 1], anchors[(i+2) % (HANGPRINTER_AXES - 1)], coords);
434+
}
435+
436+
// For each side of the base, check the plane formed by side and another point bellow them in z.
437+
for (size_t i = 0; reachable && i < HANGPRINTER_AXES - 1; ++i) {
438+
float const lower_point[3] = {anchors[i][0], anchors[i][1], anchors[i][2] - 1};
439+
reachable = reachable && isSameSide(anchors[i], anchors[(i+1) % (HANGPRINTER_AXES - 1)], lower_point, anchors[(i+2) % (HANGPRINTER_AXES - 1)], coords);
440+
}
441+
442+
return reachable;
433443
}
434444

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

0 commit comments

Comments
 (0)