private OptimumConversionBuilder CreateOptimumBuilder(Triangle from, List<Triangle> list)
        {
            OptimumConversionBuilder ocb = null;

            foreach (Triangle t in list)
            {
                OptimumConversionBuilder ocbTmp = new OptimumConversionBuilder(from, t);
                if (ocb == null || ocbTmp.Distance < ocb.Distance)
                    ocb = ocbTmp;
            }

            return ocb;
        }
        private Triangle FindEquals(Triangle triangle, List<Triangle> list)
        {
            Triangle result = null;

            foreach (Triangle t in list)
            {
                if (t.Equals(triangle))
                    return t;
            }

            return result;
        }
 private Triangle FindNear(Triangle triangle, double distance, List<Triangle> list)
 {
     Triangle result = null;
     double nearDistance = -1;
     foreach (Triangle t in list)
     {
         if (t.Equals(triangle, distance))
         {
             double tmpNearDistance = t.GetDistanceTo(triangle);
             if (tmpNearDistance < nearDistance || nearDistance == -1)
             {
                 result = t;
                 nearDistance = tmpNearDistance;
             }
         }
     }
     return result;
 }
 public double GetDistanceTo(Triangle triangle)
 {
     return triangle.A.GetDistance(A) * triangle.A.GetDistance(A) +
         (triangle.B.GetDistance(B) * triangle.B.GetDistance(B)) +
         (triangle.C.GetDistance(C) * triangle.C.GetDistance(C));
 }
 public bool Equals(Triangle triangle, double distance)
 {
     if (A.GetDistance(triangle.A) < distance && B.GetDistance(triangle.B) < distance && C.GetDistance(triangle.C) < distance)
         return true;
     if (A.GetDistance(triangle.A) < distance && B.GetDistance(triangle.C) < distance && C.GetDistance(triangle.B) < distance)
         return true;
     if (A.GetDistance(triangle.B) < distance && B.GetDistance(triangle.C) < distance && C.GetDistance(triangle.A) < distance)
         return true;
     if (A.GetDistance(triangle.B) < distance && B.GetDistance(triangle.A) < distance && C.GetDistance(triangle.C) < distance)
         return true;
     if (A.GetDistance(triangle.C) < distance && B.GetDistance(triangle.B) < distance && C.GetDistance(triangle.A) < distance)
         return true;
     if (A.GetDistance(triangle.C) < distance && B.GetDistance(triangle.A) < distance && C.GetDistance(triangle.B) < distance)
         return true;
     return false;
 }
 public Section(Vector vector, Triangle left = null, Triangle right = null)
 {
     this.Vector = vector;
     this.Left = left;
     this.Right = right;
 }
        private bool UpdateTriangles(Triangle tRight, Triangle tLeft, Section commonSection, List<Triangle> tmpResult, Graphics g = null, Pen linePen = null, Pen pointPen = null, Pen newLinePen = null, int formHeight = 0, int delay = 0)
        {
            //меняем общее ребро у двух треугольников
            Point leftExcessPoint = TriangulationBuilder.GetExcessPoint(tLeft, commonSection);
            Point rightExcessPoint = TriangulationBuilder.GetExcessPoint(tRight, commonSection);

            if (commonSection.CountAnglesSum(leftExcessPoint) + commonSection.CountAnglesSum(rightExcessPoint) < 180)
            {
                Point up = commonSection.A;
                Point down = commonSection.B;
                if (new Vector(down, rightExcessPoint).GetVectorMultiplication(new Vector(down, leftExcessPoint)) < 0)
                {
                    up = commonSection.B;
                    down = commonSection.A;
                }

                tmpResult.Remove(tLeft);
                tmpResult.Remove(tRight);
                Triangle toAddFirst = new Triangle(leftExcessPoint, down, rightExcessPoint);
                Triangle toAddSecond = new Triangle(rightExcessPoint, up, leftExcessPoint);
                tmpResult.Add(toAddFirst);
                tmpResult.Add(toAddSecond);

                if (g != null && linePen != null && newLinePen != null && formHeight != -1 && delay != -1)
                {
                    g.DrawLine(new Pen(Color.White, 2), (int)commonSection.A.X, formHeight - (int)commonSection.A.Y,
                        (int)commonSection.B.X, formHeight - (int)commonSection.B.Y);
                    g.DrawLine(newLinePen, (int)leftExcessPoint.X, formHeight - (int)leftExcessPoint.Y, (int)rightExcessPoint.X, formHeight - (int)rightExcessPoint.Y);

                    Thread.Sleep(delay);

                    g.DrawLine(new Pen(Color.White, 2), (int)leftExcessPoint.X, formHeight - (int)leftExcessPoint.Y, (int)rightExcessPoint.X, formHeight - (int)rightExcessPoint.Y);
                    g.DrawLine(linePen, (int)leftExcessPoint.X, formHeight - (int)leftExcessPoint.Y, (int)rightExcessPoint.X, formHeight - (int)rightExcessPoint.Y);

                    toAddFirst.Paint(g, linePen, pointPen, formHeight);
                    toAddSecond.Paint(g, linePen, pointPen, formHeight);
                }
                return true;
            }
            return false;
        }
        private void UpdateShell()
        {
            /*
             * Идея следующая: берем два соседних ребра в оболочке, (по способу построения они идут против часовой стрелки)
             * вычисляем их векторное произведение. Если оно положительно - оболочка не выпукла, нужно добавить в неё ребро,
             * а эти два удалить. Так же, нужно добавить треугольник. И так до тех пор, пока не сделаем полный проход, при этом
             * не изменив ни одного ребра.
             */
            bool shellChanged = true;
            while (shellChanged)
            {
                shellChanged = false;
                for (int i = 0; i < shell.Count - 1; i++)
                {
                    if (shell[i].GetVectorMultiplication(shell[i + 1]) < 0)
                    {
                        triangles.Add(new Triangle(shell[i].Start, shell[i].End, shell[i + 1].End));

                        shell[i] = new Vector(shell[i].Start, shell[i + 1].End);
                        shell.RemoveAt(i + 1);

                        shellChanged = true;
                    }
                }

                if (shell[shell.Count - 1].GetVectorMultiplication(shell[0]) < 0)
                {
                    Triangle t = new Triangle(shell[shell.Count - 1].Start,  shell[0].End, shell[shell.Count - 1].End);
                    triangles.Add(t);

                    shell[shell.Count - 1] = new Vector(shell[shell.Count - 1].Start, shell[0].End);
                    shell.RemoveAt(0);

                    shellChanged = true;
                }
            }
        }
        private Triangle GetNearestTriangleWithCommonSideInList(Triangle destination, bool a, bool b, bool c, List<Triangle> list)
        {
            foreach (Triangle t in list)
            {
                if (t.Equals(destination))
                    continue;
                if (a && (destination.a.Equals(t.a) || destination.a.Equals(t.b) || destination.a.Equals(t.c)))
                    return t;

                if (b && (destination.b.Equals(t.a) || destination.b.Equals(t.b) || destination.b.Equals(t.c)))
                    return t;

                if (c && (destination.c.Equals(t.a) || destination.c.Equals(t.b) || destination.c.Equals(t.c)))
                    return t;

            }
            return null;
        }
 private static Point GetExcessPoint(Triangle t, Section s)
 {
     //ищем точку из треугольника, не лежащую на ребре
     Point excessPoint;
     if (!t.A.Equals(s.A) && !t.A.Equals(s.B))
         excessPoint = t.A;
     else
         if (!t.B.Equals(s.A) && !t.B.Equals(s.B))
             excessPoint = t.B;
         else
             excessPoint = t.C;
     return excessPoint;
 }