Как убрать угловые индексы 2D массива? - PullRequest
0 голосов
/ 02 марта 2019

Работа над алгоритмом прямой трассировки лучей с использованием Three.js.Просто создал этот пример с помощью 2D-массива.Обратите внимание, что Spotlight здесь не задействован, за исключением разбора его местоположения.

Итак, чтобы снимать строки, я объявил:

startPoint = position of SpotLight
endPoint   = hard code for the first value

enter image description here

Затем я создаю вложенный цикл for (17x17) и создаю луч каждую итерацию обычным способом, как показано ниже:

forward_RT(){

    //Declare the start and end points of the first ray (startPoint never changes )
    var f_ray_startPoint = new THREE.Vector3(spotLight.position.x, spotLight.position.y, spotLight.position.z);
    var f_ray_endPoint = new THREE.Vector3(-490, 0, 495); //Hard Coding for 1st position of ray endPoint

    //Declare material of rays
    var ray_material_red = new THREE.LineBasicMaterial( { color: 0xff0000, opacity: 10} );
    var ray_material_yellow = new THREE.LineBasicMaterial( { color: 0xffff00 } );
    var ray_material_green = new THREE.LineBasicMaterial( { color: 0x00ff00 } );

    //Declare ray geometry
    var ray_geometry = new THREE.Geometry();
    ray_geometry.vertices.push( f_ray_startPoint );
    ray_geometry.vertices.push( f_ray_endPoint );

    //Declare values for 2d array grid
    var rows = 17;
    var cols = 17;
    var rayOffset = 60; //Offset of ray every X iteration

    for(var x=0; x<rows; x++){
        for(var z=0; z<cols; z++){
            //Declare a ray
            var f_ray = new THREE.Line(ray_geometry.clone(), ray_material_red);
            f_ray.geometry.vertices[1].x = f_ray_endPoint.x;

            scene_Main.add(f_ray); //Add ray into the scene
            f_ray_endPoint.x += rayOffset; //Add offset every new ray

            if(f_ray_endPoint.x >= 490){
                f_ray_endPoint.x -= (cols * rayOffset);
            }
        }
        f_ray_endPoint.z -= rayOffset;
    }
}

Для пользователей графики я заметил, что непрозрачность не 'работать с материалом Three.Line .

Есть ли способ добавить прозрачность на линию?


Основной вопрос

Как заблокировать итерацию, чтобы углы SpotLight не рисовались?Другими словами, я хочу получить доступ только к лучам, которые находятся внутри белого круга (SpotLights).


1 Ответ

0 голосов
/ 02 марта 2019

Если вы хотите сохранить дискретную сетку из лучей X, Y и отбросить те, которые находятся вне круга, вы можете использовать встроенный метод Vector2.distanceTo().Просто оставьте цикл таким, какой он есть, но рассчитайте расстояние до центра круга, если расстояние больше радиуса, перейдите к следующему циклу:

// Find the center of your circle
var center = new THREE.Vector2(centerX, centerZ);
// Assign radius of your circle
var radius = 17 / 2;
// Temp vector to calculate distance per iteration
var rayEnd = new THREE.Vector2();
// Result of distance
var distance = 0;

for (var x = 0; x < rows; x++) {
    for (var z = 0; z < cols; z++) {
        // Set this ray's end position
        rayEnd.set(x, z);
        // Calculate distance to center
        distance = rayEnd.distanceTo(center);

        // Skip loop if distance to center is bigger than radius
        if (distance > radius) {
            continue;
        } else {
            // Draw ray to x, z
        }
    }
}

Несколько рекомендаций:

  1. Я бы использовал один LineSegments объект вместо нескольких Line объектов для более быстрого рендеринга (Three.js быстрее рендерит один объект с большим количеством вершин, чем многие объекты с небольшим количеством вершин)).
  2. Вы можете сгенерировать геометрию вокруг начала координат (от -8 до 8) и рассчитать расстояние до (0, 0), а затем сместить ее на 60 единиц с помощью position.x = 60, для простоты.
...