/// <summary> /// Возвращает точку пересечения плоскости полигона и прямой, заданной аргументами. /// </summary> /// <param name="point1"> первая точка прямой, базовая. </param> /// <param name="point2"> вторая точка прямой, направляющая. </param> /// <param name="rayCoordinate"> отношение длины вектора от первой точки к точке пересечения и длины направляющего вектора с учетом направления. </param> /// <returns> Точка пересечения прямой и многоугольника, если они пересекаются. </returns> public DirectCoordinate?GetIntersection(DirectCoordinate point1, DirectCoordinate point2, out float rayCoordinate) { DirectCoordinate direction = point2 - point1; //направляющий вектор. //введение скалярного произведения нормали и напрвляющего вектора для проверки на параллельность: float denominator = normal.ScalarMultiplication(direction); if (denominator != 0) { //рассчет отношения длин направляющего вектора и вектора до точки персечения с учетом сонаправленности: // по теореме Фалеса искомое отношение равно отношению проекций расмматриваемых векторов на перпендикуляр к плоскости многоугольника, // а благодаря косинусам отношение проекций равно отношению скалярных произведений на нормаль направляющего вектора и вектора до любой вершины многоугольника. rayCoordinate = normal.ScalarMultiplication(vertexes[0] - point1) / denominator; //нахождение пересечения прямой и плоскости многоугольника: DirectCoordinate intersection = point1 + rayCoordinate * direction; //проверка на принадлежность точки пересечения многоугольнику: if (this.Contains(intersection)) { return(intersection); } } rayCoordinate = 0; return(null); }
/// <summary></summary> /// <param name="colorFill"> Отображаемая текстура полигона. </param> /// <param name="vertexes"> Набор координат вершин полигона. </param> public ConvexPolygon(Brush colorFill, DirectCoordinate[] vertexes) { //проверка, является ли массив точек полигоном: if (vertexes.Length < 3) { throw new Exception("Задан не многоугольник: вершин меньше трех."); } this.colorFill = colorFill; this.vertexes = vertexes; //нормаль к плоскости многоугольника задается как векторное произведение его двух первых сторон-векторов. normal = (vertexes[1] - vertexes[0]).VectorMultiplicate(vertexes[2] - vertexes[1]); //проверка на компланарность всех векторов: // копмланарность определяется относительно первых двух векторов - первые две точки не учитываются. // если все вектора, кроме последнего, компаланрны, то компалнарен и последний - последняя точка не учитывается. for (uint i = 2; i < vertexes.Length - 1; i++) { if (normal.ScalarMultiplication(vertexes[i] - vertexes[i + 1]) != 0) { throw new Exception("Многоугольник не плоский."); } } //проверка на выпуклость: // у выпуклого многоугольника все векторные произведения ближайших векторов-сторон направленны в одну сторону. // за шаблон берется нормаль, рассчитанную по двум первым сторонам. // направления векторов сравниваются через знак из скалярного произведения. for (uint i = 2; i < vertexes.Length; i++) { if (normal.ScalarMultiplication((vertexes[i] - vertexes[i - 1]).VectorMultiplicate(this[i + 1] - vertexes[i])) < 0) { throw new Exception("Многоугольник не выпуклый."); } } }