【问题标题】:unity GPS coordinates to (X,Y,Z), rotating north统一 GPS 坐标到 (X,Y,Z),向北旋转
【发布时间】:2016-09-12 16:38:48
【问题描述】:

我正在使用 Unity3D 制作一个应用程序,它使用 GPS 坐标在 3D 世界中放置一个“东西”,当你在现实世界中靠近它时,你会发现它越来越近。有点像PokemonGO

所以问题是: 我使用函数 dist(lat1,lon1,lat2,lon2) 设法将对象放置在正确的位置和距离上,它给出了两个坐标之间的距离(以米为单位)(见下文)。

接下来我要做的是让场景围绕 Y 轴转向以向北行驶(Z 轴+ 应该指向北方)。我该怎么做?

我做的是这样的:

float xx = dist (0, Tlon, 0, lon), zz = dist (Tlat, 0, lat, 0);
Vector3 position = new Vector3 (xx, 0, zz);
position.Normalize ();
float beta = Mathf.Acos(position.z) * Mathf.Rad2Deg;
position = Quaternion.Euler (0,beta-Input.compass.trueHeading,0)*position;
transform.position = position;

但它做了一些奇怪的事情,“正确”的位置在我的右边和左边(为什么?idk)

{dist函数,用于计算2个坐标之间的距离:}

float dist(float lat1, float lon1, float lat2, float lon2){  // generally used geo measurement function
    var R = 6378.137; // Radius of earth in KM
    var dLat = (lat2 - lat1) * Mathf.PI / 180;
    var dLon = (lon2 - lon1) * Mathf.PI / 180;
    var a = Mathf.Sin(dLat/2) * Mathf.Sin(dLat/2) +
        Mathf.Cos(lat1 * Mathf.PI / 180) * Mathf.Cos(lat2 * Mathf.PI / 180) *
        Mathf.Sin(dLon/2) * Mathf.Sin(dLon/2);
    var c = 2 * Mathf.Atan2(Mathf.Sqrt(a), Mathf.Sqrt(1-a));
    var d = R * c;
    return (float)(d * 1000); // meters
}

【问题讨论】:

    标签: unity3d gps compass-geolocation


    【解决方案1】:

    执行此操作的最简单方法是将每个地图对象作为父对象分配为空,然后旋转。这样你只需要将transform.rotation = Quaternion.Euler (0,Input.compass.trueHeading,0)设置为空为

    Input.compass.trueHeading - 相对于 地理北极

    看看你的代码应该是这样的:

    float xx = dist (0, Tlon, 0, lon), zz = dist (Tlat, 0, lat, 0);
    Vector3 position = new Vector3 (xx, 0, zz);
    position.Normalize ();
    position = Quaternion.AngleAxis(Input.compass.trueHeading, Vector3.up) * position;
    transform.position = position;
    

    编辑。我不知道为什么在示例中是减号,也许它也应该在我的代码中。

    transform.rotation = Quaternion.Euler(0, -Input.compass.trueHeading, 0);

    【讨论】:

      【解决方案2】:

      我实际上找到了解决我自己问题的方法,那就是:

      我采用三角洲(统一北(z = 轴)和实际地理北之间的差异)

      if (delta == 0 && (gcb.activeSelf||head.transform.eulerAngles.y!=0)) {
          Vector3 fwd = new Vector3 (0, 0, 1);
          Vector3 north = Quaternion.Euler (0, Input.compass.trueHeading, 0) * fwd;
          delta = SignedAngle(fwd,north) + (360-head.transform.eulerAngles.y);
      }
      

      然后我计算 unityNorth 和应该放置元素的位置之间的角度:

      float xx = dist (0, Tlon, 0, lon), zz = dist (Tlat, 0, lat, 0);
      Vector3 position = new Vector3 (xx, 0, zz); //the position of the target if unityNorth and actual geoNorth were the same
      position.Normalize ();
      Vector3 unityN = new Vector3 (0,0,1); // unity north
      angoloTrgt = Vector3.Angle (unityN, position);
      position *= MIN_CUBE_DIST;
      target.transform.position = new Vector3 (0,0,MIN_CUBE_DIST);
      

      然后把物体放在直角

      bollettino.transform.RotateAround (Vector3.zero, Vector3.up,  angoloTrgt - old_compass-delta);
      

      其中 old_compass 是场景加载时 Input.compass.trueHeading 的值

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-05-30
        • 2010-12-28
        • 1970-01-01
        • 1970-01-01
        • 2019-11-23
        • 2022-12-10
        • 1970-01-01
        相关资源
        最近更新 更多