Как найти положение пользователя на 2-м плане этажа, если другие координаты (3 или более точек) заданы в единстве? - PullRequest
0 голосов
/ 08 ноября 2018

Floor Plan

Можно ли найти положение пользователя, если известны координаты A, B и c, которые приняты как A (floorpointx1, floorpointy1), B(floorpointx2, floorpointy2) и C (floorpointx3, floorpointy3) .D1, D2 и D3 также могут быть предоставлены. Со всеми этими деталями мы можем найти позицию пользователя [Пользователь (floorpoint_x, floorpoint_y)]?

float D1 = Vector3.Distance(userposition, PointAPosition);
float D2 = Vector3.Distance(userposition, PointBPosition);
float D3 = Vector3.Distance(userposition, PointCPosition);

Ответы [ 2 ]

0 голосов
/ 09 ноября 2018

После нашего обсуждения в комментариях, я думаю, что лучшим решением для вашей проблемы является двухмерное преобразование подобия Хелмерта. Если у вас есть 2 или более известных точек на вашей карте этажа и поместите модель / POI в эти точки (другими словами: вы измеряете координаты в системе координат ARKit!), Вы можете рассчитать соотношение между двумя системами координат, и затем вы можете преобразовать свою пользовательскую позицию ARKit в систему координат вашей карты этажа.

Преобразование подобия делает перевод , вращения и масштаба между вашими двумя системами координат. similarity transformation

Здесь вы найдете еще немного информации и пример того, как выглядит преобразование подобия 2d helmert: http://www.geo.itu.edu.tr/dersler/Example%205_2D%20Helmert%20Similarity%20Transformation.pdf Изучите документ и посмотрите на числовой пример на странице 6-8, который не должен быть проблемой для реализации.

0 голосов
/ 09 ноября 2018

Я ожидал найти много ответов о том, как это сделать, но я мог только найти варианты «вот уравнения, сделай это сам». Итак, вот как я могу это сделать, используя класс Geometry, который мне нравится использовать, потому что он облегчает понимание таких вещей.

Большая часть математики от Intersections(Circle c1, Circle c2) от здесь .

Кроме того, я не проверял это, потому что написал здесь, так что если это не сработает, то, по крайней мере, у вас есть с чего начать. Если у вас возникли проблемы, скажите мне, как вы это исправили, и я отредактирую это.

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;
        }
    }
}

Я потратил слишком много времени на это.

...