{ Graphics g = Graphics.FromHwnd(this.Handle); // концы отрезка Point A = new Point(x[0], y[0]); Point B = new Point(x[1], y[1]); //направляющий вектор АВ Point vecAB = new Point(B.X - A.X, B.Y - A.Y); //t входа и выхода float tin = 0; float tout = 1; float d; Point n; // нормаль float thit; bool clockwise = true;//обход по часовой //Псевдоскаляр позволяет узнать движение по векторам происходит по часовой стрелке или против, для этого мы берем первые 2 ребра многоугольника if (PsevdoScal(new Point(x[2] - x[3], y[2] - y[3]), new Point(x[4] - x[3], y[4] - y[3])) < 0) clockwise = false; for (int j = 2; j < i - 1; j++) { //в зависимости от того, по часовой или против мы движемся, мы по-разному считаем нормаль. формулы в функциях есть. if (!clockwise) { n = Normalout(new Point(x[j + 1] - x[j], y[j + 1] - y[j])); } else { n = Normalin(new Point(x[j + 1] - x[j], y[j + 1] - y[j])); } //тут просто фрагмент из лекции. деление скалярных произведений для того, чтобы найти момент времени, в который пересекается прямая с ребром многоугольника d = Scal(vecAB.X, vecAB.Y, n.X, n.Y); thit = (float)Scal(n.X, n.Y, x[j] - A.X, y[j] - A.Y) / d; // из скалярного произведения направляющего вектора отрезка и нормали ребра делаем вывод о том, //что найденный момент времени соответсвует точки входа или выхода. //так как нам нужно найти макс. из т. входа и мин. из т. выхода, меняем, если нужно, соответвующие значения //tin и tout if (d > 0 && thit > tin) { tin = thit; } if (d < 0 && thit < tout) { tout = thit; } } // так как мы прошлиись по всем ребрам многоугольника, кроме замыкающего, делаем это и для него, чтобы оно и ты не плакали) if (!clockwise) { n = Normalout(new Point(x[2] - x[i-1], y[2] - y[i-1])); } else { n = Normalin(new Point(x[2] - x[i-1], y[2] - y[i-1])); } d = Scal(vecAB.X, vecAB.Y, n.X, n.Y); thit = (float)Scal(n.X, n.Y, x[i-1] - A.X, y[i-1] - A.Y) / d; if (d > 0 && thit > tin) { tin = thit; } if (d < 0 && thit < tout) { tout = thit; } //если точка входа у нас появилась позже точки выхода, значит никакого отрезка нет. if (tin > tout) return; // если все нормально, то пересчитываем значения концов отрезка и рисуем его новым цветом if (tin < tout) { Point P1 = new Point(A.X + (int)((float)vecAB.X * tin), A.Y + (int)((float)vecAB.Y * tin)); Point P2 = new Point(A.X + (int)((float)vecAB.X * tout), A.Y + (int)((float)vecAB.Y * tout)); g.DrawLine(redBrush,P1.X, P1.Y, P2.X, P2.Y); } }