Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Триангуляция полигонов библиотекой earcut.js на WebGL (https://javascript.ru/forum/misc/73838-triangulyaciya-poligonov-bibliotekojj-earcut-js-na-webgl.html)

Andrew K 20.05.2018 07:52

Триангуляция полигонов библиотекой earcut.js на WebGL
 
Здравствуйте! Понадобилось сделать триангуляцию полигонов. Нашел подходящую библиотеку https://github.com/mapbox/earcut. Но никак не могу понять как она работает. Там сказано, что функция принимает массив координат вершин вида:
earcut([10,0, 0,50, 60,60, 70,10]);

и возвращает такой объект:
[1,0,3, 3,2,1]

Во-первых почему функция принимает массив с числами выходящими за диапазон -1...1 используемый в WebGL в качестве координат точек? Даже если предположить, что это координаты в пикселях, то почему функция возвращает странное значение [1,0,3, 3,2,1]? По идее если в функцию передали квадрат (координаты 4 точек), то значит она должна отдать два треугольника и соответственно 12 цифр. Но отдала всего шесть.
Как работать с этой библиотекой?

MallSerg 20.05.2018 10:19

Цитата:

Здравствуйте! Понадобилось сделать триангуляцию полигонов.
триангуляция полигонов не возможна т.к. она строится только по координатам точек в том или ином пространстве.
Цитата:

Во-первых почему функция принимает массив с числами выходящими за диапазон -1...1 используемый в WebGL в качестве координат точек?
WebGL не накладывается ограничений на диапазон чисел используемых для координат.
Цитата:

почему функция возвращает странное значение [1,0,3, 3,2,1]
чем оно странное?
ты передаешь функции координаты точек а функция тебе возвращает треугольники (если совсем совсем разжевывать то первая вторая и третья точка это один треугольник, вторая третья и четвертая точка это следующий треугольник и так далее).
Цитата:

Как работать с этой библиотекой?
Для начала ее нужно подключить к своему коду после этого с ней можно будет работать вызывать функцию передавать ей параметры и получать результаты вызова =).

Andrew K 20.05.2018 11:53

Цитата:

триангуляция полигонов не возможна т.к. она строится только по координатам точек в том или ином пространстве.
Я это и имел в виду под триангуляцией — сделать из массива точек другой массив с координатами точек треугольников.

Цитата:

WebGL не накладывается ограничений на диапазон чисел используемых для координат.
Не накладывает. Только увидеть точку с координатами 10,0, 0,50 невозможно.

Цитата:

ты передаешь функции координаты точек а функция тебе возвращает треугольники (если совсем совсем разжевывать то первая вторая и третья точка это один треугольник, вторая третья и четвертая точка это следующий треугольник и так далее).
А, это режим рисования TRIANGLE_STRIP в методе gl.drawArrays(). Но если передавать массив [10,0, 0,50, 60,60, 70,10], то на выходе должен быть массив [10,0, 70,10, 0,50, 60,60]. Но он возвращает [1,0, 3,3, 2,1].

Я вот картинку сделал чтобы было понятнее:

Rise 20.05.2018 12:58

Andrew K,
Это индексы точек, а не координаты. [10,0, 0,50, 60,60, 70,10] это 4 точки [0, 1, 2, 3], поэтому возврат выглядит так [1,0,3, 3,2,1] или [0,50, 10,0, 70,10, 70,10, 60,60, 0,50].

MallSerg 20.05.2018 13:08

Вложений: 1
Цитата:

Не накладывает. Только увидеть точку с координатами 10,0, 0,50 невозможно.
плоскости отсечения можно задавать любые

На пальцах не получилось можно попробовать картинкой

Andrew K 20.05.2018 13:55

Ух, сам бы не догадался. Спасибо, Rise и MallSerg!

Получился такой код:
// Исходный массив с точками фигуры
let pointsArr = [10,0, 0,50, 60,60, 70,10];
// Функция принимает массив точек фигуры и возвращает массив индексов
let indexesArr = earcut(pointsArr); // returns [1,0,3, 3,2,1];
// Массив с итоговыми точками треугольников
let result = [];

// Соединю два массива. Из indexesArr возьму индексы, из pointsArr значения координат
for(let i = 0; i < indexesArr.length; i++) {
    result.push( pointsArr[ indexesArr[i] * 2 ] );
    result.push( pointsArr[ indexesArr[i] * 2 + 1 ] );
}

// Вывод координат получившихся треугольников
console.log(result); // [0, 50, 10, 0, 70, 10, 70, 10, 60, 60, 0, 50]

// Уменьшу координаты точек чтобы фигура полностью помещалась на холсте
for(let i = 0; i < result.length; i++) {
    result[i] /= 100;
}


Часовой пояс GMT +3, время: 21:58.