什么。我要实现的是拥有一个二维坐标数组并将它们映射到一个球体的三维表面。为了弄清楚如何做到这一点,我有一个xy坐标数组
我使用以下循环在每个轴上生成从0到1的20 * 20 xy坐标:
var plot = []
for (var i = 0; i <= 20; i++) {
for (var ii = 0; ii <= 20; ii++) {
plot.push({
x: ii/20,
y: i/20
})
}
}
然后我浏览数组并将xy值转换为xyz值:
for (var i = 0; i < plot.length; i++) {
points.push({
x: Math.sin(plot[i].x*(6.283185307)) * Math.sin(plot[i].y * Math.PI),
y: plot[i].y * 2,
z: Math.cos(plot[i].x*(6.283185307)) * Math.sin(plot[i].y * Math.PI)
});
}
我有两个问题:
我必须使用6.2831 ..因为Math.sin(Math.PI * 2)不会返回0
返回的球体在y轴上不稳定:
答案 0 :(得分:1)
你得到的是围绕y
轴旋转半个正弦波,sin(y*pi/2)
的水平半径为y in 0..2
。因此,尖端在北极和南极。
坐标应使用u=plot[i].x * 2*Math.PI
,v=plot[i].y * Math.PI
x : sin(u)*sin(v)
y : cos(v)
z : cos(u)*sin(v)
这将为您提供单位范围内的点数。您对Math.sin(Math.PI*2)
的担忧是没有根据的,我希望Math.sin(6.283185307)
离零更远,因为该参数是2*pi
的更接近的近似值。 (正如Tomasz Jakub Rup评论中的实际值所证实的那样。)
答案 1 :(得分:1)
在某些应用中,必须确保这些点完全匹配。例如,如果您想构建一个没有边界的球体网格。在这种情况下,您可能需要单独处理边界点。
for (var i = 0; i <= 20; i++) {
for (var ii = 0; ii <= 20; ii++) {
theta = 2* Math.PI * i /20;
phi = Math.PI * ii / 20;
if(ii==0) // North Pole
points.push( {x:0; y:1, z:0} )
else if(ii==20) // South Pole
points.push( {x:0; y:-1, z:0} )
else if(i== 0 || i == 20) // 0º longitude
points.push({ x: 0,
y: Math.cos(phi),
z: Math.sin(phi) } )
else
points.push({ x: Math.sin(theta) * Math.sin(phi),
y: Math.cos(phi),
z: Math.cos(theta) * Math.sin(phi) });
}
}
如果精确坐标很重要,您可以考虑为赤道和90º,180º,270º经度添加案例。