Задать вопрос
  • Построения в 3D карту из ч\б 2D карты?

    @mIka01 Автор вопроса
    Мне все ясно, однако я не могу написать код с быстрым выводом не на Unity. Так что и прошу помощи кого то кто уже сталкивался, решал или кто знает готовое решение.
  • Как запустить параллельно две функции?

    @mIka01 Автор вопроса
    Нет, у меня реально работает. Я даже скриншот выложил. Все без ошибок и чётко, хочешь видео приложу?
  • Как запустить параллельно две функции?

    @mIka01 Автор вопроса
    Я его уже разбил на 4 части одинаковых которые могут выполняться не зависимо друг от друга. Но как рас таки выполнить независимо друг от друга не могу (если быть точнее то каждый раз ошибки с потоками).
  • Как запустить параллельно две функции?

    @mIka01 Автор вопроса
    Нет код выполняется без ошибк, однако я не могу распаралелить.
  • Как запустить параллельно две функции?

    @mIka01 Автор вопроса
    Там есть код который принимает только d меняющиеся и другие переменные которые рашитаные заранее.
  • Как запустить параллельно две функции?

    @mIka01 Автор вопроса
    Код программы выложил в комментариях выше. В распараллеливание поставил цикл
    for (int d = 0; d < f; d++)
    .
  • Как запустить параллельно две функции?

    @mIka01 Автор вопроса
    Надо всю программу ?
  • Как запустить параллельно две функции?

    @mIka01 Автор вопроса
    Ок, попытаюсь минут через 30.
  • Как реализовать триангуляцию?

    @mIka01 Автор вопроса
    static class Helper
        {
            static Random rnd = new Random();
        public static double RndRange(double _min, double _max)
        {
            double range = _max - _min;
            double sample = rnd.NextDouble();
            double scaled = (sample * range) + _min;
            double f = scaled;
            return f;
        }
        }
  • Как реализовать триангуляцию?

    @mIka01 Автор вопроса
    public class Arc //Ребро
        {
    
            public Vector2 A;
            public Vector2 B;
    
            //Ссылка на треугольники в которые входит ребро
            public Triangle trAB;
            public Triangle trBA;
    
            //Ребро является границей триангуляции если не ссылается на 2 треугольника
            public bool IsBorder
            {
                get
                {
                    if (trAB == null || trBA == null)
                        return true;
                    else
                        return false;
                }
                set { }
            }
    
            public Arc(Vector2 _A, Vector2 _B)
            {
                A = _A;
                B = _B;
            }
    
            public static bool ArcIntersect(Arc a1, Arc a2)
            {
                Vector2 p1, p2, p3, p4;
                p1 = a1.A;
                p2 = a1.B;
                p3 = a2.A;
                p4 = a2.B;
    
                //Перепроверить CrossProduct
                double d1 = Direction(p3, p4, p1);
                double d2 = Direction(p3, p4, p2);
                double d3 = Direction(p1, p2, p3);
                double d4 = Direction(p1, p2, p4);
    
                if (p1 == p3 || p1 == p4 || p2 == p3 || p2 == p4)
                    return false;
                else if (((d1 > 0 && d2 < 0) || (d1 < 0 && d2 > 0)) &
                         ((d3 > 0 && d4 < 0) || (d3 < 0 && d4 > 0)))
                    return true;
                else if ((d1 == 0) && OnSegment(p3, p4, p1))
                    return true;
                else if ((d2 == 0) && OnSegment(p3, p4, p2))
                    return true;
                else if ((d3 == 0) && OnSegment(p1, p2, p3))
                    return true;
                else if ((d4 == 0) && OnSegment(p1, p2, p4))
                    return true;
                else
                    return false;
            }
    
            public static bool ArcIntersect(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4)
            {
    
                //Перепроверить CrossProduct
                double d1 = Direction(p3, p4, p1);
                double d2 = Direction(p3, p4, p2);
                double d3 = Direction(p1, p2, p3);
                double d4 = Direction(p1, p2, p4);
    
                if (p1 == p3 || p1 == p4 || p2 == p3 || p2 == p4)
                    return false;
                else if (((d1 > 0 && d2 < 0) || (d1 < 0 && d2 > 0)) &
                         ((d3 > 0 && d4 < 0) || (d3 < 0 && d4 > 0)))
                    return true;
                else if ((d1 == 0) && OnSegment(p3, p4, p1))
                    return true;
                else if ((d2 == 0) && OnSegment(p3, p4, p2))
                    return true;
                else if ((d3 == 0) && OnSegment(p1, p2, p3))
                    return true;
                else if ((d4 == 0) && OnSegment(p1, p2, p4))
                    return true;
                else
                    return false;
            }
    
            public Vector2 GetSecondNode(Vector2 _firstnode)
            {
                if (A == _firstnode)
                    return B;
                else if (B == _firstnode)
                    return A;
                else
                    return null;
            }
    
            public Triangle GetOtherTriangle(Triangle T1)
            {
                if (trAB == T1)
                    return trBA;
                else if (trBA == T1)
                    return trAB;
                else
                    return null;
            }
    
            public static Vector2 GetCommonPoint(Arc a1, Arc a2)
            {
                if (a1.A == a2.A)
                    return a1.A;
                else if (a1.A == a2.B)
                    return a1.A;
                else if (a1.B == a2.A)
                    return a1.B;
                else if (a1.B == a2.B)
                    return a1.B;
                else
                    return null;
            }
    
            //Определяет, связаны ли ребра
            public bool IsConnectedWith(Arc _a)
            {
                if (A == _a.A || A == _a.B)
                    return true;
    
                if (B == _a.A || B == _a.B)
                    return true;
    
                return false;
            }
    
            private static double Direction(Vector2 pi, Vector2 pj, Vector2 pk)
            {
                return Vector2.CrossProduct((pk - pi), (pj - pi));
            }
            private static bool OnSegment(Vector2 pi, Vector2 pj, Vector2 pk)
            {
                if ((Math.Min(pi.x, pj.x) <= pk.x && pk.x <= Math.Max(pi.x, pj.x)) && (Math.Min(pi.y, pj.y) <= pk.y && pk.y <= Math.Max(pi.y, pj.y)))
                    return true;
                else
                    return false;
            }
    
    
    
        }
  • Как реализовать триангуляцию?

    @mIka01 Автор вопроса
    class DynamicCache
        {
            private Triangle[] Cache = new Triangle[4];
    
            //Текущий размер кэша
            private UInt32 Size = 2;
    
            //Треугольников в кэше
            private UInt32 InCache = 0;
    
            //Реальные размеры кэшируемого пространства
            private Vector2 SizeOfSpace;
    
            //Размеры одной ячейки кэша в пересчете на реальное пространство
            private double xSize;
            private double ySize;
    
            public DynamicCache(Vector2 _sizeOfSpace)
            {
                SizeOfSpace = _sizeOfSpace;
                xSize = SizeOfSpace.x / (double)Size;
                ySize = SizeOfSpace.y / (double)Size;
            }
    
            public void Add(Triangle _T)
            {
                InCache++;
    
                if (InCache >= Cache.Length * 3)
                    Increase();
    
                Cache[GetKey(_T.Centroid)] = _T;
            }
    
            public Triangle FindTriangle(Vector2 _Point)
            {
                UInt32 key = GetKey(_Point);
                if (Cache[key] != null)
                    return Cache[key];
    
                //Дополнительный поиск ближайшей ненулевой ячейки. Несколько ускоряет работу алгоритма 
                for (uint i = key - 25; i < key && i >= 0 && i < Cache.Length; i++)
                    if (Cache[i] != null)
                        return Cache[i];
    
                for (uint i = key + 25; i > key && i >= 0 && i < Cache.Length; i--)
                    if (Cache[i] != null)
                        return Cache[i];
    
                return null;
            }
    
            //Увеличивает размер кэша в 4 раза
            private void Increase()
            {
                Triangle[] NewCache = new Triangle[(Size * 2) * (Size * 2)];
                UInt32 newIndex = 0;
    
                //Передача ссылок из старого кэша в новый
                for (UInt32 i = 0; i < Cache.Length; i++)
                {
                    newIndex = GetNewIndex(i);
                    NewCache[newIndex] = Cache[i];
                    NewCache[newIndex + 1] = Cache[i];
                    NewCache[newIndex + Size * 2] = Cache[i];
                    NewCache[newIndex + Size * 2 + 1] = Cache[i];
                }
    
                Size = Size * 2;
                xSize = SizeOfSpace.x / (double)Size;
                ySize = SizeOfSpace.y / (double)Size;
    
                Cache = NewCache;
            }
    
            private UInt32 GetKey(Vector2 _point)
            {
                UInt32 i = (UInt32)(_point.y / ySize);
                UInt32 j = (UInt32)(_point.x / xSize);
    
                if (i == Size)
                    i--;
                if (j == Size)
                    j--;
    
                return i * Size + j;
            }
    
            private UInt32 GetNewIndex(UInt32 _OldIndex)
            {
                UInt32 i = (_OldIndex / Size) * 2;
                UInt32 j = (_OldIndex % Size) * 2;
    
                return i * (Size * 2) + j;
            }
        }
  • Как реализовать триангуляцию?

    @mIka01 Автор вопроса
    public class Triangle
        {
            public Vector2[] points = new Vector2[3];
            public Arc[] arcs = new Arc[3];
    
            public Vector2 Centroid
            {
                get
                {
                    return points[2] - ((points[2] - (points[0] + ((points[1] - points[0]) * 0.5))) * 0.6666666);
                }
    
                set
                { }
            }
    
            public System.Drawing.Color color;
    
            public Triangle(Vector2 _a, Vector2 _b, Vector2 _c)
            {
                points[0] = _a;
                points[1] = _b;
                points[2] = _c;
    
                arcs[0] = new Arc(_a, _b);
                arcs[1] = new Arc(_b, _c);
                arcs[2] = new Arc(_c, _a);
            }
    
            public Triangle(Arc _arc, Vector2 _a)
            {
                points[0] = _arc.A;
                points[1] = _arc.B;
                points[2] = _a;
    
                arcs[0] = _arc;
                arcs[1] = new Arc(points[1], points[2]);
                arcs[2] = new Arc(points[2], points[0]);
            }
    
            public Triangle(Arc _arc0, Arc _arc1, Arc _arc2)
            {
                arcs[0] = _arc0;
                arcs[1] = _arc1;
                arcs[2] = _arc2;
    
                points[0] = _arc0.A;
                points[1] = _arc0.B;
    
                if (_arc1.A == _arc0.A || _arc1.A == _arc0.B)
                    points[2] = _arc1.B;
                else if (_arc1.B == _arc0.A || _arc1.B == _arc0.B)
                    points[2] = _arc1.A;
                else if (points[2] != _arc2.A && points[2] != _arc2.B)
                {
                    Console.WriteLine("ARC0.A: " + _arc0.A.x + " " + _arc0.A.y);
                    Console.WriteLine("ARC0.B: " + _arc0.B.x + " " + _arc0.B.y);
                    Console.WriteLine("ARC1.A: " + _arc1.A.x + " " + _arc1.A.y);
                    Console.WriteLine("ARC1.B: " + _arc1.B.x + " " + _arc1.B.y);
                    Console.WriteLine("ARC2.A: " + _arc2.A.x + " " + _arc2.A.y);
                    Console.WriteLine("ARC2.B: " + _arc2.B.x + " " + _arc2.B.y);
    
                    throw new Exception("Попытка создать треугольник из трех непересекающихся ребер");
                }
    
            }
    
            public Vector2 GetThirdPoint(Arc _arc)
            {
                for (int i = 0; i < 3; i++)
                    if (_arc.A != points[i] && _arc.B != points[i])
                        return points[i];
    
                return null;
            }
    
            public Arc GetArcBeatwen2Points(Vector2 _a, Vector2 _b)
            {
                for (int i = 0; i < 3; i++)
                    if (arcs[i].A == _a && arcs[i].B == _b || arcs[i].A == _b && arcs[i].B == _a)
                        return arcs[i];
    
                return null;
            }
    
    
            public static Vector2 Get4Point(Triangle T1, Triangle T2)
            {
                for (int i = 0; i < 3; i++)
                    if (T2.points[i] != T1.points[0] && T2.points[i] != T1.points[1] && T2.points[i] != T1.points[2])
                        return T2.points[i];
    
                return null;
            }
    
            public void GetTwoOtherArcs(Arc _a0, out Arc _a1, out Arc _a2)
            {
                if (arcs[0] == _a0)
                { _a1 = arcs[1]; _a2 = arcs[2]; }
                else if (arcs[1] == _a0)
                { _a1 = arcs[0]; _a2 = arcs[2]; }
                else if (arcs[2] == _a0)
                { _a1 = arcs[0]; _a2 = arcs[1]; }
                else
                { _a1 = null; _a2 = null; }
            }
    
            //Возвращает 4 точки, где: [0] принадлежит T1, [1] и [2] общие, [3] принадлежит T2
            public static Vector2[] Get4Point2(Triangle T1, Triangle T2)
            {
                Vector2[] Points = new Vector2[4];
    
                for (int i = 0; i < 3; i++)
                {
                    if (T2.points[i] != T1.points[0] && T2.points[i] != T1.points[1] && T2.points[i] != T1.points[2])
                        Points[3] = T2.points[i];
    
                    if (T1.points[i] != T2.points[0] && T1.points[i] != T2.points[1] && T1.points[i] != T2.points[2])
                        Points[0] = T1.points[i];
    
                    if (T2.points[i] == T1.points[1])
                        Points[1] = T2.points[i];
                    else if (T2.points[i] == T1.points[2])
                        Points[2] = T2.points[i];
    
                }
    
                return Points;
            }
        }
  • Как реализовать триангуляцию?

    @mIka01 Автор вопроса
    public class Vector2
        {
            public double x;
            public double y;
    
            public Vector2()
            {
                x = 0f;
                y = 0f;
            }
    
            public Vector2(double _x, double _y)
            {
                x = _x;
                y = _y;
            }
    
            public double sqrMagnitude()
            {
                return (x * x + y * y);
            }
    
            public double Magnitude()
            {
                return Math.Sqrt(x * x + y * y);
            }
    
            public static Vector2 operator -(Vector2 _a, Vector2 _b)
            {
                return new Vector2(_a.x - _b.x, _a.y - _b.y);
            }
    
            public static Vector2 operator +(Vector2 _a, Vector2 _b)
            {
                return new Vector2(_a.x + _b.x, _a.y + _b.y);
            }
    
            public static Vector2 operator *(Vector2 _a, double s)
            {
                return new Vector2(_a.x * s, _a.y * s);
            }
    
            public static double CrossProduct(Vector2 v1, Vector2 v2) //Векторное произведение
            {
                return v1.x * v2.y - v2.x * v1.y;
            }
    
            public static double DotProduct(Vector2 v1, Vector2 v2) //Скалярное произведение
            {
                return v1.x * v2.x + v2.y * v1.y;
            }
    
            public static double AngleBetweenVectors(Vector2 v1, Vector2 v2)
            {
                return Math.Acos(Vector2.DotProduct(v1, v2) / (v1.Magnitude() * v2.Magnitude()));
            }
    
            public static Vector2 Vector2Rnd(Double RangeXmin, Double RangeXmax, Double RangeYmin, Double RangeYmax)
            {
                return new Vector2(Helper.RndRange(RangeXmin, RangeXmax), Helper.RndRange(RangeYmin, RangeYmax));
            }
    
            //Если Точка P2 находится слева от вектора (P1-P0) возвращает true
            public static int isLeft(Vector2 P0, Vector2 P1, Vector2 P2)
            {
                double result = ((P1.x - P0.x) * (P2.y - P0.y) - (P2.x - P0.x) * (P1.y - P0.y));
    
                if (result > 0d)
                    return 1;
                else if (result < 0d)
                    return -1;
                else
                    return 0; //Лежит на линии
            }
    
        }
  • Как реализовать триангуляцию?

    @mIka01 Автор вопроса
    Продолжение класса.
    //Возвращает треугольник в котором находится данная точка
            private Triangle GetTriangleForPoint(Vector2 _point)
            {
                Triangle link = Cache.FindTriangle(_point);
    
                if (link == null)
                {
                    link = triangles[0];
                }
    
                if (IsPointInTriangle(link, _point))
                {
                    return link;
                }
                else
                {
                    //Путь от некоторого треугольника до искомой точки
                    Arc way = new Arc(_point, link.Centroid);
                    Arc CurentArc = null;
    
                    while (!IsPointInTriangle(link, _point))
                    {
                        CurentArc = GetIntersectedArc(way, link);
                        if (link != CurentArc.trAB)
                            link = CurentArc.trAB;
                        else
                            link = CurentArc.trBA;
    
                        way = new Arc(_point, link.Centroid);
                    }
                    return link;
    
                }
            }
    
            //Возвращает ребро треугольника которое пересекается с линией
            private Arc GetIntersectedArc(Arc Line, Triangle Target)
            {
                if (Arc.ArcIntersect(Target.arcs[0], Line))
                    return Target.arcs[0];
                if (Arc.ArcIntersect(Target.arcs[1], Line))
                    return Target.arcs[1];
                if (Arc.ArcIntersect(Target.arcs[2], Line))
                    return Target.arcs[2];
    
                return null;
            }
    
            private bool IsPointInTriangle(Triangle _triangle, Vector2 _point)
            {
                Vector2 P1 = _triangle.points[0];
                Vector2 P2 = _triangle.points[1];
                Vector2 P3 = _triangle.points[2];
                Vector2 P4 = _point;
    
                double a = (P1.x - P4.x) * (P2.y - P1.y) - (P2.x - P1.x) * (P1.y - P4.y);
                double b = (P2.x - P4.x) * (P3.y - P2.y) - (P3.x - P2.x) * (P2.y - P4.y);
                double c = (P3.x - P4.x) * (P1.y - P3.y) - (P1.x - P3.x) * (P3.y - P4.y);
    
                if ((a >= 0 && b >= 0 && c >= 0) || (a <= 0 && b <= 0 && c <= 0))
                    return true;
                else
                    return false;
            }
    
            //Вычисление критерия Делоне по описанной окружности
            private bool IsDelaunay(Vector2 A, Vector2 B, Vector2 C, Vector2 _CheckNode)
            {
                double x0 = _CheckNode.x;
                double y0 = _CheckNode.y;
                double x1 = A.x;
                double y1 = A.y;
                double x2 = B.x;
                double y2 = B.y;
                double x3 = C.x;
                double y3 = C.y;
    
                double[] matrix = { (x1 - x0)*(x1 - x0) + (y1 - y0)*(y1 - y0), x1 - x0, y1 - y0,
                                     (x2 - x0)*(x2 - x0) + (y2 - y0)*(y2 - y0), x2 - x0, y2 - y0,
                                     (x3 - x0)*(x3 - x0) + (y3 - y0)*(y3 - y0), x3 - x0, y3 - y0};
    
                double matrixDeterminant = matrix[0] * matrix[4] * matrix[8] + matrix[1] * matrix[5] * matrix[6] + matrix[2] * matrix[3] * matrix[7] -
                                            matrix[2] * matrix[4] * matrix[6] - matrix[0] * matrix[5] * matrix[7] - matrix[1] * matrix[3] * matrix[8];
    
                double a = x1 * y2 * 1 + y1 * 1 * x3 + 1 * x2 * y3
                         - 1 * y2 * x3 - y1 * x2 * 1 - 1 * y3 * x1;
    
                //Sgn(a)
                if (a < 0)
                    matrixDeterminant *= -1d;
    
                if (matrixDeterminant < 0d)
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
    
            //Вычисление критерия Делоне по противолежащим углам
            private bool IsDelaunay2(Vector2 v0, Vector2 v1, Vector2 v2, Vector2 v3)
            {
                double x0 = v0.x;
                double y0 = v0.y;
                double x1 = v1.x;
                double y1 = v1.y;
                double x2 = v3.x;
                double y2 = v3.y;
                double x3 = v2.x;
                double y3 = v2.y;
    
                double CosA = (x0 - x1) * (x0 - x3) + (y0 - y1) * (y0 - y3);
                double CosB = (x2 - x1) * (x2 - x3) + (y2 - y1) * (y2 - y3);
    
                if (CosA < 0 && CosB < 0)
                    return false;
    
                if (CosA >= 0 && CosB >= 0)
                    return true;
    
                double SinA = (x0 - x1) * (y0 - y3) - (x0 - x3) * (y0 - y1);
                double SinB = (x2 - x3) * (y2 - y1) - (x2 - x1) * (y2 - y3);
    
                if (SinA * CosB + CosA * SinB >= 0)
                    return true;
                else
                    return false;
    
            }
    
            private void CheckDelaunayAndRebuild(Arc arc)
            {
                Triangle T1 = null;
                Triangle T2 = null;
    
                if (arc.trAB != null && arc.trBA != null)
                {
                    T1 = arc.trAB;
                    T2 = arc.trBA;
                }
                else
                    return;
    
                Vector2[] CurentPoints = new Vector2[4];
    
                Arc OldArcT1A1 = null;
                Arc OldArcT1A2 = null;
                Arc OldArcT2A1 = null;
                Arc OldArcT2A2 = null;
    
                Arc NewArcT1A1 = null;
                Arc NewArcT1A2 = null;
                Arc NewArcT2A1 = null;
                Arc NewArcT2A2 = null;
    
                CurentPoints[0] = T1.GetThirdPoint(arc);
                CurentPoints[1] = arc.A;
                CurentPoints[2] = arc.B;
                CurentPoints[3] = T2.GetThirdPoint(arc);
    
                //Дополнительная проверка, увеличивает скорость алгоритма на 10%
                if (Arc.ArcIntersect(CurentPoints[0], CurentPoints[3], CurentPoints[1], CurentPoints[2]))
                    if (!IsDelaunay(CurentPoints[0], CurentPoints[1], CurentPoints[2], CurentPoints[3]))
                    {
    
                        T1.GetTwoOtherArcs(arc, out OldArcT1A1, out OldArcT1A2);
                        T2.GetTwoOtherArcs(arc, out OldArcT2A1, out OldArcT2A2);
    
                        if (OldArcT1A1.IsConnectedWith(OldArcT2A1))
                        {
                            NewArcT1A1 = OldArcT1A1; NewArcT1A2 = OldArcT2A1;
                            NewArcT2A1 = OldArcT1A2; NewArcT2A2 = OldArcT2A2;
                        }
                        else
                        {
                            NewArcT1A1 = OldArcT1A1; NewArcT1A2 = OldArcT2A2;
                            NewArcT2A1 = OldArcT1A2; NewArcT2A2 = OldArcT2A1;
                        }
    
                        //Изменение ребра
                        arc.A = CurentPoints[0];
                        arc.B = CurentPoints[3];
    
                        //переопределение ребер треугольников
                        T1.arcs[0] = arc;
                        T1.arcs[1] = NewArcT1A1;
                        T1.arcs[2] = NewArcT1A2;
    
                        T2.arcs[0] = arc;
                        T2.arcs[1] = NewArcT2A1;
                        T2.arcs[2] = NewArcT2A2;
    
                        //перезапись точек треугольников
                        T1.points[0] = arc.A;
                        T1.points[1] = arc.B;
                        T1.points[2] = Arc.GetCommonPoint(NewArcT1A1, NewArcT1A2);
    
                        T2.points[0] = arc.A;
                        T2.points[1] = arc.B;
                        T2.points[2] = Arc.GetCommonPoint(NewArcT2A1, NewArcT2A2);
    
                        //Переопределение ссылок в ребрах
                        if (NewArcT1A2.trAB == T2)
                            NewArcT1A2.trAB = T1;
                        else if (NewArcT1A2.trBA == T2)
                            NewArcT1A2.trBA = T1;
    
                        if (NewArcT2A1.trAB == T1)
                            NewArcT2A1.trAB = T2;
                        else if (NewArcT2A1.trBA == T1)
                            NewArcT2A1.trBA = T2;
    
                        //Добавление треугольников в кэш
                        Cache.Add(T1);
                        Cache.Add(T2);
    
                    }
            }
        }