示例#1
0
        private static bool UncertainSolution(RelPos2D Pos1, RelPos2D Pos2, RelPos2D Pos3)
        {
            RelPos2D[] array = new RelPos2D[] { Pos1, Pos2, Pos3 };

            return
                ((array.Contains(RelPos2D.ll) && array.Contains(RelPos2D.gg)) ||
                 (array.Contains(RelPos2D.lg) && array.Contains(RelPos2D.gl)));
        }
示例#2
0
        public Tuple <Point3D, Point3D, Point3D> Solve(Point3D Target, params Point3D[] Points)
        {
            Dictionary <Point3D, double>   distanceToTarget = new Dictionary <Point3D, double>();
            Dictionary <Point3D, RelPos2D> relativePosition = new Dictionary <Point3D, RelPos2D>();
            List <int> visited = new List <int>();

            Dictionary <RelPos2D, int> countPerPosition = new Dictionary <RelPos2D, int>()
            {
                { RelPos2D.ee, 0 },
                { RelPos2D.eg, 0 },
                { RelPos2D.el, 0 },
                { RelPos2D.ge, 0 },
                { RelPos2D.gg, 0 },
                { RelPos2D.gl, 0 },
                { RelPos2D.le, 0 },
                { RelPos2D.lg, 0 },
                { RelPos2D.ll, 0 }
            };

            foreach (var point in Points)
            {
                distanceToTarget.Add(point, TrianglePointTools.Distance(point, Target));
                RelPos2D position = TrianglePointTools.RelativePosition(point, Target);
                relativePosition.Add(point, position);
                countPerPosition[position]++;
            }

            //check countPerPosition to see if there are solutions
            int  pointsCount = Points.Length;
            bool noSolutions = false;

            foreach (var key in countPerPosition.Keys)
            {
                if (countPerPosition[key] == pointsCount)
                {
                    noSolutions = true;
                    break;
                }
            }

            noSolutions = noSolutions ||
                          countPerPosition[RelPos2D.ll] + countPerPosition[RelPos2D.le] + countPerPosition[RelPos2D.lg] == pointsCount ||
                          countPerPosition[RelPos2D.lg] + countPerPosition[RelPos2D.eg] + countPerPosition[RelPos2D.gg] == pointsCount ||
                          countPerPosition[RelPos2D.gg] + countPerPosition[RelPos2D.ge] + countPerPosition[RelPos2D.gl] == pointsCount ||
                          countPerPosition[RelPos2D.ll] + countPerPosition[RelPos2D.el] + countPerPosition[RelPos2D.gl] == pointsCount;

            if (noSolutions)
            {
                throw new Exception("No solutions.");
            }

            var  orderedPoints = Points.OrderBy(point => distanceToTarget[point]);
            bool found         = false;

            Point3D
                Point1 = null,
                Point2 = null,
                Point3 = null;

            RelPos2D PosPoint1,
                     PosPoint2,
                     PosPoint3;

            foreach (var point1 in orderedPoints)
            {
                Point1    = point1;
                PosPoint1 = relativePosition[Point1];

                var point2Candidates = orderedPoints.Where(p => p != Point1)
                                       .OrderBy(p => distanceToTarget[p]);

                //this should not happen because we know that we have at least one solution
                if (point2Candidates.Count() == 0)
                {
                    continue;
                }

                foreach (var point2 in point2Candidates)
                {
                    Point2    = point2;
                    PosPoint2 = relativePosition[Point2];

                    var point3ValidPositions = ValidPositions(PosPoint1, PosPoint2);

                    var point3Candidates = orderedPoints.Where(p => p != Point1 && p != Point2 && point3ValidPositions.Contains(relativePosition[p]))
                                           .OrderBy(p => distanceToTarget[p]);

                    if (point3Candidates.Count() == 0)
                    {
                        continue;
                    }

                    foreach (var point3 in point3Candidates)
                    {
                        Point3    = point3;
                        PosPoint3 = relativePosition[Point3];

                        //check if already visited
                        //hash subject to conflicts
                        var hash = Point1.GetHashCode() *
                                   Point2.GetHashCode() *
                                   Point3.GetHashCode();

                        if (visited.Contains(hash))
                        {
                            continue;
                        }

                        if (UncertainSolution(PosPoint1, PosPoint2, PosPoint3))
                        {
                            found = TrianglePointTools.TriangleContainsPoint(Point1, Point2, Point3, Target);
                        }
                        else
                        {
                            found = true;
                        }

                        if (found)
                        {
                            break;
                        }

                        visited.Add(hash);
                    }

                    if (found)
                    {
                        break;
                    }
                }

                if (found)
                {
                    break;
                }
            }

            if (found)
            {
                return(new Tuple <Point3D, Point3D, Point3D>(Point1, Point2, Point3));
            }

            throw new Exception("No solutions.");
        }
示例#3
0
        private static RelPos2D[] ValidPositions(RelPos2D Pos1, RelPos2D Pos2)
        {
            if (Pos1 == RelPos2D.ee || Pos2 == RelPos2D.ee)
            {
                return(AllPositions);
            }

            switch (Pos1)
            {
            case RelPos2D.ll:
                switch (Pos2)
                {
                case RelPos2D.ll:
                    return(new RelPos2D[] { RelPos2D.ee, RelPos2D.gg });

                case RelPos2D.le:
                    return(new RelPos2D[] { RelPos2D.ee, RelPos2D.gg, RelPos2D.ge });

                case RelPos2D.lg:
                    return(new RelPos2D[] { RelPos2D.ee, RelPos2D.gg, RelPos2D.ge, RelPos2D.gl });

                case RelPos2D.eg:
                    return(new RelPos2D[] { RelPos2D.ee, RelPos2D.gg, RelPos2D.ge, RelPos2D.gl, RelPos2D.el });

                case RelPos2D.gg:
                    return(AllPositions);

                case RelPos2D.ge:
                    return(new RelPos2D[] { RelPos2D.ee, RelPos2D.le, RelPos2D.lg, RelPos2D.eg, RelPos2D.gg });

                case RelPos2D.gl:
                    return(new RelPos2D[] { RelPos2D.ee, RelPos2D.lg, RelPos2D.eg, RelPos2D.gg });

                case RelPos2D.el:
                    return(new RelPos2D[] { RelPos2D.ee, RelPos2D.eg, RelPos2D.gg });
                }
                break;

            case RelPos2D.le:
                switch (Pos2)
                {
                case RelPos2D.ll:
                    return(new RelPos2D[] { RelPos2D.ee, RelPos2D.gg, RelPos2D.ge });

                case RelPos2D.le:
                    return(NoPositions);

                case RelPos2D.lg:
                    return(new RelPos2D[] { RelPos2D.ee, RelPos2D.ge, RelPos2D.gl });

                case RelPos2D.eg:
                    return(new RelPos2D[] { RelPos2D.ee, RelPos2D.ge, RelPos2D.gl, RelPos2D.el });

                case RelPos2D.gg:
                    return(new RelPos2D[] { RelPos2D.ee, RelPos2D.ge, RelPos2D.gl, RelPos2D.el, RelPos2D.ll });

                case RelPos2D.ge:
                    return(AllPositions.Except(new RelPos2D[] { Pos1, Pos2 }).ToArray());

                case RelPos2D.gl:
                    return(new RelPos2D[] { RelPos2D.ee, RelPos2D.lg, RelPos2D.eg, RelPos2D.gg });

                case RelPos2D.el:
                    return(new RelPos2D[] { RelPos2D.ee, RelPos2D.eg, RelPos2D.gg });
                }
                break;

            case RelPos2D.lg:
                switch (Pos2)
                {
                case RelPos2D.ll:
                    return(new RelPos2D[] { RelPos2D.ee, RelPos2D.gg, RelPos2D.ge, RelPos2D.gl });

                case RelPos2D.le:
                    return(new RelPos2D[] { RelPos2D.ee, RelPos2D.ge, RelPos2D.gl });

                case RelPos2D.lg:
                    return(new RelPos2D[] { RelPos2D.ee, RelPos2D.gl });

                case RelPos2D.eg:
                    return(new RelPos2D[] { RelPos2D.ee, RelPos2D.gl, RelPos2D.el });

                case RelPos2D.gg:
                    return(new RelPos2D[] { RelPos2D.ee, RelPos2D.gl, RelPos2D.el, RelPos2D.ll });

                case RelPos2D.ge:
                    return(new RelPos2D[] { RelPos2D.ee, RelPos2D.gl, RelPos2D.el, RelPos2D.ll, RelPos2D.le });

                case RelPos2D.gl:
                    return(AllPositions);

                case RelPos2D.el:
                    return(new RelPos2D[] { RelPos2D.ee, RelPos2D.eg, RelPos2D.gg, RelPos2D.ge, RelPos2D.gl });
                }
                break;

            case RelPos2D.eg:
                switch (Pos2)
                {
                case RelPos2D.ll:
                    return(new RelPos2D[] { RelPos2D.ee, RelPos2D.gg, RelPos2D.ge, RelPos2D.gl, RelPos2D.el });

                case RelPos2D.le:
                    return(new RelPos2D[] { RelPos2D.ee, RelPos2D.ge, RelPos2D.gl, RelPos2D.el });

                case RelPos2D.lg:
                    return(new RelPos2D[] { RelPos2D.ee, RelPos2D.gl, RelPos2D.el });

                case RelPos2D.eg:
                    return(NoPositions);

                case RelPos2D.gg:
                    return(new RelPos2D[] { RelPos2D.ee, RelPos2D.el, RelPos2D.ll });

                case RelPos2D.ge:
                    return(new RelPos2D[] { RelPos2D.ee, RelPos2D.el, RelPos2D.ll, RelPos2D.le });

                case RelPos2D.gl:
                    return(new RelPos2D[] { RelPos2D.ee, RelPos2D.el, RelPos2D.ll, RelPos2D.le, RelPos2D.lg });

                case RelPos2D.el:
                    return(AllPositions.Except(new RelPos2D[] { Pos1, Pos2 }).ToArray());
                }
                break;

            case RelPos2D.gg:
                switch (Pos2)
                {
                case RelPos2D.ll:
                    return(AllPositions);

                case RelPos2D.le:
                    return(new RelPos2D[] { RelPos2D.ee, RelPos2D.ge, RelPos2D.gl, RelPos2D.el, RelPos2D.ll });

                case RelPos2D.lg:
                    return(new RelPos2D[] { RelPos2D.ee, RelPos2D.gl, RelPos2D.el, RelPos2D.ll });

                case RelPos2D.eg:
                    return(new RelPos2D[] { RelPos2D.ee, RelPos2D.el, RelPos2D.ll });

                case RelPos2D.gg:
                    return(new RelPos2D[] { RelPos2D.ee, RelPos2D.ll });

                case RelPos2D.ge:
                    return(new RelPos2D[] { RelPos2D.ee, RelPos2D.ll, RelPos2D.le });

                case RelPos2D.gl:
                    return(new RelPos2D[] { RelPos2D.ee, RelPos2D.ll, RelPos2D.le, RelPos2D.lg });

                case RelPos2D.el:
                    return(new RelPos2D[] { RelPos2D.ee, RelPos2D.ll, RelPos2D.le, RelPos2D.lg, RelPos2D.eg });
                }
                break;

            case RelPos2D.ge:
                switch (Pos2)
                {
                case RelPos2D.ll:
                    return(new RelPos2D[] { RelPos2D.ee, RelPos2D.le, RelPos2D.lg, RelPos2D.eg, RelPos2D.gg });

                case RelPos2D.le:
                    return(AllPositions.Except(new RelPos2D[] { Pos1, Pos2 }).ToArray());

                case RelPos2D.lg:
                    return(new RelPos2D[] { RelPos2D.ee, RelPos2D.gl, RelPos2D.el, RelPos2D.ll, RelPos2D.le });

                case RelPos2D.eg:
                    return(new RelPos2D[] { RelPos2D.ee, RelPos2D.el, RelPos2D.ll, RelPos2D.le });

                case RelPos2D.gg:
                    return(new RelPos2D[] { RelPos2D.ee, RelPos2D.ll, RelPos2D.le });

                case RelPos2D.ge:
                    return(NoPositions);

                case RelPos2D.gl:
                    return(new RelPos2D[] { RelPos2D.ee, RelPos2D.le, RelPos2D.lg });

                case RelPos2D.el:
                    return(new RelPos2D[] { RelPos2D.ee, RelPos2D.le, RelPos2D.lg, RelPos2D.eg });
                }
                break;

            case RelPos2D.gl:
                switch (Pos2)
                {
                case RelPos2D.ll:
                    return(new RelPos2D[] { RelPos2D.ee, RelPos2D.lg, RelPos2D.eg, RelPos2D.gg });

                case RelPos2D.le:
                    return(new RelPos2D[] { RelPos2D.ee, RelPos2D.lg, RelPos2D.eg, RelPos2D.gg, RelPos2D.ge });

                case RelPos2D.lg:
                    return(AllPositions);

                case RelPos2D.eg:
                    return(new RelPos2D[] { RelPos2D.ee, RelPos2D.el, RelPos2D.ll, RelPos2D.le, RelPos2D.lg });

                case RelPos2D.gg:
                    return(new RelPos2D[] { RelPos2D.ee, RelPos2D.ll, RelPos2D.le, RelPos2D.lg });

                case RelPos2D.ge:
                    return(new RelPos2D[] { RelPos2D.ee, RelPos2D.le, RelPos2D.lg });

                case RelPos2D.gl:
                    return(new RelPos2D[] { RelPos2D.ee, RelPos2D.lg });

                case RelPos2D.el:
                    return(new RelPos2D[] { RelPos2D.ee, RelPos2D.lg, RelPos2D.eg });
                }
                break;

            case RelPos2D.el:
                switch (Pos2)
                {
                case RelPos2D.ll:
                    return(new RelPos2D[] { RelPos2D.ee, RelPos2D.eg, RelPos2D.gg });

                case RelPos2D.le:
                    return(new RelPos2D[] { RelPos2D.ee, RelPos2D.eg, RelPos2D.gg, RelPos2D.ge });

                case RelPos2D.lg:
                    return(new RelPos2D[] { RelPos2D.ee, RelPos2D.eg, RelPos2D.gg, RelPos2D.ge, RelPos2D.gl });

                case RelPos2D.eg:
                    return(AllPositions.Except(new RelPos2D[] { Pos1, Pos2 }).ToArray());

                case RelPos2D.gg:
                    return(new RelPos2D[] { RelPos2D.ee, RelPos2D.ll, RelPos2D.le, RelPos2D.lg, RelPos2D.eg });

                case RelPos2D.ge:
                    return(new RelPos2D[] { RelPos2D.ee, RelPos2D.le, RelPos2D.lg, RelPos2D.eg });

                case RelPos2D.gl:
                    return(new RelPos2D[] { RelPos2D.ee, RelPos2D.lg, RelPos2D.eg });

                case RelPos2D.el:
                    return(NoPositions);
                }
                break;
            }
            return(NoPositions);
        }