2016-11-10 16 views
0

Я делаю глобус в three.js и добавляю некоторые слои данных. Все слои будут созданы из geoJSON. Я настроил его так, что глобус (первый файл данных, который из стран) отображается в виде строк. Используется ThreeGeoJSON.Как рисовать geoJSON в three.js как сетку, а не строку и заливать цветом?

globe with lines

Однако, я не хочу просто контуры. Я хотел бы заполнить страны цветом.

Мой текущий проект можно увидеть здесь: http://bl.ocks.org/jhubley/321232d4ccefefcdc53218fd0adccac5

Код здесь: https://gist.github.com/jhubley/321232d4ccefefcdc53218fd0adccac5

Я попытался создать новую функцию, которая будет оказывать многоугольники и multipolygons в сетках вместо линий. Эта функция такова:

function drawShape(x_values, y_values, z_values, options) { 
     var shape_geom = new THREE.BoxGeometry(); 
     createVertexForEachPoint(shape_geom, x_values, y_values, z_values); 

     var shape_material = new THREE.MeshBasicMaterial({color: 0xffff00 }); 
     var shape = new THREE.Mesh(shape_geom, shape_material); 
     scene.add(shape); 

     clearArrays(); 
    } 

К сожалению, ничего не появляется, когда я использую это. В консоли нет ошибок, чтобы помочь мне понять, почему.

Может ли кто-нибудь объяснить, как я мог бы создать страны, чтобы они могли быть заполнены? Любые советы или указатели были бы очень оценены.

+0

Я не вижу, чтобы вы называли drawShape любым в своем коде ... – Marcs

+0

@ Маркс сожалеет об этом. код обновляется. Функция (и обращение к ней) находится в файле threeGeoJSON.js. – sprucegoose

ответ

1

Как @mlkn сказал, что вы должны использовать треугольники для заполнения сетки.

я бездельничал немного:

function drawLine(x_values, y_values, z_values, options) { 
    // container 
    var obj = new THREE.Object3D(); 

    // lines 
    var line_geom = new THREE.Geometry(); 
    createVertexForEachPoint(line_geom, x_values, y_values, z_values); 
    var line_material = new THREE.LineBasicMaterial({ 
    color: 'yellow' 
    }); 

    var line = new THREE.Line(line_geom, line_material); 

    obj.add(line); 

    // mesh 
    var mesh_geom = new THREE.Geometry(); 
    createVertexForEachPoint(mesh_geom, x_values, y_values, z_values); 
    var mesh_material = new THREE.MeshBasicMaterial({ 
    color: 'blue', 
    side: THREE.DoubleSide 
    }); 
    var mesh = new THREE.Mesh(mesh_geom, mesh_material); 

    obj.add(mesh); 

    scene.add(obj); 

    clearArrays(); 
} 

Object3Dobj оборачивает обе линии и сетки.

Faces (треугольники) создаются здесь:

function createVertexForEachPoint(object_geometry, values_axis1, values_axis2, values_axis3) { 
    for (var i = 0; i < values_axis1.length; i++) { 
     object_geometry.vertices.push(new THREE.Vector3(values_axis1[i], 
      values_axis2[i], values_axis3[i])); 

     object_geometry.faces.push(new THREE.Face3(0, i + 1, i)); // <- add faces 
    } 
} 

В результате немного беспорядок, я, если из-за данных или порядка вершинных/поколение не знает.

Демо:

Это threeGeoJSON плохо написана ИМО, без структуры, в качестве примера вам просто нужно изменить название var scene = ... к var myscene = ... и в целом lib перестает работать, это плохой дизайн.

Также существует большое количество использования ЦП, возможно, слишком много вызовов вызова.

+0

Ничего себе, огромное спасибо за первый проход! Это очень полезно. Я понимаю, что вы имеете в виду о том, как написано триGeoJSON, и о высоком использовании ЦП - по мере того, как я продвигаюсь вперед, я буду реорганизовать и попытаться очистить. Ваша работа действительно меня заводит. Еще раз спасибо. – sprucegoose

+2

«Результат - бит беспорядок», да, например, «Россия» имеет странное заполнение, потому что оно содержит несколько полигонов, так как оно имеет «geometry.type:« MultiPolygon »в своем json и его« geomety.coordinates » 'array содержит 13 массивов координат. Когда для «Israel» 'geometry.type:« Polygon »и его' geometry.coordinates' содержит только 1 массив координат. – prisoner849

1

У вас есть сегменты, которые образуют контур и рисуют их как линии. Но заполненная форма должна быть построена из треугольников (больше на режимах рисования webgl there).

Чтобы сделать заполненную страну, вам нужно сделать триангуляцию вашего набора сегментов. Существует несколько способов сделать это, и готов к использованию код доступен (например, this earcut implementation).

Однако, поскольку вы хотите отобразить форму на глобусе, следующей проблемой может быть размер произведенных полигонов. Если триангуляция, которую вы используете, создает большие треугольники, и вы преобразовываете вершины в сферические координаты, большие треугольники будут заметными. Здесь можно использовать displacement mapping в фрагментном шейдере или другом треугольнике (например, на основе области треугольников).

Последнее, но не менее важное: триангуляция является дорогостоящим вычислительным, поэтому, если вам не нужно делать это динамически, рассмотрите автономную подготовку геометрии. Если вам нужно триангулировать динамические данные: рассмотрите возможность использования webworker для этой задачи (или супер-быстрый сервер без javascript, если проект большой).

+0

Получил это. Большое спасибо за подробное объяснение! Это действительно помогает мне понять, и я попробую кое-что сделать и сделать больше чтения на основе ссылок, которые вы предоставили. – sprucegoose

+1

Добро пожаловать! Для такой сетки [THREE.BufferGeometry] (https://threejs.org/docs/index.html?q=buff#Reference/Core/BufferGeometry) может быть полезно. – mlkn

 Смежные вопросы

  • Нет связанных вопросов^_^