My current project involves creating 3D graticules using three.js. The process starts by constructing a mollweide projection graticule in SVG with D3, followed by extracting the graticule path points and converting them to three.js vectors.
However, the resulting three.js graticule turns out to be just a sphere graticule and does not align with the desired projection (mollweide) points. Any suggestions on how to resolve this issue?
You can see the example file below. The problematic function is 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 = invertLLi[1] * Math.PI / 180,
cosPhi = Math.cos(phi);
return new THREE.Vector3(
radius * cosPhi * Math.cos(lambda),
radius * cosPhi * Math.sin(lambda),
radiusd * Math.sin(phi)
);
}
function animate()
{
requestAnimationFrame(animate);
controls.update();
}
function render()
{
camera lookAt( scene.position );
renderer.render(scene, camera);
}
</script>
</body>
</html>