简体   繁体   English

将GPS统一坐标为(X,Y,Z),向北旋转

[英]unity GPS coordinates to (X,Y,Z), rotating north

I'm making an app with Unity3D which uses GPS coordinates to place a "thing" in the 3D world, as you walk in real world close to it, you will find it getting close. 我正在使用Unity3D开发一个应用程序,该应用程序使用GPS坐标在3D世界中放置“物体”,当您在靠近它的真实世界中行走时,您会发现它越来越近。 kinda like PokemonGO 有点像PokemonGO

So the problem is: I managed to place the object at the right place and distance, using a function dist(lat1,lon1,lat2,lon2) which give me the distance in meters between the 2 coordinates (see below). 所以问题是:我使用函数dist(lat1,lon1,lat2,lon2)设法将对象放置在正确的位置和距离处,该函数以米为单位给出了两个坐标之间的距离(见下文)。

What i want to do next is to make the scene turn around the Y axis in order to head north (Z axis+ should be pointing North). 我接下来要做的是使场景绕Y轴旋转以向北行驶(Z轴+应该指向北)。 how do i do this? 我该怎么做呢?

What i did was this: 我所做的是:

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;

But it does weird stuff, the "right" position is both at my right and at my left (why? idk) 但这确实很奇怪,“正确”的位置在我的右边和我的左边(为什么?idk)

{dist function, used to calculate distances between 2 coords:} {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
}

Simplest way to do this will be if you will have every map object assigned to empty as a parent and then rotate. 最简单的方法是将每个地图对象作为父级分配为空,然后旋转。 This way you only need set transform.rotation = Quaternion.Euler (0,Input.compass.trueHeading,0) on empty as 这样,您只需要在empty transform.rotation = Quaternion.Euler (0,Input.compass.trueHeading,0)设置为

Input.compass.trueHeading - The heading in degrees relative to the geographic North Pole Input.compass.trueHeading相对于地理北极的航向,以度为单位

Looking at your code it should look like: 查看您的代码,其外观应类似于:

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;

EDIT. 编辑。 I don't know why in example is a minus, maybe it should be in my code too. 我不知道为什么示例中是负号,也许它也应该在我的代码中。

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

I actually found a solution to my own question, and that is: 我实际上找到了自己的问题的解决方案,那就是:

I take the delta (difference between unity north (z= axis) and the actual geo north) 我采用了增量(统一北(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);
}

then i calculate the angle between the unityNorth and the place where the element should be placed: 然后我计算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);

And then place the object at the right angle 然后将物体垂直放置

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

Where old_compass is the value of Input.compass.trueHeading when the scene loads 其中old_compass是场景加载时Input.compass.trueHeading的值

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 将 GPS 坐标转换为 X、Y、Z 坐标 - Converting GPS coordinates to X, Y, Z coordinates 在 Unity 中旋转 object 时,脚本不会在 Z 轴上旋转 object,只有 X 和 Y? - When rotating an object in Unity, the script doesn't rotate the object on the Z-axis, only the X and Y? 为什么 object 也在 x 和 z 上旋转? 它应该只在 y 上旋转 - Why the object is rotating also on x and z ? It should be rotating only on y 为什么在 z 轴上旋转对象时,它也会旋转 x 和 y 而没有将 z 设置为 0? - Why when rotating the object on z axis it's rotating also the x and y and not setting z to 0? Unity 3D中如何将对象移动到鼠标的z和y坐标 - How to move objects to the z and y coordinates of the mouse in Unity 3D 在 Unity 中围绕 X 和 Y 轴旋转对象问题 - Rotating an object around X and Y axis issue in Unity Unity - 如何检查在 x,y,z 位置是否有特定 Tilemap 的 Tile - Unity - How to check if there is a Tile of an specific Tilemap in the position x,y,z 在Unity中更改x和y旋转也会怪异地更改z - Changing the x and y rotation weirdly changes the z too in Unity Unity - 弹丸运动,找到击中坐标 x,y 所需的角度 - Unity - Projectile Motion, find the angle needed to hit coordinates x,y Unity3D仅在x和z轴上旋转时如何防止“倾斜”? - Unity3D How to Prevent “Tilt” when rotating on x and z axis only?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM