Мне нет дела до пересечения граней
Это означает, что мы можем уменьшить равнины до точек, взяв точку в середине:
const vecOp = op => (a, b) => a.map((c, i) => op(c, b[i] || b));
const add = vecOp((a, b) => a + b);
const sub = vecOp((a, b) => a - b);
const mul = vecOp((a, b) => a * b);
const div = vecOp((a, b) => a / b);
const sum = v => v.reduce((a, b) => a + b, 0);
const middle = (a, b) => div(add(a, b), 2);
const planeToPoint = ([a, b, c, d]) => middle(
middle(a, b),
middle(c, d)
);
Теперь, чтобы отсортировать по «ближе к камере», можно провести линию между центрами двух плоскостей, что приведет к направлению:
const aToB = (a, b) =>
sub(
planeToPoint(b),
planeToPoint(a)
);
Теперь мы можем превратить вращение камеры ввзгляд камеры на вектор :
const rotToVec = (yaw, pitch) => ([
Math.cos(yaw) * Math.cos(pitch),
Math.sin(yaw) * Math.cos(pitch),
Math.sin(pitch)
]);
, и это направление можно сравнить с направлением камеры, что дает угол между ними:
const angle = (a, b) => sum(mul(a, b)) / sum(a) * sum(b)
Теперь давайте повернем это все вместе:
const camVec = rotToVec(cam.yaw, cam.pitch);
planes.sort((a, b) =>
Math.abs(angle(aToB(a, b), camVec)) < Math.PI / 4 /*90°*/ ? 1 : -1
);
Отказ от ответственности: я не пробовал приведенный выше код, не работал с параллельными проекциями и не разбираюсь в математике, поэтому будьте осторожны со своими словами, я понятия не имею, что яговорить о