private int FindEdge ref int int dir int Point pon функция для поиска

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
private int FindEdge(ref int i, int dir, int n, Point[] pon)//функция для поиска края
{
for (; ; ) // бесконечный цикл
{
int i1 = i + dir; // ищем край
if (i1 < 0) // перебор
i1 = n - 1; // по
else // всем
if (i1 >= n) i1 = 0; // вершинам и просмотр
if (P[i1].Y < P[i].Y) return -1; // ребро [i,i1] идет вверх
else
if (P[i1].Y == P[i].Y) i = i1; // горизонтальное ребро
else return i1; // ребро [i,i1] идет вниз
}
}
private void FillConvexPolygon(Point[] points, int c)
{
int yMin = points[0].Y, yMax = points[0].Y, topPointIndex = 0;
for (int i = 1; i < c; i++)
{
if (points[i].Y < points[topPointIndex].Y)// поиск самой верхней вершины по У, все тело цикла делает только это
{
topPointIndex = i;
}
else
{
if (points[i].Y > yMax)
{
yMax = points[i].Y;
}
}
}
yMin = points[topPointIndex].Y;
if (yMin == yMax) // проверка на косяк, если у нас многоугольник - прямая
{
int xMin = points[0].X, xMax = points[0].X;
for (int i = 1; i < c; i++)
{
if (points[i].X < xMin)
{
xMin = points[i].X;
}
else
{
if (points[i].X > xMax)
{
xMax = points[i].X;
}
}
}
Graphics.FromHwnd(this.Handle).DrawLine(new Pen(Color.Black), xMin, yMin, xMax, yMax);
return;
}
// самое важное: ищем вершины, между которыми будем закрашивать линиями наш многоугольник
// суть проста, находим текущую и следующую вершину, запоминаем их и движемся дальше, по названию переменных,
// думаю, поймешь, что есть текущая, а что есть следующая
int i1, i1next, i2, i2next;
i1 = topPointIndex;
i1next = FindEdge(ref i1, -1, c, points);
i2 = topPointIndex;
i2next = FindEdge(ref i2, 1, c, points);
int x1, x2;
for (int y = yMin; y <= yMax; y++)
{
// снова формулы, мы движемся по У от одной вершины до другой, так же как и с треугольником, нам нужны координаты
// по Х, чтобы отрисовать линию, они ведь изменяются после "спуска", поэтому в этих формулах мы считаем эти Х
x1 = points[i1].X + (y - points[i1].Y) * (points[i1next].X - points[i1].X) / (points[i1next].Y - points[i1].Y);
x2 = points[i2].X + (y - points[i2].Y) * (points[i2next].X - points[i2].X) / (points[i2next].Y - points[i2].Y);
Graphics.FromHwnd(this.Handle).DrawLine(new Pen(Color.Black), x1, y, x2, y);// Ну и отрисуем сразу первую посчитанную
if (y + 1 == points[i1next].Y) // тут банальная проверка на то, а не вышли ли мы за пределы нашего массива вершин
{
i1 = i1next;
i1next = i1next - 1 < 0 ? c - 1 : i1next - 1;
if (points[i1].Y == points[i1next].Y)
{
break;
}
}
if (y + 1 == points[i2next].Y)
{
i2 = i2next;
i2next = i2next + 1 >= c ? 0 : i2next + 1;
if (points[i2].Y == points[i2next].Y)
{
break;
}
}
}
}
// так кратенько описал, если нужно больше подробностей, то напишу подробнее