Покраска с помощью соседних вершин

Описание

Для начала я вам покажу эту картинку:

И так...
У меня есть основная (черная) вершина, нулевой (черный) угол и другие вершины связанные с ним.
У главной вершины есть свойство palette: Map<number, Color> который из себя представляет список связанных с ним вершин по типу [Угол вершины считая с основной линии, цвет вершины], как показано на картинке. Мне нужно покрасить основную вершину с помощью соседних вершин вот так:

Серые линии биссектрисы. Все углы в диапазоне [0, 2π)

Так же

Для своего же удобства я создал функцию который красит по заданным углам:

function fillSector(beginAngle: number, endAngle: number, color: Color): void;

Проблема

Я уже 3 часа не могу правильно рассчитать откуда у меня должна начаться покраска и до куда для определенного цвета, в основном из-за разреза в части с черной линией. Чуть выше этой линии у меня углы ближе к 0, а чуть ниже 2π.

Вопрос

Мне нужно узнать правильный подход к алгоритму, который будет считать сектор покраски.

Пример

Результат для примера сверху должно быть что-то вроде такого:

function aWonderfulFunction(palette: Map<number, Color>): Map<number, Color>;

const palette = new Map([
    [1 / 4 * PI, Color.RED], // От угла 1/4π приходит красный цвет
    [5 / 6 * PI, Color.GREEN], // От угла 5/6π приходит зеленый цвет
    [3 / 2 * PI, Color.BLUE], // От угла 3/2π приходит синий цвет
]);

const result = aWonderfulFunction(palette);

console.log(result);
// new Map([
//  [13 / 24 * PI, Color.RED], // От начала (0π) до биссектрисы красно-зеленого (которая под углом 13/24π) красим красным цветом
//  [14 / 12 * PI, Color.GREEN], // От биссектрисы красно-зеленого (13/24π) до биссектрисы зелено-синего (которая под углом 14/12π) красим зеленым цветом
//  [15 / 8 * PI, Color.BLUE], // От биссектрисы зелено-синего (14/12π) до биссектрисы сине-красного (которая под углом 15/8π) красим синим цветом
//  [2 * PI, Color.RED], // От биссектрисы сине-красного (14/12π) до конца (2π) красим красным цветом
// ]);

Ответы (2 шт):

Автор решения: MBo

Есть ещё такой способ, который не боится переходов через 0
(не подходит напрямую, если разность углов >=Pi):

csum = cos(a)+cos(b)
ssum = sin(a)+sin(b)
middle = atan2(ssum, csum)

По сути - складываются единичные направляющие вектора углов, определяется направление суммарного вектора.

→ Ссылка
Автор решения: Grundy

Для поиска биссектрисы нужно найти на сколько один угол отличается от второго и разделить пополам и прибавить к первому.

Для углов, между которым нет перехода через угол формула будет простой

(a + b) / 2

в противном случае нужна корректировка, например, добавить второму углу 2π - это позволит найти верную разницу между углами

(a + (b+2π))/2

Теперь уже результат может быть больше 2π - и этот случай так же можно скорректировать либо вычитанием 2π в случае необходимости, либо взятием остатка от деления

В js формулу можно обобщить до следующей:

var angle = ((firtsAngle + secondAngle + (firtsAngle > secondAngle)*2*Math.PI)/2) % (2*Math.PI)
→ Ссылка