3. js CSS3DRenderer: не трогайте другие элементы - PullRequest
1 голос
/ 12 июля 2020

Я использую случайные позиции для своих элементов в моем Three. js CSS3DRenderer.

Некоторые элементы соприкасаются друг с другом. Есть ли способ избежать этого?

Код:

// Setup

items.forEach((jksalfjlasdk) => {
  const item = new CSS3DObject(item);
  item.position.x = Math.random() * 1000 - 500;
  item.position.y = Math.random() * 1000 - 500;
  item.position.z = Math.random() * 1000 - 500;
  item.rotation.y = Math.random() * 0.5 - 0.5;
  scene.add(item);
});

1 Ответ

1 голос
/ 13 июля 2020

Некоторое время я делал сценарий для чего-то вроде этого go, так как я хотел случайным образом генерировать равномерно распределенные сферы в трехмерном пространстве .

Вы передаете количество объектов вы хотите выполнить рендеринг и количество попыток для каждого из них, чтобы отвести одно дальше от остальных (меньшее число дает вам лучшую производительность, большее число - лучший результат, 10 в большинстве случаев подойдет).

function randomPointsSpace(qty, tries){
    let points = [];
    for(let i=0; i<qty; i++){
        let candidates = [];
        for(let j=0; j<tries; j++){
            candidates.push(getCandidate());
        } 
        points.push(getBestCandidate(points, candidates));
    }
    return points;
}

function getCandidate(){
    return {x: Math.random(), y: Math.random(), z: Math.random()};
}

function getBestCandidate(members, candidates){
    let max = 0,
        selected;

    for(let k=0; k<candidates.length; k++){
        let min = 1,
            c = candidates[k];

        for(let l=0; l<members.length; l++){
            let m = members[l];
            let dist = Math.sqrt( (c.x-m.x) ** 2 + (c.y-m.y) ** 2 + (c.z-m.z) ** 2 ) - m.r/2;

            if(dist < min){
                min = dist;
            }
        }

        if(min > max){
            max = min;
            selected = c;
            selected.r = min/2;
        }
    }

    return selected;
}

const ar = randomPointsSpace(20, 10);

console.log(ar);

Затем вы получаете массив объектов с координатами x, y, x и радио r, все как числа от 0 до 1, которые вам нужно умножить на размер вашего 3D-пространства.

ar = [
  {
    "x": 0.33811887215352576,
    "y": 0.942598814594636,
    "z": 0.4027051631550116,
    "r": 0.5
  },
  {
    "x": 0.7434202306598208,
    "y": 0.10045068968699278,
    "z": 0.010629850147066078,
    "r": 0.38175578599626914
  },
  {
    "x": 0.6657177122961799,
    "y": 0.07700830496311029,
    "z": 0.875727933811969,
    "r": 0.3390095317818107
  }
];

const canvasLateral = 1000;
const objectsMaxSize = 400;

ar.map( (a) => {
  a.x *= canvasLateral;
  a.y *= canvasLateral;
  a.z *= canvasLateral;
  a.r *= objectsMaxSize;
});

console.log(ar);
...