Объекты < /strong>
Единственные объекты, которые существуют в мире, - это многоугольники с высотой. Полигон определяется положением, с вершинами в качестве точек смещения с его позиции: < /p>
Код: Выделить всё
{
position: {
x: null,
y: null,
z: null
},
hitbox: {
vertices: [
[x,y],[x,y],[x,y]
],
height: null,
search_distance: null, // maximum possible distance across a polygon
},
max_vertice_y: null, // furthest top vertice y position
min_vertice_y: null // lowest bottom vertice y position
}
< /code>
у меня есть алгоритм, который разбивает полигоны на более мелкие многоугольники, которые предотвращают сценарий полигона перед и позади другого многоугольника. Таким образом, для этого примера предположим, что все полигоны будут существовать только перед или позади любого другого. Покажите ниже все, что разделяет одну и ту же проблему ... Полигон (а) может быть полностью ниже другого (b) и поэтому напечатан перед ним. Однако позже в списке обнаруживается многоугольник (C), который печатается до (b), и после (а) из -за положения z и высоты (c) в паре с положением y (a). Я не могу создать метод, который сохраняет истину одного многоугольника по сравнению с другим, не повлиял на результат полигонов, отсортированных после него. В данный момент я исследую топологический вид, но я не могу определить, что такое «зависимость». Я чувствую, что у каждого многоугольника есть только список всего до и после, что может измениться позже, если он появится перед полигоном, который сам сам по себе появляется в списке «после» его предшественника. src = "https://i.sstatic.net/2zd66sm6.png"/>
Мой самый последний подход [/b]
function sortTerrain() {
// terrain_ground and terrain_decor are objects with the properties mentioned above
// create working "grab from list"
let comp_work = [...terrain_ground, ...terrain_decor];
// create sorted list
let working = [comp_work.shift()];
// while grab list isnt empty, take from and insert into sorted list
while (comp_work.length > 0) {
let current = comp_work.shift();
// get index of insert position
let insert = -1;
// start from the furthest forward printed object in the sorted list and work backwards until a truth is found
// **this was originally working from the start to end under the condition of when a truth is not found, exit and use last saved index ... this WORKS but, not as well as looking for a single truth. both still create the issue mentioned above
for (let i=working.length-1; i>=0; i--) {
let compare = working[i];
if (sameZPlane(current, compare)) {
// on same z plane, sort by y
// if guaranteed infront of
if (current.max_vertice_y < compare.min_vertice_y) {
insert = i;
break;
}
// if overlap on y
if (current.min_vertice_y < compare.max_vertice_y && current.max_vertice_y > compare.min_vertice_y) {
// check for ray cast to determine current is in front of compare
// also check rear-forward using rayCastInfrontOf(x, x, true) in case rear is smaller than the gap between a vertice pair of the front polygon
if (rayCastInfrontOf(current, compare) || rayCastInfrontOf(compare, current, true)) {
insert = i;
break;
} else if (current.min_vertice_y < compare.min_vertice_y) {
// if not, then check if current min is in front of compare min
insert = i;
break;
}
}
} else {
// sort by z index
if (current.position.z > compare.position.z) {
insert = i;
break;
} else if (current.position.z == compare.position.z) {
// shared z position yet failing sameZPlane is a 0 height terrain, sort by height
// THIS IS UNLIKELY TO CONTRIBUTE TO ANY PRINT ERRORS
if (current.hitbox.height > compare.hitbox.height) {
insert = i;
break;
}
}
}
}
// no insert location found, add at start of the stack
if (insert == -1) {
working.unshift(current);
} else {
// insert after last found index
working.splice(insert+1, 0, current);
}
}
}
function expandTerrainVertices() {
// can of worms
}
function rayCastInfrontOf(front, rear, reverse = false) {
// allow reverse check by sending truth boolean to reverse param
// safe ray length
let ray = (front.hitbox.search_distance + rear.hitbox.search_distance) * (reverse ? -1 : 1);
// shrink vertices of "front" so that rays casted will not give false positive to polygons sharing a vertice point + position value
let shrink_front_vertices = expandTerrainVertices(front, -1);
// run ray from all vertice points of front backwards (or rear forwards if reverse param is true) and see if it intersects any vertice connections in rear
// "middle" is used to get next safe vertice pair
let middle = 0;
for (let i=0; i a.position.z && b.position.z < a_top)
) {
return true;
}
return false;
}Подробнее здесь: https://stackoverflow.com/questions/795 ... -algorithm