Exemple #1
0
        /// <summary>
        /// Két, a középpontjával és sugarával adott körnek számolja ki a metszéspontjait, ha lézetnek, vagy létezik
        /// </summary>
        /// <param name="P0">Az első kör középpontja</param>
        /// <param name="r0">Az első kör sugara</param>
        /// <param name="P1">A második kör középpontja</param>
        /// <param name="r1">A második kör sugara</param>
        /// <returns>Az Intersection objektum a metszéspontokat reprezentálja, melyben egy lista tárolja, hogy hány metszéspontja van a két körnek</returns>
        public static Intersection CalculateIntersection(Point P0, double r0, Point P1, double r1)
        {
            double d, a, h;
            Point  P2, isPoint1, isPoint2;

            d = LocationCalculator.Distance(P0, P1);

            if (d > r0 + r1)
            {
                return(new Intersection(new List <Point>()));               // Két külön körről van szó
            }
            if (d < Math.Abs(r0 - r1))
            {
                return(new Intersection(new List <Point>()));                        // Az egyik kör a másikon belül van
            }
            if (d == 0 && r0 == r1)
            {
                return(new Intersection(null));                         // A két kör éppen egybeesik
            }
            //TODO: megvizsgálni, hogy két metszéspont lesz, egy, végtelen, vagy nem érintkeznek

            a  = (Math.Pow(r0, 2) - Math.Pow(r1, 2) + Math.Pow(d, 2)) / (2 * d);
            h  = Math.Sqrt(Math.Pow(r0, 2) - Math.Pow(a, 2));
            P2 = new Point(P0.X + a * (P1.X - P0.X) / d, P0.Y + a * (P1.Y - P0.Y) / d);

            isPoint1 = new Point(P2.X + h * (P1.Y - P0.Y) / d, P2.Y - h * (P1.X - P0.X) / d);
            isPoint2 = new Point(P2.X - h * (P1.Y - P0.Y) / d, P2.Y + h * (P1.X - P0.X) / d);

            // Ha a két kör éppen érinti egymást egy ponton (d = r1 + r2), akkor is két pont lesz a metszet eredménye, de ezek egybeesnek
            List <Point> solutions = new List <Point>();

            solutions.Add(isPoint1);
            solutions.Add(isPoint2);
            return(new Intersection(solutions));
        }
        /// <summary>
        /// Első eset: a két távolság által jelzett kör messze van egymástól:
        /// Megoldás: mindkettőt arányosan növeljük
        /// </summary>
        protected bool CheckFarDistances(NearbyBluetoothTag tag1, NearbyBluetoothTag tag2)
        {
            if (LocationCalculator.Distance(tag1.Origo, tag2.Origo) > tag1.AveragePredictedDistanceFromTag + tag2.AveragePredictedDistanceFromTag)
            {
                double deviance = LocationCalculator.Distance(tag1.Origo, tag2.Origo) - (tag1.AveragePredictedDistanceFromTag + tag2.AveragePredictedDistanceFromTag);
                deviance += BIAS;  // Az eltérés torzítása, így biztosan lesz metszéspont
                double max   = tag1.AveragePredictedDistanceFromTag + tag2.AveragePredictedDistanceFromTag;
                double rate1 = tag1.AveragePredictedDistanceFromTag / max;
                double rate2 = tag2.AveragePredictedDistanceFromTag / max;
                tag1.SetAveragePredictedDistance(tag1.AveragePredictedDistanceFromTag + deviance * rate1);
                tag2.SetAveragePredictedDistance(tag2.AveragePredictedDistanceFromTag + deviance * rate2);


                //TEST
                double dist = LocationCalculator.Distance(tag1.Origo, tag2.Origo) - (tag1.AveragePredictedDistanceFromTag + tag2.AveragePredictedDistanceFromTag);
                if (dist > 0.0)
                {
                    dist = 0; /* throw new Exception("Calculation error: distance must be 0.0"); */
                }
                //TEST

                return(true);
            }
            else
            {
                return(false);
            }
        }
Exemple #3
0
        /// <summary>
        /// !!! Ez csak pontos esetben működik !!!
        ///
        /// Minden metszet minden pontját megvizsgáljuk, és az elsőhöz viszonyítjuk.
        /// Feltesszük, hogy minden metszet tartalmaz egy pontot, amely közös a többivel, így az első is.
        /// Ezért azt keressük, hogy az első metszet első, vagy második pontja a közös pont.
        /// </summary>
        public override Point CalculateCommonPoint(List <Intersection> intersections)
        {
            double minDist     = LocationCalculator.Distance(intersections[0].Points[0], intersections[1].Points[0]);
            Point  commonPoint = intersections[0].Points[0];

            for (int pointIdx = 0; pointIdx < 2; pointIdx++)
            {
                Point ip1 = intersections[0].Points[pointIdx];
                for (int i = 1; i < intersections.Count; i++)
                {
                    for (int otherPointIdx = 0; otherPointIdx < 2; otherPointIdx++)
                    {
                        Point  ip2 = intersections[i].Points[otherPointIdx];
                        double d   = LocationCalculator.Distance(ip1, ip2);
                        if (d < minDist)
                        {
                            minDist     = d;
                            commonPoint = ip1;
                            if (pointIdx == 1)
                            {
                                return(commonPoint);               // Ha az első pont nem jó, és találtunk kisebb távolságot, akkor ez lesz a közös pont
                            }
                        }
                    }
                }
            }

            return(commonPoint);
        }
Exemple #4
0
 /// <summary>
 /// Az egyik tag távolságából felírható kör tartalmazza-e a másik tag távolsága alapján felírható kört (average predicted distance alapján)
 /// </summary>
 public bool Includes(NearbyBluetoothTag tag)
 {
     if (this.avgPredictedDistance > LocationCalculator.Distance(this.origo, tag.origo) + tag.avgPredictedDistance)
     {
         return(true);
     }
     return(false);
 }
        private Point getClosestPoint(Point P, List <Point> IntersectionPoints)
        {
            int    mini = 0;
            Point  intersectionPoint;
            double mindist = LocationCalculator.Distance(P, IntersectionPoints[0]);
            double dist;

            for (int i = 1; i < IntersectionPoints.Count; i++)
            {
                intersectionPoint = IntersectionPoints[i];
                dist = LocationCalculator.Distance(P, intersectionPoint);
                if (dist < mindist)
                {
                    mini    = i;
                    mindist = dist;
                }
            }
            return(IntersectionPoints[mini]);
        }
Exemple #6
0
        public double DeviceMotion(Point DevicePosition)
        {
            double distanceFromTag = LocationCalculator.Distance(origo, DevicePosition);

            label_distance.Content = Math.Round(distanceFromTag, 2);
            if (distanceFromTag > zoneRadius)
            {
                if (hasDevice)
                {
                    background.Children.Remove(deviceDistance);
                    background.Children.Remove(line_radius);
                    background.Children.Remove(predictedDistance);
                    background.Children.Remove(label_prediction);
                    background.Children.Remove(avgPredictedDistance);
                    background.Children.Remove(label_avg_prediction);
                    hasDevice = false;
                    contactEventHandler.DeviceLeft(origo);
                }
            }
            else if (!hasDevice)
            {
                background.Children.Add(deviceDistance);
                background.Children.Add(line_radius);
                background.Children.Add(predictedDistance);
                background.Children.Add(label_prediction);
                background.Children.Add(avgPredictedDistance);
                background.Children.Add(label_avg_prediction);
                predictedDistance.Visibility = Visibility.Hidden;
                label_prediction.Visibility  = Visibility.Hidden;
                hasDevice = true;
                contactEventHandler.DeviceAppear(origo, distanceFromTag, mac);
            }
            Canvas.SetLeft(deviceDistance, origo.X - distanceFromTag);
            Canvas.SetTop(deviceDistance, origo.Y - distanceFromTag);
            deviceDistance.Width  = distanceFromTag * 2;
            deviceDistance.Height = distanceFromTag * 2;
            line_radius.X1        = origo.X;
            line_radius.Y1        = origo.Y;
            line_radius.X2        = DevicePosition.X;
            line_radius.Y2        = DevicePosition.Y;

            return(distanceFromTag);
        }
        /// <summary>
        /// Második eset: az egyik kör a másikon belül helyezkedik el:
        /// Megoldás: a nagyobb kört arányosan csökkentjük, a kisebb kört pedig arányosan növeljük
        /// </summary>
        protected bool CheckInclude(NearbyBluetoothTag tag1, NearbyBluetoothTag tag2)
        {
            NearbyBluetoothTag bigger, smaller;

            if (tag1.Includes(tag2))
            {
                bigger  = tag1;
                smaller = tag2;
            }
            else if (tag2.Includes(tag1))
            {
                bigger  = tag2;
                smaller = tag1;
            }
            else
            {
                return(false);
            }

            double deviance = bigger.AveragePredictedDistanceFromTag - (LocationCalculator.Distance(bigger.Origo, smaller.Origo) + smaller.AveragePredictedDistanceFromTag);

            deviance += BIAS;   // Az eltérés torzítása, így biztosan lesz metszéspont
            double max   = bigger.AveragePredictedDistanceFromTag + smaller.AveragePredictedDistanceFromTag;
            double brate = bigger.AveragePredictedDistanceFromTag / max;
            double srate = smaller.AveragePredictedDistanceFromTag / max;

            bigger.SetAveragePredictedDistance(bigger.AveragePredictedDistanceFromTag - deviance * brate);
            smaller.SetAveragePredictedDistance(smaller.AveragePredictedDistanceFromTag + deviance * srate);


            //TEST
            double dist = bigger.AveragePredictedDistanceFromTag - (LocationCalculator.Distance(bigger.Origo, smaller.Origo) + smaller.AveragePredictedDistanceFromTag);

            if (dist > 0.0)
            {
                dist = 0; /* throw new Exception("Calculation error: distance must be 0.0"); */
            }
            //TEST

            return(true);
        }
        public LocationResult CalculateLocation(List <NearbyBluetoothTag> NearbyDistances, LocationResult LastLocation)
        {
            List <NearbyBluetoothTag> Distances = NearbyDistances.ToList <NearbyBluetoothTag>();

            Distances.RemoveAll(tag => tag.AverageRSSI == 0.0);
            if (Distances.Count == 0)
            {
                return(new LocationResult(new Point(-1, -1), Precision.NoTag));
            }
            if (Distances.Count == 1)
            {
                return(new LocationResult(Distances[0].Origo, Precision.OneTag, Distances[0].AveragePredictedDistanceFromTag)); // 1 vagy semennyi kör esetén nem tudunk pozíciót meghatározni
            }
            if (Distances.Count == 2)                                                                                           // 2 kör esetén a metszet két pontja közti felezőpont kell
            {
                ForceAllIntersections(Distances);
                Intersection points = Intersection.CalculateIntersection(Distances[0].Origo, Distances[0].AveragePredictedDistanceFromTag, Distances[1].Origo, Distances[1].AveragePredictedDistanceFromTag);
                return(new LocationResult(LocationCalculator.Midpoint(points.Points[0], points.Points[1]), Precision.TwoTag, LocationCalculator.Distance(points.Points[0], points.Points[1]) / 2));
            }

            return(CalculateCommonPoint(Distances, LastLocation));
        }
Exemple #9
0
        protected override LocationResult CalculateCommonPoint(List <NearbyBluetoothTag> Distances, LocationResult LastLocation)
        {
            List <Point> adjacentPoints = new List <Point>(); // ebben lesznek az egyes metszetek legközelebbi pontjai után kiválogatott szomszédos pontok

            // kiszámoljuk minden kör, minden másik körhöz mért metszéspontját
            List <Intersection> intersectionPoints = GetIntersections(Distances); // ebben lesznek két-két kör metszéspontjai

            // eddig jó
            for (int i = 0; i < intersectionPoints.Count; i++)
            {
                for (int j = i + 1; j < intersectionPoints.Count; j++)
                {
                    if (i == j)
                    {
                        continue;
                    }
                    adjacentPoints.Add(LocationCalculator.ClosestPoint(intersectionPoints[i], intersectionPoints[j]));
                }
            }

            return(new LocationResult(LocationCalculator.PointAverage(adjacentPoints), Precision.ThreeOrMoreTag));
        }
        /// <summary>
        /// !!! Ez csak pontos esetben működik !!!
        ///
        /// Ez a módszer nem vizsgálja meg, csak az első két metszet pontjait.
        /// Azon a feltevésen alapszik, hogy minden metszet két pontja közül az egyik közös.
        /// Így elég, ha két metszés megvizsgálunk, és megkeressük a közös pontot.
        /// </summary>
        public override Point CalculateCommonPoint(List <Intersection> intersections)
        {
            List <Point> mainIntersectPoints       = intersections[0].Points;
            List <Point> comparsionIntersectPoints = intersections[1].Points;

            double mindist     = LocationCalculator.Distance(mainIntersectPoints[0], comparsionIntersectPoints[0]);
            Point  commonPoint = mainIntersectPoints[0];

            for (int i = 0; i < mainIntersectPoints.Count; i++)
            {
                for (int j = 0; j < comparsionIntersectPoints.Count; j++)
                {
                    double dist = LocationCalculator.Distance(mainIntersectPoints[i], comparsionIntersectPoints[j]);
                    if (dist < mindist)
                    {
                        mindist     = dist;
                        commonPoint = mainIntersectPoints[i];
                    }
                }
            }

            return(commonPoint);
        }
        /// <summary>
        /// Ez működik általános esetre, amikor nincs pontos metszéspont
        ///
        /// A legközelebbi 3 metszéspont átlagpontját adjuk vissza
        /// Válasszuk ki a metszéspontok távolságai közül a legrövidebb hármat
        /// Elméletileg a 3 távolság 6 metszéspontja lényegében 3 pont, amit keresünk, ezek átlaga kell
        /// </summary>
        public override Point CalculateCommonPoint(List <Intersection> intersections)
        {
            List <IntersectDistance> idistances = new List <IntersectDistance>();     // A metszéspontok távolságai
            IntersectDistance        idist;

            for (int i = 0; i < intersections.Count; i++)
            {
                for (int j = 0; j < intersections.Count; j++)
                {
                    if (i != j)
                    {
                        // Egy metszet két metszéspontjának távolságát nem is vesszük figyelembe
                        idist = new IntersectDistance(intersections[i].Points[0], intersections[j].Points[1]);
                        if (!idistances.Contains(idist))
                        {
                            idistances.Add(idist);
                        }
                        idist = new IntersectDistance(intersections[i].Points[0], intersections[j].Points[0]);
                        if (!idistances.Contains(idist))
                        {
                            idistances.Add(idist);
                        }
                        idist = new IntersectDistance(intersections[i].Points[1], intersections[j].Points[1]);
                        if (!idistances.Contains(idist))
                        {
                            idistances.Add(idist);
                        }
                    }
                }
            }

            //---------------------új megoldás:--------------------

            // Az összes metszéspontot ebben a listában tároljuk
            List <Point> intersectPoints = new List <Point>();

            //Ebben a listában tároljuk el a k legközelebbi metszéspontokat
            List <Point> closestPoints = new List <Point>();

            IntersectDistance firstDistance = getMinimumDistance(idistances);

            closestPoints.Add(firstDistance.P1);
            closestPoints.Add(firstDistance.P2);

            foreach (Intersection i in intersections)
            {
                foreach (Point p in i.Points)
                {
                    if (!p.Equals(firstDistance.P1) && !p.Equals(firstDistance.P2))
                    {
                        intersectPoints.Add(p);
                    }
                }
            }

            Point candidate1 = getClosestPoint(firstDistance.P1, intersectPoints);
            Point candidate2 = getClosestPoint(firstDistance.P2, intersectPoints);

            closestPoints.Add(getThirdPoint(candidate1, candidate2, firstDistance));

            return(LocationCalculator.PointAverage(closestPoints));
        }
 private double getDistance(Point p1, Point p2, Point p3)
 {
     return(LocationCalculator.Distance(p1, p2) + LocationCalculator.Distance(p2, p3) + LocationCalculator.Distance(p1, p3));
 }
 public IntersectDistance(Point P1, Point P2)
 {
     this.P1       = P1;
     this.P2       = P2;
     this.Distance = LocationCalculator.Distance(P1, P2);
 }