-
Notifications
You must be signed in to change notification settings - Fork 26
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
22 segment intersect #13
base: master
Are you sure you want to change the base?
Conversation
|
> Из классов Антон просил написать такую заготовку, чтобы человек не тратил время на написание несложных доп функций, только на алгоритм. Компараторы остальных классов и хэш-функция нужны в реализации, зачем их каждому переписывать |
Скорее всего не стоит полностью в ноутбуке писать реализацию классов |
Мы сегодня говорили с Антоном, он предложил (настоятельно порекомендовал) вынести все типовые классы со всех конспектов в отдельную либу. Он передаст более формальные требования через Артёма чуть позже. |
Да, про память я забыла рассказать, Антон напомнил уже, я добавлю. Точки пересечения отрезков тоже являются событиями, читай внимательнее. И в каркасе идет разбор всех трех возможных типов. Сравнение событий надо сделать немного иначе, это да. |
Покажи мне место в тексте своего алгоритма, где ты говоришь, что после того как мы нашли какое-либо пересечение мы добавили его в кучу событий. (Я этого просто совсем не увидел, я видел только слово добавляем в статус).
Каркас будет работать только в случае если в одной точки пересекаются не более 2 отрезков. Мне кажется задача твоего алгоритма совершенно иная. Кроме того, ты сама же приводишь в док-во оценки времени совершенно другой код алгоритм. Кроме того, зачем делить на случаи, если это вписывается в общую концепцую. Возможно, как пример, отдельной задачи было бы неплохо попросить написать 3 случая. А потом показать сам алгоритм, ведь он совсем не похож на эти 3 случая. Ну почти не похож. |
Их и не нужно переписывать. Просто убери их из нотебука в соседний файлик, и импортируй оттуда. Возможно, в строчке с импортом можно добавить комментарий, что этот класс поддерживает. Вряд ли кому то интересно смотреть на то, как реализован
Возможно, под разные задачи у этих классов будут немного разные компараторы. Например, мой для точки - нестандартный |
Это неправда, я писала этот алгоритм, такая реализация работает в случае, если в точке пересекаются/начинаются/заканчиваются больше двух отрезков, почитай внимательнее описание и порядок, в котором идут ивенты. Не понятно, какую общую концепцию ты имеешь ввиду. Случаев никаких нет, только три типа событий, который обрабатываются совершенно разными образами. |
В целом, если рассматривать конспект, как туториал для нешарящего (вроде меня), претензий нет: написано понятным языком, как следует разжёвано. (Годные замечания были даны до меня. Так что не знаю, к чему ещё можно придраться). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
В целом, по материалу претензий нет, потому что он просто аккуратно скопирован с Де Берга. В дополнение к тому, что уже было сказано другими ревьюверами, могу сказать, что вывод оценки абсолютной погрешности очень плохо поддаётся восприятию. Если мы здесь пишем простые и понятные туториалы, то можно его куда-нибудь спрятать или вообще убрать, чтобы он не отвлекал. Хотя возможно, что этого делать и не стоит.
Этот конспект на доработке после разговора с Антоном (еще неделю назад). Он будет очень сильно исправлен. Поэтому пока прошу не тратить время на его ревью. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Моя основная претензия - картинки. Во-первых, они шакальные. Вместо красивых и гладких x
и y
я вижу нечто, состоящее из ступенек. А во-вторых, они маленькие, вообще не понятно, что происходит. Если не крутить зум до 150-175%, то индексов у названий линий не видно совсем, да и при зуме они размытые (из-за п.1). Предлагаю всё перерисовать в векторе.
"source": [ | ||
"import matplotlib.pyplot as plt\n", | ||
"import numpy as np\n", | ||
"import bintrees\n", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
можно сделать from bintrees import RBTree
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"Перед тем, как приступить к изучению этого материала, настоятельно рекомендуется ознакомиться с конспектом про [афинное пространство](https://github.com/CT-18/cg/tree/5_affine_space), а именно с предикатом \"левый поворот\" и задачей о пересечении двух отрезков." |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Предполагается, что конспект всё-таки будут просматривать локально (а иначе как делать упражнения). Поэтому ссылки тоже нужно давать относительные и локальные, типа ../5_affine_space/blbla.ipynb
. Смержись с мастером, чтобы у тебя были уже принятые конспекты.
}, | ||
"source": [ | ||
"Теперь давайте подробнее разберем, что именно должно происходить при достижении заметающей прямой каждого типа события. Так как статус, как ранее было сказано, это упорядоченный набор пересекающих заметающую прямую отрезков в конкретный момент времени, то два отрезка являются соседними в статусе, если они являются ближайшими вдоль $l$.\n", | ||
"1. <img src=\"images/upper_endpoint.png\" style=\"float: right\"/> Если событие - начало отрезка, то это значит, что новый отрезок начал пересекать заметающую прямую. Поэтому он должен быть добавлен в статус и проверен на пересечение с двумя своими непосредственными соседями сверху и снизу, если они есть. Нас интересуют только пересечения правее заметающей прямой, так как если пересение находится левее, то оно уже было обнаружено (этот достаточно очевидный факт будет доказан чуть позже). Например, если отрезки $s_k$ и $s_l$ были соседними в статусе, и в какой-то момент между ними появился новый отрезок $s_i$, то мы должны проверить, не пересекается ли $s_i$ с $s_k$ и $s_i$ с $s_l$. Если мы находим точку пересечения левее $l$, то мы должны запомнить это событие (позже мы разберем подробнее, что это значит) и впоследствии обработать его. <br><br>\n", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Если мы находим точку пересечения левее ll , то мы должны запомнить это событие
может всё-таки правее? те, что левее, ведь уже запомнены
"source": [ | ||
"Теперь давайте обсудим, какие структуры данных нам понадобятся для реализации алгоритма. На самом деле их всего две: очередь событий $\\Omega$ и статус $T$. \n", | ||
"\n", | ||
"Как раньше было показано, алгоритм совершает какие-то действия только при достижении заметающей прямой какого-либо события. Следовательно, программно сэмитировать движение $l$ мы можем просто рассматривая события в том порядке, в котором прямая настигла бы их по ходу своего движения справа налево. Определим отношение \"меньше\" $\\prec$ для двух событий $p$ и $q$: будем считать, что событие \"левый конец\" меньше события \"пересечение\", а последнее меньше собятия \"правый конец\". Если события одного типа, то \n", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Странный значок "меньше" - с загнутыми "усами". Да и в этом предложении он не особо нужен.
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"Итак, мы придумали эффективный алгоритм, сильно сократив количество проверок (строгая оценка будет даначуть позже). Теперь нужно убедиться в том, что он по-прежнему находит все точки пересечений. Для начала уберем из рассмотрения перекрывающиеся (имеющие больше одной общей точки) и вертикальные отрезки, а также случай, когда больше двух отрезков пересекаются в одной точке. Эти три случая обрабатываются несложно, не выбиваясь из общего алгоритма. Однако для простоты рассуждений временно будем считать, что таких ситуаций быть не может, и покажем, что в таком предположении алгоритм работает корректно." |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
дана пробел чуть
"source": [ | ||
"Теперь давайте обсудим, какие структуры данных нам понадобятся для реализации алгоритма. На самом деле их всего две: очередь событий $\\Omega$ и статус $T$. \n", | ||
"\n", | ||
"Как раньше было показано, алгоритм совершает какие-то действия только при достижении заметающей прямой какого-либо события. Следовательно, программно сэмитировать движение $l$ мы можем просто рассматривая события в том порядке, в котором прямая настигла бы их по ходу своего движения справа налево. Определим отношение \"меньше\" $\\prec$ для двух событий $p$ и $q$: будем считать, что событие \"левый конец\" меньше события \"пересечение\", а последнее меньше собятия \"правый конец\". Если события одного типа, то \n", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
сымитировать, события. (а не собятия). Проверь спеллчеком.
"Отметим, что началом отрезка будем считать тот его конец, который меньше второго в лексикографическом порядке.\n", | ||
"\n", | ||
"Теперь вернемся к трем случаям, о которых мы временно забывали, и рассмотрим, как обрабатывается каждый из них:\n", | ||
"1. <img src=\"images/skew.png\" style=\"float: right\"/> Если в множестве $S$ есть вертикальный отрезок $s_i$, то в очереди $\\Omega$ у нас будут лежать два события с одинаковыми $x$-координатами, отвечающие за начало и конец $s_i$. Благодаря вышеопределенному порядку $\\prec$, сначала будет рассмотрено событие \"начало отрезка\", так как его $y$-координата меньше, и отрезок будет проверен на пересечение с соседями. Через какое-то время будет рассмотрено событие \"конец отрезка\" и будут проведены соответствующие проверки. То есть случай вертикального отрезка ничем не отличается от случая невертикального, и нам не нужно совершать никаких дополнительных действий для его обработки. Для лучшего понимания можно просто представить, что заметающая прямая не вертикальная, а наклонена от вертикальной оси под очень небольшим углом влево, как на рисунке справа (такой прием называется *skew*). Тогда очевидно, что нижний конец вертикального отрезка всегда будет достигаться первым. <br><br>\n", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Здесь "меньше с усами" тоже не особо нужно, из контекста понятно, о каком порядке речь.
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"Теперь давайте опишем алгоритм *in general*, пока не рассматривая обработку событий и другие детали: \n", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in general
В общем, в целом, не вдаваясь в детали - есть много русских синонимов. Я уже писал, что я думаю об употреблении английских терминов без необходимости
" plt.scatter(x1, y1, c = 'black', s = 30)\n", | ||
" plt.scatter(x2, y2, c = 'black', s = 30)\n", | ||
"\n", | ||
"print(\"Found intersections:\", find_intersections(segments))\n", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
учитывая, что здесь вызывается та самая handle_event_point(events, status, event) # declared below
, читатель в первый раз радостно получает NameError
в лицо.
В первый раз оно не работает, а когда эта функция уже будет, всем будет лень проматывать наверх. Поэтому код
print("Found intersections:", find_intersections(segments))
лучше перенести туда, где будет всё готово - непосредственно до или после ячейки с чекером на весь алгоритм.
"\n", | ||
"* [Ivan J. Balaban - An optimal algorithm for finding segments intersections](https://pdfs.semanticscholar.org/f523/84b8cc2b44f91c1e4048c7bc0021f6e01b01.pdf)\n", | ||
"\n", | ||
"Однако алгоритмы Бентли-Оттмана и Ивана Балабана сложны в реализации, поэтому на практике используются достаточно редко. Чаще всего эта задача решается с использованием [квадродеревьев](https://github.com/CT-18/cg/tree/1_skip_quadtree), так как такой подход имеет ту же асимптотику и при этом более прост в реализации." |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Также поправить ссылку на квадродеревья в соответствии с замечанием, которое я написал в начале конспекта.
Bentley Ottmann algorithm and related problems