javascript - D3+三.js : graticule projection - cannot apply projection to graticule

标签 javascript d3.js svg three.js

我正在尝试在 three.js 中创建 3D 标线。当前的这项工作首先使用 D3 在 SVG 中构建一个 mollweide 投影标线。然后它提取网格路径点,将它们转换为 three.js 向量。

但是,生成的 three.js 标线只是一个球体标线,不会响应所需的投影(mollweide)点。有什么想法吗?

这显示在下面的文件中。违规功能是vertex(point)

 <!DOCTYPE HTML>

<html>

<head>
<script src="https://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="https://d3js.org/d3.geo.projection.v0.min.js"></script>
<script src="https://d3js.org/d3-array.v1.min.js"></script>
<script src="https://rawgit.com/mrdoob/three.js/r86/build/three.min.js"></script>
<script src="https://rawgit.com/mrdoob/three.js/r86/examples/js/controls/OrbitControls.js"></script>

  <title>3D Mollweide Projection</title>
  <style type="text/css">
  <!--
 .background {
  fill: #a4bac7;
}

.foreground {
  fill: none;
  stroke: #333;
  stroke-width: 1.5px;
}

.graticule {
  fill: none;
  stroke: #fff;
  stroke-width: .5px;
}


  -->
  </style>
</head>

<body style=font-family:arial>

<center>SVG Drawing (mollweide projection):</center>
<svg id=projectionSVG width=600 height=440 overflow=visible />
Three.js Drawing (rotate and mousewheel zoom):<br>
<div  id=container></div>

<script>
var projection
var gratPathPointArray=[]
var radius = 230


//----build svg graticule----
    projection = d3.geo.mollweide()
    .scale(120);

    var path = d3.geo.path()
    .projection(projection);

    var graticule = d3.geo.graticule();

    var svg= d3.select("#projectionSVG")
    svg.append("path")
    .datum(graticule.outline)
    .attr("class", "background")
    .attr("d", path);

    var graticuleG=svg.append("g")
    .attr("class", "graticule")
    .selectAll("path")
    .data(graticule.lines)
    .enter().append("path")
    .attr("d", path);


    var graticulePathG=projectionSVG.lastChild

    var graticulePaths=graticulePathG.childNodes
    for(p=0;p<graticulePaths.length;p++)
    {
        var holdArray=[]
        var graticulePath=graticulePaths[p]
        var d=graticulePath.getAttribute("d")
        var d=d.replace(/M/,"").replace(/L/g,",")
        var dSplit=d.split(",")
        for(var k=0;k<dSplit.length;k++)
        {
        var x=dSplit[k]
        var y=dSplit[k+1]
        holdArray.push([x,y])
        k++
        }
        gratPathPointArray.push(holdArray)
    }

    threeJSVectors()

function threeJSVectors()
{
    initThree()

    var geometry = new THREE.Geometry();
    var material= new THREE.LineBasicMaterial({color: 0xaaaaaa})


    var splineVectors=[]
    //=========graticule lines==============
    gratPathPointArray.forEach(function(line)
    {
        d3.pairs(line.map(vertex), function(a, b)
        {
            geometry.vertices.push(a, b);
        });
    });

    scene.add( new THREE.LineSegments(geometry, material))

    animate()
    render()
}

//----build three.js graticule---
var renderer,camera,controls,scene
function initThree()
{
    var width = 600,
    height = 600

    scene = new THREE.Scene;
    camera = new THREE.PerspectiveCamera(70, width / height, 1, 1000);
    renderer = new THREE.WebGLRenderer({alpha: true});

    camera.position.x = -7;
    camera.position.y = -245;
    camera.position.z = 315;
    renderer.setPixelRatio(window.devicePixelRatio);
    renderer.setSize(width, height);
    container.appendChild(renderer.domElement);
    controls = new THREE.OrbitControls( camera,renderer.domElement );
    controls.addEventListener( 'change', render );
}
//---does not apply projection????---
//--convert path point to vector---
function vertex(point)
{
    //---get lng/lat degrees of each projection point--
     var invertLL=projection.invert(point)
       //---to radians--
    var lambda = invertLL[0] * Math.PI / 180,
    phi = invertLL[1] * Math.PI / 180,
    cosPhi = Math.cos(phi);
    return new THREE.Vector3(
        radius * cosPhi * Math.cos(lambda),
        radius * cosPhi * Math.sin(lambda),
        radius * Math.sin(phi)
    );
}

function animate()
{
	requestAnimationFrame(animate);
	controls.update();
}

function render()
{
	camera.lookAt( scene.position );
    renderer.render(scene, camera);

}
</script>

</body>
</html>

最佳答案

我不知道你想在那里做什么 :) 你的顶点(点)函数正确地确定了 2D 点的 3D 位置,从而重建了地球。但是,如果您只想要平面形状,请检查以下内容:

 <!DOCTYPE HTML>

<html>

<head>
<script src="https://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="https://d3js.org/d3.geo.projection.v0.min.js"></script>
<script src="https://d3js.org/d3-array.v1.min.js"></script>
<script src="https://rawgit.com/mrdoob/three.js/r86/build/three.min.js"></script>
<script src="https://rawgit.com/mrdoob/three.js/r86/examples/js/controls/OrbitControls.js"></script>

  <title>3D Mollweide Projection</title>
  <style type="text/css">
  <!--
 .background {
  fill: #a4bac7;
}

.foreground {
  fill: none;
  stroke: #333;
  stroke-width: 1.5px;
}

.graticule {
  fill: none;
  stroke: #fff;
  stroke-width: .5px;
}


  -->
  </style>
</head>

<body style=font-family:arial>

<center>SVG Drawing (mollweide projection):</center>
<svg id=projectionSVG width=600 height=440 overflow=visible />
Three.js Drawing (rotate and mousewheel zoom):<br>
<div  id=container></div>

<script>
var projection
var gratPathPointArray=[]
var radius = 230


//----build svg graticule----
    projection = d3.geo.mollweide()
    .scale(120);

    var path = d3.geo.path()
    .projection(projection);

    var graticule = d3.geo.graticule();

    var svg= d3.select("#projectionSVG")
    svg.append("path")
    .datum(graticule.outline)
    .attr("class", "background")
    .attr("d", path);

    var graticuleG=svg.append("g")
    .attr("class", "graticule")
    .selectAll("path")
    .data(graticule.lines)
    .enter().append("path")
    .attr("d", path);


    var graticulePathG=projectionSVG.lastChild

    var graticulePaths=graticulePathG.childNodes
    for(p=0;p<graticulePaths.length;p++)
    {
        var holdArray=[]
        var graticulePath=graticulePaths[p]
        var d=graticulePath.getAttribute("d")
        var d=d.replace(/M/,"").replace(/L/g,",")
        var dSplit=d.split(",")
        for(var k=0;k<dSplit.length;k++)
        {
        var x=dSplit[k]
        var y=dSplit[k+1]
        holdArray.push([x,y])
        k++
        }
        gratPathPointArray.push(holdArray)
    }

    threeJSVectors()

function threeJSVectors()
{
    initThree()

    var geometry = new THREE.Geometry();
    var material= new THREE.LineBasicMaterial({color: 0xaaaaaa})


    var splineVectors=[]
    //=========graticule lines==============
    gratPathPointArray.forEach(function(line)
    {
        d3.pairs(line.map(vertex), function(a, b)
        {
            geometry.vertices.push(a, b);
        });
    });

    scene.add( new THREE.LineSegments(geometry, material))

    animate()
    render()
}

//----build three.js graticule---
var renderer,camera,controls,scene
function initThree()
{
    var width = 600,
    height = 600

    scene = new THREE.Scene;
    camera = new THREE.PerspectiveCamera(70, width / height, 1, 1000);
    renderer = new THREE.WebGLRenderer({alpha: true});

    camera.position.x = -7;
    camera.position.y = -245;
    camera.position.z = 315;
    renderer.setPixelRatio(window.devicePixelRatio);
    renderer.setSize(width, height);
    container.appendChild(renderer.domElement);
    controls = new THREE.OrbitControls( camera,renderer.domElement );
    controls.addEventListener( 'change', render );
}
//---does not apply projection????---
//--convert path point to vector---
function vertex(point)
{
    return new THREE.Vector3(
        point[0] - 500,
        point[1] - 150,
        0
    );
}

function animate()
{
	requestAnimationFrame(animate);
	controls.update();
}

function render()
{
	camera.lookAt( scene.position );
    renderer.render(scene, camera);

}
</script>

</body>
</html>

关于javascript - D3+三.js : graticule projection - cannot apply projection to graticule,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45000507/

相关文章:

html - Masking SVG-filter,不是简单地将mask和filter结合起来

javascript - d3.js 条形图不太像我想要的

javascript - 多个表行作为 backbone.js View ?

html - 如何将 REST 响应放回 angular JS 标签中以绘制 D3 js 饼图

javascript - 如何重置 svg 缩放并适合屏幕以获取具有不同方向的随机但大型 map /数据集

d3.js - 在直流系列图中设置 Y 轴范围

javascript - 缩放 D3 强制布局链接标记上的箭头

javascript - Meteor,将脚本移动到页面底部

javascript - 输出带引号的数组时出现问题

javascript - 使用 jQuery 在 input->value 中插入值