コード例 #1
0
        /// <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);
        }
コード例 #2
0
        /// <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("Многоугольник не выпуклый.");
                }
            }
        }