【问题标题】:Latitude and Longitude to Vector3 Not Aligning on 3D SphereVector3的纬度和经度未在3D球体上对齐
【发布时间】:2020-01-12 17:33:03
【问题描述】:

我正在尝试将纬度和经度转换为 Vector3 格式。对于给定的纬度和经度,我想将其转换为 Vector3,其中标记对象将定位在此 Vector3 位置。

这是我的代码:

void createLand()
{
    double latitude_rad = (latitude) * Math.PI / 180;
    double longitude_rad = (longitude) * Math.PI / 180;

    double xPos = (radiusEarth * Math.Cos((latitude_rad)) * Math.Cos((longitude_rad)));
    double yPos = (radiusEarth * Math.Cos((latitude_rad)) * Math.Sin((longitude_rad)));
    double zPos = (radiusEarth * Math.Sin((latitude_rad)));

    markerPos.x = (float)xPos;
    markerPos.y = (float)yPos;
    markerPos.z = (float)zPos;

    ObjectMarker.position = markerPos;
}

我使用 6371 作为 radiusEarth,这是伦敦 lat:51.509865, lon:-0.118092 的输出:

这是北极的输出,纬度:90,经度:135:

标记(即闪亮的小球)位置错误。

我的转换有什么问题吗?或者有没有其他方法可以解决这个问题?

编辑...

我用过的地球贴图可以在here找到,是10K的图。我构建了球体并使用 Blender 应用了纹理 - 我对球体应用了旋转,以便前视图将反映 lat,long: 0,0 的位置。

创建地球对象的代码:

void createEarth()
{
    ObjectEarth.gameObject.transform.localScale = 1f * radiusEarth * Vector3.one;
}

编辑 2...

这是使用 Unity 的预定义向量时放置标记的位置:

void createLand()
{
    ObjectMarker.position = radiusEarth * Vector3.forward;
}

void createLand()
{
    ObjectMarker.position = radiusEarth * Vector3.right;
}

void createLand()
{
    ObjectMarker.position = radiusEarth * Vector3.up;
}

【问题讨论】:

  • 它几乎就像下面的球体在两个方向上都偏离了 90.. 由于图片与北极点对齐,我认为伦敦会在正确的位置..
  • 您的数学似乎是正确的,当您拍摄这些屏幕截图时,您的球体和相机/检查器视图的方向是什么?
  • 请包含您正在使用的纹理以及将创建球体并将纹理应用到球体以制作minimal reproducible example的代码。
  • @NSJacob1 - 地球球体没有应用任何旋转。拍摄上述屏幕截图时,Inspector 设置为前视图
  • @Ruzihm - 我创建了一个编辑,解释了如何创建球体以及如何应用纹理。

标签: c# unity3d vector coordinates


【解决方案1】:

您在转换为 3d 空间时使用了错误的坐标轴。

  • Y 是上/下轴,所以绝对应该是@​​987654321@。
  • 0,0 位于z = 1*radiusEarth,因此 z 必须是 cos*cos 的那个。
  • 0,90 位于x = -1 * radiusEarth,因此 x 需要为负 cos*sin。

总共:

void createLand()
{
    double latitude_rad = latitude * Math.PI / 180;
    double longitude_rad = longitude * Math.PI / 180;

    double zPos = radiusEarth * Math.Cos(latitude_rad) * Math.Cos(longitude_rad);
    double xPos = -radiusEarth * Math.Cos(latitude_rad) * Math.Sin(longitude_rad);
    double yPos = radiusEarth * Math.Sin(latitude_rad);

    markerPos.x = (float)xPos;
    markerPos.y = (float)yPos;
    markerPos.z = (float)zPos;

    ObjectMarker.position = markerPos;
}

【讨论】:

  • @SidS 我根据问题中显示的图像更新了答案。注意double xPos = -radiusEarth * Math.Cos(latitude_rad) * Math.Sin(longitude_rad); 中的负数以及匹配的markerPos.x = (float)xPos;markerPos.y = (float)yPos;markerPos.z = (float)zPos;
  • 刚刚尝试了上面的代码,使用 lat, long, 90, 135,标记按预期与北极对齐,尽管当使用 0,0 时,标记会转到原点,即在中心,在地球范围内
  • @SidS 这真的很奇怪,因为double zPos = radiusEarth * Math.Cos(latitude_rad) * Math.Cos(longitude_rad); 应该是zPos = radiusEarth;...所以它不应该在地球内部,对吧?似乎我忽略了另一个错字或将其复制到您的脚本时出错。
  • 我刚刚复制并粘贴了代码,是的,它应该在地球内部。我会检查我的脚本以确保我的结果没有任何问题。
  • 答案中的新代码是正确的,问题在我这边。谢谢!
猜你喜欢
  • 1970-01-01
  • 2018-01-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-13
  • 2012-03-29
  • 2010-10-11
  • 1970-01-01
相关资源
最近更新 更多