Как определить точку пересечения двух линий в GDI +?

Я использую .NET для создания приложения с поверхностью для рисования, аналогичной Visio. Пользовательский интерфейс соединяет два объекта на экране с помощью Graphics.DrawLine. Эта простая реализация отлично работает, но по мере того, как поверхность становится более сложной, мне нужен более надежный способ представления объектов. Одно из этих строгих требований - определение точки пересечения двух линий, чтобы я мог обозначить разделение с помощью какой-то графики.

Итак, мой вопрос: может ли кто-нибудь предложить способ сделать это? Возможно, с другой техникой (может быть, GraphViz) или алгоритмом?

Вы имеете в виду линии или сегменты? Я ищу для этого надежную реализацию на C#, и я слежу за этими вопросами по SO, и я заметил, что многие люди говорят «линии», когда имеют в виду «линейные сегменты». Первый - это гораздо более простой случай b / c на плоскости x, y, любые 2 непараллельные прямые гарантированно пересекают где-то, но большинство программных приложений используют линейные сегменты, а не прямые.

user316117 28.12.2015 21:44

У меня вопрос 7 лет назад, поэтому я понятия не имею.

Robert S. 29.12.2015 02:42
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
2
9 804
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

спросить др. математика

Однозначно информативнее, чем dr.evil, спасибо за ссылку!

vikingsteve 22.08.2013 17:23
Ответ принят как подходящий

Представление линий с помощью y = mx + c проблематично для компьютерной графики, потому что вертикальные линии требуют, чтобы m было бесконечным.

Кроме того, линии в компьютерной графике имеют начальную и конечную точки, в отличие от математических линий, которые имеют бесконечную протяженность. Обычно интересует пересечение линий только в том случае, если точка пересечения лежит на обоих рассматриваемых сегментах линии.

Если у вас есть два линейных сегмента, один от векторов x1 до x1 + v1 и один от векторов x2 до x2 + v2, тогда определите:

a = (v2.v2 v1.(x2-x1) - v1.v2 v2.(x2-x1)) / ((v1.v1)(v2.v2) - (v1.v2)^2)
b = (v1.v2 v1.(x2-x1) - v1.v1 v2.(x2-x1)) / ((v1.v1)(v2.v2) - (v1.v2)^2)

где для векторов p = (px, py), q = (qx, qy), p.q - скалярное произведение (px * qx + py * qy). Сначала проверьте, если (v1.v1) (v2.v2) = (v1.v2) ^ 2 - если да, то линии параллельны и не пересекаются.

Если они не параллельны, то если 0 <= a <= 1 и 0 <= b <= 1, точка пересечения лежит на обоих отрезках прямой и задается точкой

x1 + a * v1

Редактировать Вывод уравнений для a и b следующий. Точка пересечения удовлетворяет векторному уравнению

x1 + a*v1 = x2 + b*v2

Взяв скалярное произведение этого уравнения с v1 и с v2, мы получим два уравнения:

v1.v1*a - v2.v1*b = v1.(x2-x1)
v1.v2*a - v2.v2*b = v2.(x2-x1)

которые образуют два линейных уравнения для a и b. Решение этой системы (умножением первого уравнения на v2.v2, а второго на v1.v1 и вычитанием или иным образом) дает уравнения для a и b.

Если вы поверните систему отсчета, чтобы выровнять ее с первым сегментом линии (таким образом, начало координат теперь является началом первой линии, а вектор для первой линии простирается вдоль оси X), возникает вопрос: где находится вторая линия? ударьте по оси X в новой системе координат. На этот вопрос гораздо легче ответить. Если первая линия называется A и определяется A.O как начало линии, а «A.V» - вектор линии, то есть A.O + A.V является конечной точкой линии. Систему отсчета можно определить с помощью матрицы:

    | A.V.X   A.V.Y   A.O.X |
M = | A.V.Y  -A.V.X   A.O.Y |
    |   0       0       1   |

В однородных координатах эта матрица обеспечивает основу для системы отсчета, которая отображает линию A от 0 до 1 на оси X. Теперь мы можем определить преобразованную линию B как:

C.O = M*(B.O)
C.V = M*(B.O + B.V) - C.O

Где оператор * правильно определен для однородных координат (в данном случае проекция из 3-х пространств на 2-х пространственные). Теперь все, что осталось, это проверить и увидеть, где C попадает в ось X, что совпадает с решением стороны Y параметрического уравнения C для t:

C.O.Y + t * C.V.Y = 0
     -C.O.Y
t = --------
      C.V.Y

Если t находится в диапазоне от 0 до 1, то C попадает в ось X внутри линейного сегмента. Место, куда он попадает по оси X, задается стороной X параметрического уравнения для C:

x = C.O.X + t * C.V.X

Если x находится в диапазоне от 0 до 1, то пересечение находится на линейном сегменте A. Затем мы можем найти точку в исходной системе координат с помощью:

p = A.O + A.V * x

Вы, конечно, должны сначала проверить, имеет ли какой-либо линейный сегмент нулевую длину. Также, если C.V.Y = 0 у вас есть параллельные отрезки линии. Если C.V.X также равен нулю, у вас есть коллинеарные отрезки линии.

Другие вопросы по теме