D3+Three.js:经纬网投影 - 不能将投影应用于经纬网



我正在尝试在三个.js中创建3D经纬网。目前的工作首先使用 D3 在 SVG 中构建一个 mollweide 投影刻度。然后,它提取经纬网路径点,将它们转换为三个.js向量。

然而,得到的三个.js经纬网只是一个球面经纬网,并且不响应所需的投影(mollweide(点。有什么想法吗?

这显示在下面的文件中。有问题的函数是顶点(点(

<!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>

最新更新