Screw conveyors join by the shared rule: low ends and verticals join in the corner block (t67 phase 2)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+38
-13
@@ -176,23 +176,48 @@ function screwIntake(i, p, dx, dy) {
|
||||
}
|
||||
}
|
||||
|
||||
// Four lanes cross a block in four beats; the casing carries every lane across the corner.
|
||||
// Prefer the next diagonal block, then either straight join, then the open head.
|
||||
// Powder may enter any screw except one pushing exactly against it.
|
||||
function screwAccepts(p, dx, dy) {
|
||||
return SCREW_DX[p] !== -dx || SCREW_DY[p] !== -dy;
|
||||
}
|
||||
// Straight mouths retain side-feeding into lifts; only diagonal transfers need a join.
|
||||
function straightScrewNext(i, p) {
|
||||
const dx = SCREW_DX[p], dy = SCREW_DY[p], x = i % W, y = (i / W) | 0;
|
||||
const xx = x + dx, yy = y + dy, next = yy * W + xx;
|
||||
if ((xx >> 2) === (x >> 2) && (yy >> 2) === (y >> 2)) return next;
|
||||
const end = dx + dy > 0 ? 1 : 0;
|
||||
const q = part[next], nb = (yy >> 2) * BW + (xx >> 2);
|
||||
if (blockP[nb] && !(SCREW_DX[q] && SCREW_DY[q])) return next;
|
||||
const join = endJoin(x >> 2, y >> 2, end);
|
||||
if (join >= 0) {
|
||||
const target = join >> 1, v = blockV[target];
|
||||
if (blockP[target] === BP_SCREW && v >= 4) {
|
||||
if (target === nb) return next;
|
||||
if (!blockP[nb]) {
|
||||
const lane = dx ? y & 3 : x & 3;
|
||||
const tx = target % BW * BS + (join & 1 ? BS - 1 : 0);
|
||||
return (((target / BW) | 0) * BS + lane) * W + tx;
|
||||
}
|
||||
}
|
||||
}
|
||||
return SCREW_DX[q] && SCREW_DY[q] ? -1 : next;
|
||||
}
|
||||
// Four lanes cross a block in four beats; only a mutual geometric join can receive them.
|
||||
function diagonalScrewNext(i, p) {
|
||||
const x = i % W, y = (i / W) | 0, dx = SCREW_DX[p], dy = SCREW_DY[p];
|
||||
const xx = x + dx, bx = x & ~3, by = y & ~3;
|
||||
const xx = x + dx;
|
||||
if (xx < 0 || xx >= W) return -1;
|
||||
if ((xx >> 2) === (x >> 2)) return i + dx;
|
||||
const yy = y + dy * BS;
|
||||
if (yy >= 0 && yy < H) {
|
||||
const q = part[yy * W + xx];
|
||||
if (q >= P_SCREW_UR && q <= P_SCREW_UL && SCREW_DX[q] === dx && SCREW_DY[q] === dy) return yy * W + xx;
|
||||
const yy = y + dy * BS, join = endJoin(x >> 2, y >> 2, dx > 0 ? 1 : 0);
|
||||
if (join >= 0) {
|
||||
const nb = join >> 1, nx = nb % BW * BS, ny = ((nb / BW) | 0) * BS;
|
||||
if (blockP[nb] === BP_BELT || blockP[nb] === BP_FILTER) return (ny - 1) * W + xx;
|
||||
if (blockP[nb] === BP_SCREW) {
|
||||
const v = blockV[nb];
|
||||
if (v >= 4) return yy * W + xx;
|
||||
if (v & 1) return (ny + (y & 3)) * W + xx;
|
||||
return (ny + (dy > 0 ? 0 : 3)) * W + nx + (y & 3);
|
||||
}
|
||||
}
|
||||
if (IS_SCREW[part[y * W + xx]]) return y * W + xx;
|
||||
if (dy > 0 && yy < H && (mat[yy * W + xx] === BELTL || mat[yy * W + xx] === BELTR)) return ((yy & ~3) - 1) * W + xx;
|
||||
const hy = by + (dy > 0 ? BS : -1), hx = bx + (y & 3);
|
||||
if (hy >= 0 && hy < H && IS_SCREW[part[hy * W + hx]]) return hy * W + hx;
|
||||
// An open mouth discharges along the diagonal, clear of the last block.
|
||||
// A corner screw is a separate end, not an open discharge cell.
|
||||
return yy >= 0 && yy < H && !IS_SCREW[part[yy * W + xx]] ? yy * W + xx : -1;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user