Skip to content
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

Open
wants to merge 20 commits into
base: master
Choose a base branch
from
Open

22 segment intersect #13

wants to merge 20 commits into from

Conversation

akustareva
Copy link
Collaborator

Bentley Ottmann algorithm and related problems

@sandwwraith
Copy link
Collaborator

sandwwraith commented Jan 27, 2017

  1. Не нужно писать импорты в каждой ячейке, достаточно одного раза на весь ноутбук (например, в начале или при первом использовании)

  2. В упражнении, я считаю, всё-таки нужно оставить раскомментированным определение функции - чтобы пользователь знал её сигнатуру. Можешь просто сделать так, чтобы она сразу возвращала результат функции-ответа.

  3. Из классов Point, Segment и Event интерес может представлять лишь компаратор последнего, всё остальное лучше убрать с глаз долой. И если тернарник не влезает в одну строку, может, стоит написать его нормально?

  4. А что, доказательства у нас теперь ромбиками? :)

  5. Наверное, код проще дописывать, когда тебе дана пустая функция, а не когда надо писать где-то в середине вместо комментариев. Впрочем, это уже лично моё мнение. И я бы не отказался от реализации "по умолчанию" с ответами

  6. План в текущем виде немного бесполезен. Желательно, чтобы он был кликабелен, как нормальное содержание. Ну или убери его, особо ничего не потеряешь

@akustareva
Copy link
Collaborator Author

> Из классов Point, Segment и Event интерес может представлять лишь компаратор последнего

Антон просил написать такую заготовку, чтобы человек не тратил время на написание несложных доп функций, только на алгоритм. Компараторы остальных классов и хэш-функция нужны в реализации, зачем их каждому переписывать

@novikd
Copy link
Collaborator

novikd commented Jan 27, 2017

Скорее всего не стоит полностью в ноутбуке писать реализацию классов Type, Segment, Event. Лучше вынести в какой-то файл, а в ноутбуке просто описать интерфейс. Слишком много кода(где особо смысла нет) просто мешает

@akustareva
Copy link
Collaborator Author

akustareva commented Jan 27, 2017

Мы сегодня говорили с Антоном, он предложил (настоятельно порекомендовал) вынести все типовые классы со всех конспектов в отдельную либу. Он передаст более формальные требования через Артёма чуть позже.

@akustareva
Copy link
Collaborator Author

Да, про память я забыла рассказать, Антон напомнил уже, я добавлю.

Точки пересечения отрезков тоже являются событиями, читай внимательнее. И в каркасе идет разбор всех трех возможных типов. Сравнение событий надо сделать немного иначе, это да.

@krasnotsvetov
Copy link
Collaborator

krasnotsvetov commented Jan 27, 2017

Точки пересечения отрезков тоже являются событиями, читай внимательнее. И в каркасе идет разбор всех трех возможных типов. Сравнение событий надо сделать немного иначе, это да.

Покажи мне место в тексте своего алгоритма, где ты говоришь, что после того как мы нашли какое-либо пересечение мы добавили его в кучу событий. (Я этого просто совсем не увидел, я видел только слово добавляем в статус).

И в каркасе идет разбор всех трех возможных типов. Сравнение событий надо сделать немного иначе, это да.

Каркас будет работать только в случае если в одной точки пересекаются не более 2 отрезков. Мне кажется задача твоего алгоритма совершенно иная. Кроме того, ты сама же приводишь в док-во оценки времени совершенно другой код алгоритм. Кроме того, зачем делить на случаи, если это вписывается в общую концепцую.

Возможно, как пример, отдельной задачи было бы неплохо попросить написать 3 случая. А потом показать сам алгоритм, ведь он совсем не похож на эти 3 случая. Ну почти не похож.

@sandwwraith
Copy link
Collaborator

Антон просил написать такую заготовку, чтобы человек не тратил время на написание несложных доп функций, только на алгоритм. Компараторы остальных классов и хэш-функция нужны в реализации, зачем их каждому переписывать

Их и не нужно переписывать. Просто убери их из нотебука в соседний файлик, и импортируй оттуда. Возможно, в строчке с импортом можно добавить комментарий, что этот класс поддерживает. Вряд ли кому то интересно смотреть на то, как реализован __add__ и прочее.

(настоятельно порекомендовал) вынести все типовые классы со всех конспектов в отдельную либу.

Возможно, под разные задачи у этих классов будут немного разные компараторы. Например, мой для точки - нестандартный

@akustareva
Copy link
Collaborator Author

Каркас будет работать только в случае если в одной точки пересекаются не более 2 отрезков.

Это неправда, я писала этот алгоритм, такая реализация работает в случае, если в точке пересекаются/начинаются/заканчиваются больше двух отрезков, почитай внимательнее описание и порядок, в котором идут ивенты. Не понятно, какую общую концепцию ты имеешь ввиду. Случаев никаких нет, только три типа событий, который обрабатываются совершенно разными образами.

@profick
Copy link

profick commented Jan 31, 2017

  1. (Пока мы ещё не запилили общую библиотеку для типовых классов) Возможно так выглядит нагляднее, но, тем не менее, я считаю, что импортировать класс Point из samples не нужно, так как он уже был создан ранее, в примере про "левый поворот". Лично у меня возникло подозрение, что "может быть в samples реализация как-то отличается и надо бы посмотреть этот файл".

  2. "О вкусах не спорят", но всё же стоит убрать "\large" из формулы точки пересечения двух отрезков, так как формулы разных размеров смотрятся не очень вкусно. Либо сделать левую часть последнего равенства также "\large". (Понятно, что изначально хотелось выделить итоговую формулу).

  3. Исправить очепятки:
    переберающий -> перебирающий
    персечений -> пересечений
    дейтвия -> действия
    алгорим -> алгоритм

В целом, если рассматривать конспект, как туториал для нешарящего (вроде меня), претензий нет: написано понятным языком, как следует разжёвано.
Упражнения неплохие. В принципе, после их выполнения более-менее осознаешь, как это всё работает.

(Годные замечания были даны до меня. Так что не знаю, к чему ещё можно придраться).

Copy link
Member

@Owntage Owntage left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

В целом, по материалу претензий нет, потому что он просто аккуратно скопирован с Де Берга. В дополнение к тому, что уже было сказано другими ревьюверами, могу сказать, что вывод оценки абсолютной погрешности очень плохо поддаётся восприятию. Если мы здесь пишем простые и понятные туториалы, то можно его куда-нибудь спрятать или вообще убрать, чтобы он не отвлекал. Хотя возможно, что этого делать и не стоит.

@akustareva
Copy link
Collaborator Author

Этот конспект на доработке после разговора с Антоном (еще неделю назад). Он будет очень сильно исправлен. Поэтому пока прошу не тратить время на его ревью.

@akustareva akustareva requested a review from Owntage January 31, 2017 17:01
@sandwwraith sandwwraith self-requested a review March 14, 2017 00:53
Copy link
Collaborator

@sandwwraith sandwwraith left a 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",
Copy link
Collaborator

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), а именно с предикатом \"левый поворот\" и задачей о пересечении двух отрезков."
Copy link
Collaborator

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",
Copy link
Collaborator

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",
Copy link
Collaborator

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": [
"Итак, мы придумали эффективный алгоритм, сильно сократив количество проверок (строгая оценка будет даначуть позже). Теперь нужно убедиться в том, что он по-прежнему находит все точки пересечений. Для начала уберем из рассмотрения перекрывающиеся (имеющие больше одной общей точки) и вертикальные отрезки, а также случай, когда больше двух отрезков пересекаются в одной точке. Эти три случая обрабатываются несложно, не выбиваясь из общего алгоритма. Однако для простоты рассуждений временно будем считать, что таких ситуаций быть не может, и покажем, что в таком предположении алгоритм работает корректно."
Copy link
Collaborator

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",
Copy link
Collaborator

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",
Copy link
Collaborator

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",
Copy link
Collaborator

@sandwwraith sandwwraith Mar 15, 2017

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",
Copy link
Collaborator

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 в лицо.

image

В первый раз оно не работает, а когда эта функция уже будет, всем будет лень проматывать наверх. Поэтому код

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), так как такой подход имеет ту же асимптотику и при этом более прост в реализации."
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Также поправить ссылку на квадродеревья в соответствии с замечанием, которое я написал в начале конспекта.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants