private void MyBGWorker_DoWork(object sender, DoWorkEventArgs e) { /* Работа потока */ // стек окон // List <int[]> windows = new List <int[]>(); // добавляем в стек фулл окно // int[] a = { 0, 0, WIN_SIZE }; windows.Add(a); // кол-во итераций // num_iter = 0; // пока стек не пуст // выполняем цикл обработки окна из стека // while (windows.Count != 0) { // если отменили выполнение потока - выходим из цикла // иначе выполняем обработку очередного окна из стека // if (MyBGWorker.CancellationPending == true) { e.Cancel = true; break; } else { // инкриментируем кол-во итераций // num_iter++; // берем из стека очередное окно, удаляя его из стека // int[] win = windows[0]; windows.RemoveAt(0); // данные окна, используемые во время цикла обработки // int x = win[0], y = win[1], size = win[2]; // если окно размером в 1 пиксель // if (size == 1) { // необходимо понять каким цветом покрасить этот пиксель // для этого необходимо понять какой многоугольник экранирует // т.е. у какого многоугольника Z в данной точке ближе к наблюдателю // если вообще есть многоугольник в этом пискеле // иначе покрасить фоном float max_z = -1000; Polygon max_polygon = null; // для каждого многоугольника вычисляем Z в данной точке // и запоминаем наибольшее (ближайшее) к наблюдателю // foreach (var polygon in polygons) { if (Warnock.IsPointInside(new MyPoint(x, y, 0), polygon)) { float z = Warnock.FindCoordZ(new MyPoint(x, y, 0), polygon); if (z > max_z) { max_polygon = polygon; max_z = z; } } } // если не нашли многоугольник красим в цвет фона // иначе красим цветом многоугольника // Color color; if (max_polygon == null) { color = BG_COLOR; } else { color = max_polygon.color; } // отрисовка // Draw(x, y, size, color); //message = "Pixel " + color.ToString() + " at ( " + x.ToString() + " , " + y.ToString() + " )"; message = ""; Thread.Sleep(SLEEP_TIME); MyBGWorker.ReportProgress(num_iter); // возвращаемся в начало цикла while // continue; } // создаем многоугольник "квадрат" - текущее окно // List <MyPoint> temp = new List <MyPoint>(); temp.Add(new MyPoint(x, y, 0)); temp.Add(new MyPoint(x, y + size, 0)); temp.Add(new MyPoint(x + size, y + size, 0)); temp.Add(new MyPoint(x + size, y, 0)); Polygon rectangle = new Polygon(temp, Color.White); // если опция включена // нарисовать текущий квадрат // if (checkBox_splitting.Checked) { if (size - 1 != 1) { DrawRect(x, y, size - 1, SPLIT_COLOR); message = ""; Thread.Sleep(SLEEP_TIME); MyBGWorker.ReportProgress(num_iter); } } // посчитаем кол-во многоугольников, которые пересекаются с окном // List <bool> is_intersec_poly = new List <bool>(); foreach (var polygon in polygons) { is_intersec_poly.Add(Warnock.IsIntersected(rectangle, polygon)); } int num_intersec_poly = 0; foreach (var value in is_intersec_poly) { if (value) { num_intersec_poly++; } } // -- Имеется единственный охватывающий многоугольник. В этом случае окно закрашивается его цветом. -- // // если квадрат расположен полностью в многоугольнике и такой многоугольник один // т.е. многоугольник экранирует // // считаем для каждого многоугольника след.параметр: // кол-во вершин квадрата, которые входят в каждый многоугольник // List <int> rec_in_poly = new List <int>(); foreach (var polygon in polygons) { rec_in_poly.Add(Warnock.PointsInPolygon(rectangle.points, polygon)); } List <int> indices_covering = new List <int>(); for (int i = 0; i < rec_in_poly.Count; i++) { if (rec_in_poly[i] == 4) { indices_covering.Add(i); } } if (indices_covering.Count == 1 && num_intersec_poly == 1) { // отрисовка // Draw(x, y, size, polygons[indices_covering[0]].color); message = "Poly " + polygons[indices_covering[0]].color.ToString() + " at ( " + x.ToString() + " , " + y.ToString() + " ) Size = " + size.ToString(); Thread.Sleep(SLEEP_TIME); MyBGWorker.ReportProgress(num_iter); // возвращаемся в начало цикла while // continue; } // считаем для каждого многоугольника след.параметры: // 1. кол-во вершин квадрата, которые входят в каждый многоугольник // 2. кол-во вершин каждого многоугольника, которые входят в квадрат // bool split = false; if (is_intersec_poly.Contains(true)) { split = true; } // -- Все многоугольники сцены - внешние по отношению к окну. В этом случае окно закрашивается фоном -- // // если квадрат не внутри никакого многоугольника // и внутри квадрата нет многоугольника // то закрашиваем квадрат фоном // if (!split) { // отрисовка // Draw(x, y, size, BG_COLOR); message = "Whitebox at ( " + x.ToString() + " , " + y.ToString() + " ) Size = " + size.ToString(); Thread.Sleep(SLEEP_TIME); MyBGWorker.ReportProgress(num_iter); // возвращаемся в начало цикла while // continue; } // -- Пересекающий многоугольник -- // // если внутри квадрата есть хотя бы одна вершина многоугольника - разбиваем квадрат // else { windows.AddRange(Warnock.SplitWindow(x, y, size)); // возвращаемся в начало цикла while // continue; } } } //end while }