代码之家  ›  专栏  ›  技术社区  ›  zyonneo

如果其他坐标(3个或更多点)以统一形式给出,如何在二维平面图上找到用户位置?

  •  1
  • zyonneo  · 技术社区  · 7 年前

    Floor Plan

    如果A、B和c的坐标已知,并且取为A(floorpointx1、floorpointy1)、B(floorpointx2、floorpointy2)和c(floorpointx3、floorpointy3),是否可以找到用户的位置。还可以提供D1、D2和D3。有了所有这些详细信息,我们可以找到用户的位置[用户(floorpoint_x、FloorPointy)]?

    float D1 = Vector3.Distance(userposition, PointAPosition);
    float D2 = Vector3.Distance(userposition, PointBPosition);
    float D3 = Vector3.Distance(userposition, PointCPosition);
    
    2 回复  |  直到 7 年前
        1
  •  0
  •   SonicBlue22    7 年前

    我希望能找到很多关于如何做到这一点的答案,但我只能找到“这是方程式,自己动手”的变体。下面是我如何使用一个几何类来做的,我喜欢使用这个类,因为它使这样的东西更容易理解。

    大部分的数学知识都来自 Intersections(Circle c1, Circle c2) 来自 here .

    namespace StuffYouStoleFromStackOverflow {
        public static class Geometry {
            public enum AngleType { Radians, Degrees }
    
            public static float GetAngle(Vector2 v1, Vector2 v2, AngleType units = AngleType.Degrees) { return GetAngle(v1.x, v1.y, v2.x, v2.y, units); }
            public static float GetAngle(float x1, float y1, float x2, float y2, AngleType units = AngleType.Degrees) {
                if(units == AngleType.Radians) return Mathf.Atan2(y1 - y2, x1 - x2);
                else return Mathf.Atan2(y1 - y2, x1 - x2) * Mathf.Rad2Deg;
            }
    
            public static Vector2[] Intersection(Circle c1, Circle c2) {
                float r1 = c1.radius, r2 = c2.radius;
                float d = Vector2.Distance(c1.center, c2.center);
                if(d > c1.radius + c2.radius) {
                Vector2[] i = {   // only gets here if there is no real intersection
                        Vector2.Lerp(c1.center, c2.center, c1.radius / d),
                        Vector2.Lerp(c1.center, c2.center, c2.radius / d)
                    };
                    return i;
                }
    
                // squared versions of the variables, because we use them a lot.
                float d_2 = d * d, r1_2 = r1 * r1, r2_2 = r2 * r2;
    
                float b = d_2 - r1_2 + r2_2;
                float x = b / (2 * d);
                float a = (1 / d) * Mathf.Sqrt((4 * d_2 * r2_2) - (b * b));
                float y = (a / 2);
    
                float angle = GetAngle(c1.center, c2.center, AngleType.Radians);
    
                Vector2[] intersections = new Vector2[2];
                intersections[0] = new Vector2(x, +y).Rotate(angle, AngleType.Radians) + c1.center;
                intersections[1] = new Vector2(x, -y).Rotate(angle, AngleType.Radians) + c1.center;
    
                return intersections;
            }
    
            public static Vector2 Intersection(Circle c1, Circle c2, Circle c3) {
                var i1 = Intersection(c1, c2);
                var i2 = Intersection(c1, c3);
    
                int smallest = 0;
                float[] D = new float[4];
                D[0] = Vector2.Distance(i1[0], i2[0]);
                D[1] = Vector2.Distance(i1[0], i2[1]);
                D[2] = Vector2.Distance(i1[1], i2[0]);
                D[3] = Vector2.Distance(i1[1], i2[1]);
    
                for(int j < 1; j < 4; j++)
                    if(D[smallest] > D[j]) smallest = j;
    
                else return i2[smallest % 2]; //not 100% sure on this part, might be i1 instead?
            }
    
            public class Circle {
                public Vector2 center;
                public float radius;
                public Circle(Vector2 center, float radius) {
                    this.center = center;
                    this.radius = radius;
                }
            }
    
            public static Vector2 Rotate(this Vector2 vector, float angle, AngleType units = AngleType.Degrees) {
                if(units == AngleType.Degrees) angle * Mathf.Deg2Rad;
                float sin = Mathf.Sin(angle), cos = Mathf.Cos(angle);
                vector.x = (cos * vector.x) - (sin * vector.y);
                vector.y = (sin * vector.x) + (cos * vector.y);
                return vector;
            }
        }
    }
    

    我在这上面花了太长时间。

        2
  •  0
  •   Community Mohan Dere    5 年前

    经过我们在评论中的讨论,我认为解决您的问题的最佳方案是2D helmert相似性变换。如果在楼层地图中有2个或多个已知点,并在这些点上放置模型/POI(换句话说:您正在测量ARKit坐标系中的坐标!)可以计算两个坐标系之间的关系,然后可以将用户ARKit位置转换为楼层地图坐标系。

    相似性变换产生了一个 翻译 旋转 规模 similarity transformation

    http://www.geo.itu.edu.tr/dersler/Example%205_2D%20Helmert%20Similarity%20Transformation.pdf

    推荐文章