Ответ 1
Вы попадаете в это, потому что ваш obj[i].angle
основан на эллипсе coördinates, а не на xy coördinates сверху вниз (на самом деле это то, что вы генерируете все остальное, поэтому нам не нужно делать расчеты для него).
Вам понадобятся оба угла, поэтому я добавил второе свойство для другого угла. Угол эллипса необходим для поворота контекста, поэтому вы можете перпендикулярно вектору от начала координат, если смотреть. Новый угол для расчетов. Вы можете думать о нем как о не-2D-версии.
obj[i].trueAngle = angle;
Теперь у нас есть значение для работы, я предлагаю рисовать полукруг для "темной стороны", а затем добавлять или вырезать из этого региона по мере необходимости, используя кривую по вашему выбору для завершения тени, например
// centre on planet
ctx.translate(originX + obj[i].x, originY + obj[i].y);
ctx.rotate(obj[i].angle - Math.PI / 2);
// semicircle dark side
ctx.arc(0, 0, 12, 0, Math.PI, false);
// path along terminator
var offset_terminator = -20 * Math.sin(obj[0].trueAngle) * (1 - camera.angle);
ctx.bezierCurveTo(-7, offset_terminator, 7, offset_terminator, 12, 0);
//fill
ctx.fillStyle = 'rgba(213,0,0,0.9)'; //red shadow - easier to see
ctx.fill();
Здесь я также сделал тень на пару пикселей больше, чем на планете, я просто играл с числами, пока не нашел некоторые, которые выглядели хорошо.
Обратите внимание, что я устанавливаю вращение, поэтому 0, 0
является средой планеты, а ось x перемещается вдоль терминатора