コード例 #1
0
ファイル: Main.cs プロジェクト: palkiviad/pathTracing
        protected override void OnMouseDown(MouseButtonEventArgs e)
        {
            base.OnMouseDown(e);

            Vector3 point = new Vector3(0, 0, 0);

            Glu.UnProject(new Vector3(e.X, e.Y, 0.0f), ref point);
            Vector2 point2 = new Vector2(point.X, point.Y);

            if (e.Button == MouseButton.Left)
            {
                if (Vector2.Distance(start, point2) < selectionRadius)
                {
                    dragMode = DragMode.Start;
                    start    = point2;
                }
                else if (Vector2.Distance(end, point2) < selectionRadius)
                {
                    dragMode = DragMode.End;
                    end      = point2;
                }
            }
            else if (e.Button == MouseButton.Right)
            {
                pathSet = false;
                OnResize();
            }
        }
コード例 #2
0
ファイル: Map.cs プロジェクト: palkiviad/pathTracing
        private bool FindTrasingData(Segment l, ref TracingData data)
        {
            var intersections = new Dictionary <Vector2, int>();
            var inDistances   = new Dictionary <float, Vector2>();
            var outDistances  = new Dictionary <float, Vector2>();

            for (var i = 0; i < Segments.Length; i++)
            {
                var segment        = Segments[i];
                var intersectPoint = new Vector2();
                var isIntersects   = Vector2.SegmentToSegmentIntersection(l.Start, l.End, segment.Start, segment.End, ref intersectPoint);
                if (!isIntersects)
                {
                    continue;
                }

                intersections[intersectPoint] = i;
                inDistances[Vector2.Distance(intersectPoint, l.Start)] = intersectPoint;
                outDistances[Vector2.Distance(intersectPoint, l.End)]  = intersectPoint;
            }

            if (intersections.Count == 0)
            {
                return(false);
            }

            data.InPoint         = inDistances[inDistances.Keys.Min()];
            data.OutPoint        = outDistances[outDistances.Keys.Min()];
            data.InSegmentIndex  = intersections[data.InPoint];
            data.OutSegmentIndex = intersections[data.OutPoint];
            return(true);
        }
コード例 #3
0
ファイル: Main.cs プロジェクト: palkiviad/pathTracing
        protected override void OnMouseMove(MouseMoveEventArgs e)
        {
            base.OnMouseMove(e);

            if (dragMode != DragMode.Start && dragMode != DragMode.End)
            {
                return;
            }

            Vector3 point = new Vector3(0, 0, 0);

            Glu.UnProject(new Vector3(e.X, e.Y, 0.0f), ref point);
            Vector2 point2 = new Vector2(point.X, point.Y);

            if (dragMode == DragMode.Start)
            {
                start = point2;
            }
            else
            {
                end = point2;
            }

            settings.StartAndEnd = new[] { start, end };
        }
コード例 #4
0
ファイル: Map.cs プロジェクト: palkiviad/pathTracing
        public IEnumerable <Vector2> GetPath(Vector2 start, Vector2 end)
        {
            var result = new List <Vector2>();

            movedSegments = new List <Segment>();

            // 1. Старт
            result.Add(start);

            Vector2 obstacleEnd = start;

            while (obstacleEnd != Vector2.zero)
            {
                // 2. Сразу проверяем можем ли построить путь без пересечений
                List <Vector2> intersectPoints = findIntersectPoints3(obstacleEnd, end, segments);
                if (intersectPoints.Count == 0)
                {
                    result.Add(end);
                    return(result);
                }

                // Вычисляем два пути: по часовой и против часовой стрелки
                PathDistance byEnd   = calcPathByEnd(obstacleEnd, intersectPoints, start, end);
                PathDistance byStart = calcPathByStart(obstacleEnd, intersectPoints, start, end);

                PathDistance shortestDistance = byEnd.distance < byStart.distance ? byEnd : byStart;

                result.AddRange(shortestDistance.points);
                obstacleEnd = shortestDistance.obstacleEnd;
            }

            result.Add(end);
            return(result);
        }
コード例 #5
0
ファイル: Main.cs プロジェクト: palkiviad/pathTracing
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            Size = settings.Size;
            if (settings.Location.X != int.MinValue && settings.Location.Y != int.MinValue)
            {
                Location = new Point(settings.Location.X, settings.Location.Y);
            }

            if (settings.StartAndEnd != null)
            {
                start   = settings.StartAndEnd[0];
                end     = settings.StartAndEnd[1];
                pathSet = true;
            }

            GL.ClearColor(0.7f, 0.7f, 0.7f, 0.0f);
            GL.Disable(EnableCap.DepthTest);

            if (!File.Exists(settings.CurrentFile))
            {
                settings.CurrentFile = null;
                LoadFile(settings.NextFile);
            }
            else
            {
                LoadFile(settings.CurrentFile);
            }
        }
コード例 #6
0
ファイル: Map.cs プロジェクト: palkiviad/pathTracing
        public PathDistance calcPathByStart(Vector2 obstacleEnd, List <Vector2> intersectPoints, Vector2 start, Vector2 end)
        {
            // Находим ближайшую точку пересечения и ее сегмент, запоминаем
            Vector2 intersectNearestPoint = findNearestPoint(obstacleEnd, intersectPoints);
            Segment nearestSegment        = findNearestSegment(intersectNearestPoint);

            // Проверяем можем ли с вершины обстакла дойти до финиша
            if (findIntersectPoints2(nearestSegment.start, end, segments) == 0)
            {
                PathDistance path1 = new PathDistance();

                path1.addPoint(intersectNearestPoint);
                path1.accDistance(Vector2.Distance(start, intersectNearestPoint));

                // Выбираем Начало отрезка и запоминаем
                path1.addPoint(nearestSegment.start);
                path1.accDistance(Vector2.Distance(intersectNearestPoint, nearestSegment.start));

                path1.obstacleEnd = Vector2.zero;
                return(path1);
            }

            PathDistance path = new PathDistance();

            path.addPoint(intersectNearestPoint);
            path.accDistance(Vector2.Distance(start, intersectNearestPoint));

            // Выбираем Начало отрезка и запоминаем
            path.addPoint(nearestSegment.start);
            path.accDistance(Vector2.Distance(intersectNearestPoint, nearestSegment.start));

            // Если не можем, ищем обстакл на котором располагается ближайший сегмент
            Obstacle obstacle = findObstacleBySegment(nearestSegment);

            // Идем по сегментам обстакла, пока не будем пересекать сами себя и не будем пересекать уже пройденные обстаклы,
            // или не построем путь из вершина до финиша
            while (!(findIntersectPoints2(nearestSegment.start, end, obstacle.segments) == 0 &&
                     findIntersectPoints2(nearestSegment.start, end, movedSegments.ToArray()) == 0))
            {
                nearestSegment = obstacle.getNextSegmentByCounterClockWise(nearestSegment);

                // Нашли следующий сегмент обстакла, проверяем можем ли дойти до финиша без пересечений
                if (findIntersectPoints2(nearestSegment.start, end, segments) == 0)
                {
                    path.addPoint(nearestSegment.start);
                    path.accDistance(Vector2.Distance(nearestSegment.end, nearestSegment.start));
                    path.obstacleEnd = Vector2.zero;
                    return(path);
                }

                // Не можем - запоминаем конец обстакла
                path.addPoint(nearestSegment.start);
                path.accDistance(Vector2.Distance(nearestSegment.end, nearestSegment.start));
            }

            path.obstacleEnd = nearestSegment.start;
            movedSegments.AddRange(obstacle.segments.ToList());
            return(path);
        }
コード例 #7
0
ファイル: Main.cs プロジェクト: palkiviad/pathTracing
        private void OnResize()
        {
            GL.Viewport(ClientRectangle.X, ClientRectangle.Y, ClientRectangle.Width, ClientRectangle.Height);

            InternalBox box = obstaclesCollection.Bounds;

            settings.Size = new Size(Bounds.Width, Bounds.Height);

            // теперь отскейлим  box так, чтобы сохранить пропорции
            // также добавим ещё процентов 20 по сторонам

            float coeffW = (float)Width / Height;
            float coeffM = box.W / box.H;

            float halfW, halfH;

            if (coeffW < coeffM)
            {
                halfW = box.W / 2;
                halfH = box.W / coeffW / 2;
            }
            else
            {
                halfH = box.H / 2;
                halfW = box.H * coeffW / 2;
            }

            Vector2 center = box.Center;

            // если пути нет, проставим его ровно посереднине слева направо
            if (!pathSet)
            {
                start   = new Vector2(center.x - halfW * 1.1f, center.y);
                end     = new Vector2(center.x + halfW * 1.1f, center.y);
                pathSet = true;

                settings.StartAndEnd = new[] { start, end };
            }

            // И надбавим 20% чтобы было откуда и куда строить путь
            halfW *= 1.2f;
            halfH *= 1.2f;

            Matrix4 projection = Matrix4.CreateOrthographicOffCenter(center.x - halfW, center.x + halfW,
                                                                     center.y - halfH, center.y + halfH, -10, 10);

            GL.MatrixMode(MatrixMode.Projection);
            GL.LoadMatrix(ref projection);

            Vector3 point = new Vector3(0, 0, 0);

            Glu.UnProject(new Vector3(0, 0, 0), ref point);
            Vector2 pointA = new Vector2(point.X, point.Y);

            Glu.UnProject(new Vector3(20, 0, 0), ref point);
            Vector2 pointB = new Vector2(point.X, point.Y);

            selectionRadius = Vector2.Distance(pointA, pointB);
        }
コード例 #8
0
        private Vector2 step1(Vector2 start, Vector2 end, List <Vector2> result, bool v)
        {
            var intersectPoints = findIntersectPoints(start, end);

            Vector2 nearestPoint = findNearestPoint(start, intersectPoints);

            result.Add(nearestPoint);

            Vector2 nearestPeak = findNearestPeak(nearestPoint, v);

            result.Add(nearestPeak);
            return(nearestPeak);
        }
コード例 #9
0
ファイル: Map.cs プロジェクト: palkiviad/pathTracing
        public IEnumerable <Vector2> GetPath(Vector2 start, Vector2 end)
        {
            var path = new List <Vector2> {
                start
            };
            var startEnd = new Segment(start, end);

            foreach (var obstacle in Obstacles)
            {
                obstacle.WayAround(startEnd).ForEach(p => path.Add(p));
            }

            path.Add(end);
            return(path);
        }
コード例 #10
0
ファイル: Map.cs プロジェクト: palkiviad/pathTracing
        private List <Vector2> findIntersectPoints3(Vector2 start, Vector2 end, Segment[] segments)
        {
            var result = new List <Vector2>();

            foreach (Segment segment in segments)
            {
                Vector2 res = Vector2.zero;
                if (Vector2.SegmentToSegmentIntersection(segment.start, segment.end, start, end, ref res))
                {
                    result.Add(res);
                }
            }

            return(result);
        }
コード例 #11
0
ファイル: Map.cs プロジェクト: palkiviad/pathTracing
        private int findIntersectPoints2(Vector2 start, Vector2 end, Segment[] segments)
        {
            int count = 0;

            foreach (Segment segment in segments)
            {
                Vector2 res = Vector2.zero;
                if (Vector2.SegmentToSegmentIntersection(segment.start, segment.end, start, end, ref res))
                {
                    count++;
                }
            }

            return(count);
        }
コード例 #12
0
ファイル: Map.cs プロジェクト: palkiviad/pathTracing
        private Segment findNearestSegment(Vector2 intersectNearestPoint)
        {
            var result = new Segment();

            foreach (Segment segment in segments)
            {
                float diff = Vector2.Distance(segment.start, intersectNearestPoint)
                             + Vector2.Distance(segment.end, intersectNearestPoint)
                             - Vector2.Distance(segment.start, segment.end);
                if (diff < 0.01)
                {
                    result = segment;
                    break;
                }
            }

            return(result);
        }
コード例 #13
0
        private IEnumerable <Vector2> findIntersectPoints(Vector2 startPath, Vector2 endPath)
        {
            var result = new List <Vector2>();

            for (int i = 0; i < obstacles.Length; i++)
            {
                for (int j = 0; j < obstacles[i].Length; j++)
                {
                    Vector2 v1;
                    Vector2 v2;

                    if (j == obstacles[i].Length - 1)
                    {
                        v1 = new Vector2(obstacles[i][j].x, obstacles[i][j].y);
                        v2 = new Vector2(obstacles[i][0].x, obstacles[i][0].y);
                    }
                    else
                    {
                        v1 = new Vector2(obstacles[i][j].x, obstacles[i][j].y);
                        v2 = new Vector2(obstacles[i][j + 1].x, obstacles[i][j + 1].y);
                    }

                    Vector2 v3  = new Vector2(startPath.x, startPath.y);
                    Vector2 v4  = new Vector2(endPath.x, endPath.y);
                    Vector2 res = new Vector2();

                    //  Console.WriteLine("obstacle segment = " + v1 + " - " + v2);
                    //   Console.WriteLine("path segment = " + v3 + " - " + v4);

                    var segmentToSegmentIntersection = Vector2.SegmentToSegmentIntersection(v1, v2, v3, v4, ref res);
                    //   Console.WriteLine("intersect res = " + segmentToSegmentIntersection);
                    //  Console.WriteLine("intersect point = " + v4);
                    //  Console.WriteLine();
                    if (segmentToSegmentIntersection)
                    {
                        result.Add(res);
                    }
                }
            }

            return(result);
        }
コード例 #14
0
        public IEnumerable <Vector2> GetPath(Vector2 start, Vector2 end)
        {
            var result = new List <Vector2>();

            result.Add(start);

            //printObstacle();

            Vector2 nearestPeak1 = step1(start, end, result, false);
            Vector2 nearestPeak2 = step1(nearestPeak1, end, result, false);
            Vector2 nearestPeak3 = step1(nearestPeak2, end, result, true);
            Vector2 nearestPeak4 = step1(nearestPeak3, end, result, true);
            Vector2 nearestPeak5 = step1(nearestPeak4, end, result, true);

//            Vector2 nearestPeak6 = step1(nearestPeak5, end, result, true);
//            Vector2 nearestPeak7 = step1(nearestPeak6, end, result, true);
//            Vector2 nearestPeak8 = step1(nearestPeak7, end, result, true);

            return(result);
        }
コード例 #15
0
ファイル: Map.cs プロジェクト: palkiviad/pathTracing
        private void createSegmentsAndObstacles(Vector2[][] sourceObstacles)
        {
            int segmentsLength = 0;

            for (int i = 0; i < sourceObstacles.Length; i++)
            {
                segmentsLength += sourceObstacles[i].Length;
            }

            obstacles = new Obstacle[sourceObstacles.Length];
            segments  = new Segment[segmentsLength];
            int k = 0;

            for (int i = 0; i < sourceObstacles.Length; i++)
            {
                Segment[] segmentsForObstacle = new Segment[sourceObstacles[i].Length];
                for (int j = 0; j < sourceObstacles[i].Length; j++)
                {
                    Vector2 endS   = Vector2.zero;
                    Vector2 startS = Vector2.zero;
                    if (j == sourceObstacles[i].Length - 1)
                    {
                        startS = sourceObstacles[i][j];
                        endS   = sourceObstacles[i][0];
                    }
                    else
                    {
                        startS = sourceObstacles[i][j];
                        endS   = sourceObstacles[i][j + 1];
                    }

                    var segment = new Segment(startS, endS);
                    segments[k] = segment;
                    segmentToObstacleIndex.Add(segment, i);
                    segmentsForObstacle[j] = segment;
                    k++;
                }

                obstacles[i] = new Obstacle(segmentsForObstacle);
            }
        }
コード例 #16
0
ファイル: Map.cs プロジェクト: palkiviad/pathTracing
        public List <Vector2> WayAround(Segment l)
        {
            var td = new TracingData();

            if (!FindTrasingData(l, ref td))
            {
                return(new List <Vector2>());
            }

            var toEndPath    = new List <Vector2>();
            var toEndPathLen = 0.0;

            toEndPath.Add(td.InPoint);
            for (var i = td.InSegmentIndex; i != td.OutSegmentIndex; i = (i + 1) % Segments.Length)
            {
                var newP = Segments[i].End;
                toEndPathLen += Vector2.Distance(toEndPath.Last(), newP);
                toEndPath.Add(newP);
            }

            toEndPathLen += Vector2.Distance(toEndPath.Last(), td.OutPoint);
            toEndPath.Add(td.OutPoint);

            var toStartPath    = new List <Vector2>();
            var toStartPathLen = 0.0;

            toStartPath.Add(td.InPoint);
            for (var i = td.InSegmentIndex; i != td.OutSegmentIndex; i = i == 0 ? Segments.Length - 1 : i - 1)
            {
                var newP = Segments[i].Start;
                toStartPathLen += Vector2.Distance(toStartPath.Last(), newP);
                toStartPath.Add(newP);
            }

            toStartPathLen += Vector2.Distance(toStartPath.Last(), td.OutPoint);
            toStartPath.Add(td.OutPoint);

            return(toStartPathLen < toEndPathLen ? toStartPath : toEndPath);
        }
コード例 #17
0
ファイル: MainTest.cs プロジェクト: palkiviad/pathTracing
        private static double Length(IEnumerable <Vector2> path)
        {
            double res = 0;

            bool    first = true;
            Vector2 prev  = Vector2.zero;

            foreach (Vector2 vertex in path)
            {
                if (first)
                {
                    first = false;
                    prev  = vertex;
                    continue;
                }

                res += Vector2.Distance(prev, vertex);
                prev = vertex;
            }

            return(res);
        }
コード例 #18
0
        private Vector2 findNearestPeak(Vector2 nearestPoint, bool v)
        {
            Vector2 res = new Vector2();

            for (int i = 0; i < obstacles.Length; i++)
            {
                for (int j = 0; j < obstacles[i].Length; j++)
                {
                    Vector2 v1;
                    Vector2 v2;

                    if (j == obstacles[i].Length - 1)
                    {
                        v1 = new Vector2(obstacles[i][j].x, obstacles[i][j].y);
                        v2 = new Vector2(obstacles[i][0].x, obstacles[i][0].y);
                    }
                    else
                    {
                        v1 = new Vector2(obstacles[i][j].x, obstacles[i][j].y);
                        v2 = new Vector2(obstacles[i][j + 1].x, obstacles[i][j + 1].y);
                    }

                    Vector2 part1 = new Vector2();
                    Vector2 part2 = new Vector2();
                    float   diff  = Vector2.Distance(v1, nearestPoint) + Vector2.Distance(v2, nearestPoint) - Vector2.Distance(v1, v2);

                    Vector2 peak = v ? v1 : v2;

                    if (diff < 0.1)
                    {
                        res = peak;
                        break;
                    }
                }
            }


            return(res);
        }
コード例 #19
0
        private Vector2 findNearestPoint(Vector2 startPath, IEnumerable <Vector2> intersectPoints)
        {
            Vector2 res         = new Vector2();
            float   minDistance = 0;

            foreach (Vector2 point in intersectPoints)
            {
                var distance = Vector2.Distance(startPath, point);
                if (minDistance == 0)
                {
                    minDistance = distance;
                    res         = point;
                }

                if (distance < minDistance)
                {
                    res = point;
                }
            }

            // Console.WriteLine("nearestPoint = " + res);
            return(res);
        }
コード例 #20
0
ファイル: Map.cs プロジェクト: palkiviad/pathTracing
        private Vector2 findNearestPoint(Vector2 start, IEnumerable <Vector2> intersectPoints)
        {
            Vector2 res         = new Vector2();
            float   minDistance = 0;

            foreach (Vector2 point in intersectPoints)
            {
                var distance = Vector2.Distance(start, point);
                if (minDistance == 0)
                {
                    minDistance = distance;
                    res         = point;
                }

                if (distance < minDistance)
                {
                    minDistance = distance;
                    res         = point;
                }
            }

            return(res);
        }
コード例 #21
0
ファイル: Map.cs プロジェクト: palkiviad/pathTracing
 public Segment(Vector2 start, Vector2 end)
 {
     Start = start;
     End   = end;
 }
コード例 #22
0
ファイル: MainTest.cs プロジェクト: palkiviad/pathTracing
        private void SaveStatistics()
        {
            const float barrierSuccessRate = 0.96f;

            StringBuilder sb = new StringBuilder(
                "<!DOCTYPE html><meta charset=\"UTF-8\"><html><head><style>table {    width:100%;}table, th, td {    border: 1px solid black;    border-collapse: collapse;}th, td {    padding: 15px;    text-align: left;}table#t01 tr:nth-child(even) {    background-color: #eee;}table#t01 tr:nth-child(odd) {   background-color: #fff;}table#t01 th {    background-color: black;    color: white;}</style></head><body><h2>Рекорды</h2><table>");

            // тут табличка

            // Сначала хэдера
            sb.Append("<tr>");
            sb.Append("<th>User</th>");

            sb.Append("<th>Total</th>");
            sb.Append("<th>Total duration</th>");
            sb.Append("<th>Total length</th>");

            // Имена файлов
            HashSet <string> files = new HashSet <string>();

            foreach (var val in statistics)
            {
                files.Add(val.file);
            }

            HashSet <string> users = new HashSet <string>();

            foreach (var val in statistics)
            {
                users.Add(val.user);
            }


            foreach (var file in files)
            {
                sb.Append("<th colspan=\"4\" style=\"text-align:center\">" + file + "</th>");
            }
            sb.Append("</tr>");

            // Вторая строка - средние значение
            sb.Append("<tr>");
            sb.Append("<td>-</td>");

            sb.Append("<td>-</td>");
            sb.Append("<td>-</td>");
            sb.Append("<td>-</td>");

            for (int i = 0; i < files.Count; i++)
            {
                sb.Append("<td>Success</td>");
                sb.Append("<td>Duration</td>");
                sb.Append("<td>Length</td>");
                sb.Append("<td>Points</td>");
            }

            sb.Append("</tr>");


            // Построим интервалы, за попадание в которые будем давать баллы. Для этого просто получим min и max значения
            // Интервалы строим на базе значений людей, которые выдали

            // Интервалы раздельны по файлам и по типу - длительность и длина

            Dictionary <string, Vector2> durationIntervals = new Dictionary <string, Vector2>();
            Dictionary <string, Vector2> lengthIntervals   = new Dictionary <string, Vector2>();

            foreach (var file in files)
            {
                var fileStatistics = statistics.FindAll(p => p.file == file);

                float minDuration = (float)fileStatistics.Min(p => p.statistics.successRate <= barrierSuccessRate ? double.MaxValue : p.statistics.duration);
                float maxDuration = (float)fileStatistics.Max(p => p.statistics.successRate <= barrierSuccessRate ? double.MinValue : p.statistics.duration);

                float minLength = (float)fileStatistics.Min(p => p.statistics.successRate <= barrierSuccessRate ? double.MaxValue : p.statistics.length);
                float maxLength = (float)fileStatistics.Max(p => p.statistics.successRate <= barrierSuccessRate ? double.MinValue : p.statistics.length);

                durationIntervals[file] = new Vector2(minDuration, maxDuration);
                lengthIntervals[file]   = new Vector2(minLength, maxLength);
            }


            // Теперь по фамилиям и файлам получим очки
            List <Tuple <string, string, int> > durationScore = new List <Tuple <string, string, int> >();
            List <Tuple <string, string, int> > lengthScore   = new List <Tuple <string, string, int> >();

            foreach (string user in users)
            {
                foreach (var file in files)
                {
                    Statistics stat = statistics.Find(p => p.user == user && p.file == file).statistics;

                    if (stat.successRate <= barrierSuccessRate)
                    {
                        durationScore.Add(new Tuple <string, string, int>(user, file, 0));
                        lengthScore.Add(new Tuple <string, string, int>(user, file, 0));
                    }
                    else
                    {
                        // Интервал по файлу
                        Vector2 durationInterval = durationIntervals[file];

                        if (durationInterval.x == durationInterval.y)
                        {
                            durationScore.Add(new Tuple <string, string, int>(user, file, 10));
                        }
                        else
                        {
                            float t = (float)((stat.duration - durationInterval.x) / (durationInterval.y - durationInterval.x));
                            durationScore.Add(new Tuple <string, string, int>(user, file, 10 - (int)(t * 10)));
                        }

                        Vector2 lengthInterval = lengthIntervals[file];

                        if (lengthInterval.x == lengthInterval.y)
                        {
                            lengthScore.Add(new Tuple <string, string, int>(user, file, 10));
                        }
                        else
                        {
                            float t = (float)((stat.length - lengthInterval.x) / (lengthInterval.y - lengthInterval.x));

                            lengthScore.Add(new Tuple <string, string, int>(user, file, 10 - (int)(t * 10)));
                        }
                    }
                }
            }

            Dictionary <string, int> totalScores   = new Dictionary <string, int>();
            Dictionary <string, int> totalDuration = new Dictionary <string, int>();
            Dictionary <string, int> totalLength   = new Dictionary <string, int>();

            foreach (string user in users)
            {
                // Находим все файлы по данному юзеру
                var userDurationScores = durationScore.FindAll(p => p.Item1 == user);
                var userLengthScores   = lengthScore.FindAll(p => p.Item1 == user);

                totalDuration[user] = userDurationScores.Sum(p => p.Item3);
                totalLength[user]   = userLengthScores.Sum(p => p.Item3);

                totalScores[user] = userDurationScores.Sum(p => p.Item3) + userLengthScores.Sum(p => p.Item3);
            }


            // А дальше - по фамилиям
            foreach (string user in users)
            {
                sb.Append("<tr>");
                sb.Append("<td>" + user + "</td>");

                // Тотал
                sb.Append("<td>" + totalScores[user] + "</td>");

                // Тотал длительность
                sb.Append("<td>" + totalDuration[user] + "</td>");

                // Тотал дистанция
                sb.Append("<td>" + totalLength[user] + "</td>");

                foreach (var file in files)
                {
                    Statistics stat = statistics.Find(p => p.user == user && p.file == file).statistics;

//                    if (stat.successRate <= barrierSuccessRate)
//                        sb.Append("<td style=\"color: red;font-weight: bold;\">" + string.Format("{0:0.00}", stat.successRate) + "</td>");
//                    else
//                        sb.Append("<td>" + string.Format("{0:0.00}", stat.successRate) + "</td>");

                    if (stat.successRate <= barrierSuccessRate)
                    {
                        sb.Append("<td style=\"color: red;font-weight: bold;\">" + stat.SuccessRateForHtml() + "</td>");
                    }
                    else
                    {
                        sb.Append("<td>" + stat.SuccessRateForHtml() + "</td>");
                    }
                    // если stat.successRate == 1 мы должны найти среди таких молодцев лучший показатель

                    var fileStatistics = statistics.FindAll(p => p.file == file);

                    if (stat.successRate > barrierSuccessRate)
                    {
                        var minDuration = fileStatistics.Min(p => p.statistics.successRate <= barrierSuccessRate ? double.MaxValue : p.statistics.duration);
                        var minLength   = fileStatistics.Min(p => p.statistics.successRate <= barrierSuccessRate ? double.MaxValue : p.statistics.length);
                        var minPoints   = fileStatistics.Min(p => p.statistics.successRate <= barrierSuccessRate ? double.MaxValue : p.statistics.points);

                        sb.Append((minDuration == stat.duration ? "<td style=\"color: green;font-weight: bold;\">" : "<td>") + string.Format("{0:0.000}", stat.duration) + "</td>");
                        sb.Append((minLength == stat.length ? "<td style=\"color: green;font-weight: bold;\">" : "<td>") + string.Format("{0:0.000}", stat.length) + "</td>");
                        sb.Append((minPoints == stat.points ? "<td style=\"color: green;font-weight: bold;\">" : "<td>") + string.Format("{0:0.000}", stat.points) + "</td>");
                    }
                    else
                    {
                        sb.Append("<td>" + string.Format("{0:0.000}", stat.duration) + "</td>");
                        sb.Append("<td>" + string.Format("{0:0.000}", stat.length) + "</td>");
                        sb.Append("<td>" + string.Format("{0:0.000}", stat.points) + "</td>");
                    }
                }

                sb.Append("</tr>");
            }

            sb.Append("</table></body></html>");
            File.WriteAllText("records.html", sb.ToString());
        }
コード例 #23
0
ファイル: MainTest.cs プロジェクト: palkiviad/pathTracing
            public Obstacles(string file, InternalObstaclesCollection collection)
            {
                this.file       = file;
                this.collection = collection;

                const int totalNumberOfPoints = 100;

                int            numberOfRandomPoints = collection.areasA != null && collection.areasB != null ? (int)(totalNumberOfPoints * 0.2f) : totalNumberOfPoints;
                const int      numberOfAreaPoints   = (int)(totalNumberOfPoints * 0.8f);
                List <Vector2> testPoints           = new List <Vector2>();

                int pos = 0;

                // Для каждого набора точек сгенерим список случайных конечных и начальных точек
                // Если на карте заданы areaA и areaB, мы сгенерим кучку точек в пределах этих area
                if (collection.areasA != null && collection.areasB != null)
                {
                    do
                    {
                        InternalBox[] startAreas;
                        InternalBox[] endAreas;

                        if (Mathematics.Random.Range(0, 2) == 0)
                        {
                            startAreas = collection.areasA;
                            endAreas   = collection.areasB;
                        }
                        else
                        {
                            startAreas = collection.areasA;
                            endAreas   = collection.areasB;
                        }

                        InternalBox startArea = startAreas[Mathematics.Random.Range(0, startAreas.Length)];
                        InternalBox endArea   = endAreas[Mathematics.Random.Range(0, endAreas.Length)];

                        Vector2 startPoint = new Vector2(Mathematics.Random.Range(startArea.LeftBottom.x, startArea.RightTop.x),
                                                         Mathematics.Random.Range(startArea.LeftBottom.y, startArea.RightTop.y));
                        Vector2 endPoint = new Vector2(Mathematics.Random.Range(endArea.LeftBottom.x, endArea.RightTop.x),
                                                       Mathematics.Random.Range(endArea.LeftBottom.y, endArea.RightTop.y));

                        if (collection.Contains(startPoint) || collection.Contains(endPoint))
                        {
                            continue;
                        }

                        testPoints.Add(startPoint);
                        testPoints.Add(endPoint);

                        pos += 2;
                    } while (pos <= numberOfAreaPoints);
                }

                InternalBox box = collection.Bounds;
                Vector2     min = box.LeftBottom - new Vector2(box.W * 0.1f, box.H * 0.1f);
                Vector2     max = box.RightTop + new Vector2(box.W * 0.1f, box.H * 0.1f);

                pos = 0;
                do
                {
                    Vector2 randomPoint = new Vector2(Mathematics.Random.Range(min.x, max.x), Mathematics.Random.Range(min.y, max.y));

                    if (collection.Contains(randomPoint))
                    {
                        continue;
                    }

                    testPoints.Add(randomPoint);
                    pos++;
                } while (pos != numberOfRandomPoints);

                points = testPoints.ToArray();
            }
コード例 #24
0
ファイル: MainTest.cs プロジェクト: palkiviad/pathTracing
        public void TestMain()
        {
            Console.WriteLine("Started");

            IMap[] maps = new IMap[Game.pathFinders.Length];
            Array.Copy(Game.pathFinders, maps, maps.Length);

            // Чтобы как-то не дай Бог никакой зависимости от порядка запуска не допустить, рандомизируем.
            Random rnd = new Random();

            maps = maps.OrderBy(x => rnd.Next()).ToArray();

            // Предзагрузим все файлы
            string[] files = Directory.EnumerateFiles(InternalSettings.SettingsDir, "*.*", SearchOption.TopDirectoryOnly)
                             .Where(s => s.EndsWith(".txt") || s.EndsWith(".svg")).ToArray();


            fileToObstacles = new Obstacles[files.Length];
            for (int i = 0; i < files.Length; i++)
            {
                fileToObstacles[i] = new Obstacles(files[i], new InternalObstaclesCollection(files[i]));
            }


            Vector2 temp1 = Vector2.zero;
            Vector2 temp2 = Vector2.zero;

            // Ну и запустим банальные тестики, просто на нахождение пути
            for (int i = 0; i < maps.Length; i++)
            {
                Console.WriteLine("Map: " + maps[i].GetType().Namespace);

                for (int j = 0; j < fileToObstacles.Length; j++)
                {
                    Obstacles obstacle = fileToObstacles[j];

                    int pairsCount = obstacle.points.Length / 2;

                    List <double> durations   = new List <double>();
                    List <double> lengths     = new List <double>();
                    List <int>    pointCounts = new List <int>();
                    //  bool[] successes = new bool[pairsCount];

                    IMap map = maps[i];

                    bool initFail   = false;
                    bool intialized = false;
                    AbortableBackgroundWorker backgroundWorker = new AbortableBackgroundWorker();
                    backgroundWorker.DoWork += delegate {
                        stopwatch.Restart();

                        try {
                            map.Init(obstacle.collection.Data);
                            intialized = true;
                        } catch (Exception) {
                            initFail = true;
                        }

                        stopwatch.Stop();
                    };

                    backgroundWorker.RunWorkerAsync();

                    workerStopwatch.Restart();

                    // здесь мы одновременно ждём результата и считаем время
                    while (true)
                    {
                        if (intialized || initFail)
                        {
                            break;
                        }

                        if (workerStopwatch.ElapsedMilliseconds > 10000)
                        {
                            backgroundWorker.Abort();
                            backgroundWorker.Dispose();
                            //  Console.WriteLine("Init aborted");
                            initFail = true;
                            break;
                        }

                        Thread.Sleep(100);
                    }

                    workerStopwatch.Stop();

                    int failsException = 0;
                    int failsTimeout   = 0;
                    int failsPath      = 0;

                    if (!initFail)
                    {
                        for (int k = 0; k < obstacle.points.Length; k += 2)
                        {
                            bool fail = false;


                            // Увы, но наши досточтимые калеги не смогли написать алгоритмы не уходящие в вечный цикл, или не перебирающие миллионы объектов
                            // Поэтому будем снимать поиски, отрабатывающие дольше секунды

                            IEnumerable <Vector2> path = null;
                            Vector2 a = obstacle.points[k];
                            Vector2 b = obstacle.points[k + 1];

                            backgroundWorker         = new AbortableBackgroundWorker();
                            backgroundWorker.DoWork += delegate {
                                stopwatch.Restart();
                                try {
                                    path = map.GetPath(a, b);
                                } catch (ThreadAbortException) {
                                    fail = true;
                                } catch (Exception) {
                                    failsException++;
                                    fail = true;
                                }

                                stopwatch.Stop();
                            };

                            backgroundWorker.RunWorkerAsync();

                            workerStopwatch.Restart();

                            // здесь мы одновременно ждём результата и считаем время
                            while (true)
                            {
                                if (path != null || fail)
                                {
                                    break;
                                }

                                if (workerStopwatch.ElapsedMilliseconds > 1000)
                                {
                                    backgroundWorker.Abort();
                                    backgroundWorker.Dispose();
                                    //  Console.WriteLine("GetPath aborted");
                                    failsTimeout++;
                                    fail = true;
                                    break;
                                }

                                Thread.Sleep(100);
                            }

                            workerStopwatch.Stop();

                            //    Console.WriteLine("Time elapsed (ms): {0}", stopwatch.Elapsed.TotalMilliseconds);

                            if (!fail && path.Count() < 2)
                            {
                                failsPath++;
                                fail = true;
                            }

                            // Здесь мы должны отвалидировать адекватность пути и если он невалидный, отметить это
                            if (!fail && (path.First() != obstacle.points[k] || path.Last() != obstacle.points[k + 1]))
                            {
                                failsPath++;
                                fail = true;
                            }

                            if (!fail && obstacle.collection.Intersects(path, ref temp1, ref temp2))
                            {
                                failsPath++;
                                fail = true;
                            }

                            if (!fail)
                            {
                                durations.Add(stopwatch.Elapsed.TotalMilliseconds);
                                pointCounts.Add(path.Count());
                                lengths.Add(Length(path));
                            }

                            //   successes[l] = !fail;
                        }
                    }

                    var stats = new Statistics(
                        initFail ? 0 : 1 - (float)(failsPath + failsTimeout + failsException) / pairsCount,
                        durations.Count == 0 ? 0 : durations.Average(),
                        lengths.Count == 0 ? 0 : lengths.Average(),
                        pointCounts.Count == 0 ? 0 : pointCounts.Average(),
                        initFail ? 0 : pairsCount,
                        failsException,
                        failsTimeout,
                        failsPath
                        );

                    Console.WriteLine("File: " + obstacle.file + stats.ToString());

                    statistics.Add(new UserFileStatistics(maps[i].GetType().Namespace.Replace("PathFinder.", ""), obstacle.file, stats));
                }
            }

            SaveStatistics();

            Console.WriteLine("Test finsihed.");
        }
コード例 #25
0
ファイル: Map.cs プロジェクト: palkiviad/pathTracing
 public Segment(Vector2 start, Vector2 end)
 {
     this.start = start;
     this.end   = end;
 }
コード例 #26
0
ファイル: Map.cs プロジェクト: palkiviad/pathTracing
 public void addPoint(Vector2 point)
 {
     points.Add(point);
 }
コード例 #27
0
ファイル: Main.cs プロジェクト: palkiviad/pathTracing
        protected override void OnRenderFrame(FrameEventArgs e)
        {
            base.OnRenderFrame(e);

            GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);

            Matrix4 modelview = Matrix4.LookAt(Vector3.UnitZ, Vector3.Zero, Vector3.UnitY);

            GL.MatrixMode(MatrixMode.Modelview);
            GL.LoadMatrix(ref modelview);

            GL.Hint(HintTarget.LineSmoothHint, HintMode.Nicest);

            //    tr.Draw();

            obstaclesCollection.Draw();

            if (obstaclesCollection.Initialized && !obstaclesCollection.Contains(start) && !obstaclesCollection.Contains(end))
            {
                //  stopwatch.Restart();
                IEnumerable <Vector2> path = map.GetPath(start, end);

                //  stopwatch.Stop();
                //    Console.WriteLine("Time elapsed (ms): {0}", stopwatch.Elapsed.TotalMilliseconds);

                // Сами линии пути
                {
                    GL.Color3(0.5f, 1.0f, 0.5f);
                    GL.LineWidth(3);
                    GL.Begin(PrimitiveType.LineStrip);
                    foreach (Vector2 vertex in path)
                    {
                        GL.Vertex3(vertex.x, vertex.y, 0.0f);
                    }
                    GL.End();
                }

                // Точки на линии пути
                {
                    GL.Color3(1.0f, 1.0f, 0.5f);
                    GL.PointSize(6);
                    GL.Begin(PrimitiveType.Points);
                    foreach (Vector2 vertex in path)
                    {
                        GL.Vertex3(vertex.x, vertex.y, 0.0f);
                    }
                    GL.End();
                }

                Vector2 badSegmentStart = Vector2.zero;
                Vector2 badSegmentEnd   = Vector2.zero;
                if (obstaclesCollection.Intersects(path, ref badSegmentStart, ref badSegmentEnd))
                {
                    //      Console.WriteLine("Intersection");

                    GL.Color3(1f, 0.0f, 0.0f);
                    GL.LineWidth(3);
                    GL.Begin(PrimitiveType.Lines);
                    GL.Vertex3(badSegmentStart.x, badSegmentStart.y, 0.0f);
                    GL.Vertex3(badSegmentEnd.x, badSegmentEnd.y, 0.0f);
                    GL.End();
                }
            }

            // Яркими точечками - начало и конец
            GL.PointSize(12);

            GL.Color3(1.0f, 0.5f, 0.5f);
            GL.Begin(PrimitiveType.Points);
            GL.Vertex3(start.x, start.y, 0.0f);
            GL.End();

            GL.Color3(0.5f, 0.5f, 1.0f);
            GL.Begin(PrimitiveType.Points);
            GL.Vertex3(end.x, end.y, 0.0f);
            GL.End();

            SwapBuffers();
        }