Russian Qt Forum

Программирование => Алгоритмы => Тема начата: Igors от Сентябрь 28, 2015, 12:45



Название: Градиент (постановка)
Отправлено: Igors от Сентябрь 28, 2015, 12:45
Добрый день

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

Есть поверхность (для простоты плоскость) на которой лежит N брусков. Все это полигонные 3D объекты. Юзер хочет управлять ориентацией брусков, напр сделать так чтобы все они развернулись к центру (левая картинка = ожидаемый рез-т). Для этого он берет кисточку и рисует круг на плоскости (правая картинка). Дальше в его представлении умная (моя) программа должна сделать все автоматычно.

Детали (для взыскательных постановщиков). Ну цвет задается в вертексах. Бруски не меняют своей позиции но могут быть повернуты вокруг своих центров. Что еще? Не вижу, пожалуй все.

И вот я не вижу как сделать то что хочет юзер. Подскажите

Спасибо


Название: Re: Градиент (постановка)
Отправлено: Racheengel от Сентябрь 28, 2015, 15:10
А что это должно быть "физически"? Какое-нибудь магнитное поле?


Название: Re: Градиент (постановка)
Отправлено: Bepec от Сентябрь 28, 2015, 15:36
Задача поставлена неясно :D

Разворот брусков к центру. Центру чего?
Пользователь рисует круг на плоскости. Для чего?
Программа должна сделать автоматычно. Что сделать?

И каким макаром связан градиент и положение брусков? :D

Есть данные для начала, нет описания результата. Что в результате то получиться должно?


Название: Re: Градиент (постановка)
Отправлено: Igors от Сентябрь 28, 2015, 15:51
А что это должно быть "физически"? Какое-нибудь магнитное поле?
Ну а почему нет? Вполне удачная аналогия. Но она необязательна. Пользователь задает (рисует) градиент в и рассчитывает использовать его вектора/направления, а для чего - уже его дело. Ну вот напр для поворота/ориентации

Задача поставлена неясно :D

Разворот брусков к центру. Центру чего?
Пользователь рисует круг на плоскости. Для чего?
Программа должна сделать автоматычно. Что сделать?

И каким макаром связан градиент и положение брусков? :D

Есть данные для начала, нет описания результата. Что в результате то получиться должно?
Боже, ну почему при чтении Ваших ответов в моей памяти сразу оживают Бивис и Батхед?  :'( :'(
Ну как можно не сообразить чисто "по картинкам", даже не читая? Все, больше нет сил Вам отвечать  :'(


Название: Re: Градиент (постановка)
Отправлено: Bepec от Сентябрь 28, 2015, 16:21
Не могу по мутному описанию вообразить тот самый вариант, что подразумеваете в глубинах разума вы :)


Название: Re: Градиент (постановка)
Отправлено: Racheengel от Сентябрь 28, 2015, 16:27
А если пользователь нарисует 2 кружка, к какому центру должны развернуться бруски? К сильнейшему или к ближайшему?


Название: Re: Градиент (постановка)
Отправлено: Racheengel от Сентябрь 28, 2015, 18:38
В общем, если бруски не перемещаются по полю, а только вращаются, и вращение должно зависеть только от локального градиента (который находится в Bounding Box бруска, ну т.е. не бокс, а окружность, описывающая брусок), то я бы разбивал для каждого бруска его описывающую окружность на сегменты, скажем, с шагом в 1 градус и искал бы наиболее "сильный" градиент между началом и концом сегмента. Ну и соотв-но разворачивал бы брусок вдоль него. Но это только если в виду имеется именно это...


Название: Re: Градиент (постановка)
Отправлено: Igors от Сентябрь 29, 2015, 04:47
А если пользователь нарисует 2 кружка, к какому центру должны развернуться бруски? К сильнейшему или к ближайшему?
Я рассказал все что получил от пользователя. Да, задача еще не поставлена (см название топика).

Думается к ближайшему, существует градиент в точке, он локален. Там где градиент = 0 (черный цвет), он не должен применяться вообще (ну или "нечего применять"), там бруски остаются в исходном положении. Каких-то др разумных вариантов не видно, поэтому уточнять это у пользователя не нужно.  

В общем, если бруски не перемещаются по полю, а только вращаются, и вращение должно зависеть только от локального градиента (который находится в Bounding Box бруска, ну т.е. не бокс, а окружность, описывающая брусок), то я бы разбивал для каждого бруска его описывающую окружность на сегменты, скажем, с шагом в 1 градус и искал бы наиболее "сильный" градиент между началом и концом сегмента. Ну и соотв-но разворачивал бы брусок вдоль него. Но это только если в виду имеется именно это...
Плоскость - 3D модель, в данном случае состоит из квадратиков(полигонов), см сетку на правой картинке. Цвет задан в вертексах, это OpenGL его рисует плавно, на самом деле данные дискретны. Поэтому совершенно не понял причем здесь Bounding Box.


Название: Re: Градиент (постановка)
Отправлено: qate от Сентябрь 29, 2015, 08:38
из постановки задачи можно понять, что бруски надо развернуть одним из концов к центру круга, вращая вокруг их центра - тут вроде все ясно как делать
если брусок не попал в круг полностью - не ккрутить его
если попал частично - повернуть частично
пользователя заставить подписать это "тз" и делать )


Название: Re: Градиент (постановка)
Отправлено: Igors от Сентябрь 29, 2015, 09:03
из постановки задачи можно понять, что бруски надо развернуть одним из концов к центру круга, вращая вокруг их центра - тут вроде все ясно как делать
Да, с этим проблем нет

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

С абстракцией напряженка. Круг - значит только круг, брусок - только брусок :) Но все равно, хоть какие-то мысли есть - уже хорошо



Название: Re: Градиент (постановка)
Отправлено: Racheengel от Сентябрь 30, 2015, 10:56
Цитировать
Поэтому совершенно не понял причем здесь Bounding Box.

Ну я как рассуждал. Есть брусок, который может вращаться только вокруг своего центра. Значит, максимальная область "воздействия" - это описанная им окружность диаметром в длину бруска.

Пока не сказано иного, принимаем, что брусок разворачивается вдоль отрезка, который представляет собой максимальный градиент, скажем, "силы". Т.е. разность значений градиента в начале и конце отрезка - максимальна.

Поэтому мы можем разбить окружность на Х диаметров с шагом в N градусов и посчитать градиент каждого полученного отрезка. Затем выбрать максимальный и расположить брусок вдоль него.


Название: Re: Градиент (постановка)
Отправлено: Igors от Сентябрь 30, 2015, 11:27
Ну я как рассуждал. Есть брусок, который может вращаться только вокруг своего центра. Значит, максимальная область "воздействия" - это описанная им окружность диаметром в длину бруска.
На мой взгляд - не очень естественно. Не забить ли нам на размеры объекта и использовать только его центр (точку)? Ведь круг в примере намного больше бруска, если наоборот то по-любому смысла нет. Кобыле-реализации станет явно легче :) Но тогда возникает вопрос: а что считать "степенью воздействия"?


Название: Re: Градиент (постановка)
Отправлено: Racheengel от Сентябрь 30, 2015, 11:39
Ну а если мы возьмем только центр - как по одной точке градиент вычислять??

И как должен быть ориентирован брусок, если вдруг он попадет точно в центр зеленого круга?


Название: Re: Градиент (постановка)
Отправлено: Igors от Октябрь 01, 2015, 07:27
Ну а если мы возьмем только центр - как по одной точке градиент вычислять??

И как должен быть ориентирован брусок, если вдруг он попадет точно в центр зеленого круга?
Ну ясно, "задам вопрос, поддержу разговор, а там видно  будет" :) Это нормально, корректно - но мне это как-то неинтересно. Хотелось бы получить мешок идей (пусть спорных), а не растолковывать что такое градиент.

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


Название: Re: Градиент (постановка)
Отправлено: Racheengel от Октябрь 01, 2015, 09:18
Дык я вроде бы и предлагаю -ориентировать бруски по их локальным градиентам. Все равно других вариантов пока я не вижу.


Название: Re: Градиент (постановка)
Отправлено: Igors от Октябрь 01, 2015, 12:29
Дык я вроде бы и предлагаю -ориентировать бруски по их локальным градиентам. Все равно других вариантов пока я не вижу.
А как его посчитать, этот локальный градиент? Вот формулировка этой подзадачи:

Есть тр-к в вершинах которого заданы значения интенсивности (показано зеленым) v0, v1, v2. Есть точка внутри тр-ка, известны ее барицентрические координаты a, b, c. Интенсивность в точке интерполируется

v = v0 * a + v1 * b + v2 * c;

Как аналитически найти вектор интенсивности в точке? Численное решение хлопотно и неточно, учитывая что тр-к в 3D


Название: Re: Градиент (постановка)
Отправлено: Racheengel от Октябрь 03, 2015, 00:17
А почему нельзя отрендерить это все в битмап и использовать значения яркости в нужных точках? Зачем решать именно аналитически?

Градиент тогда считается просто, как разность интенсивности в начальной и конечной точках.


Название: Re: Градиент (постановка)
Отправлено: Igors от Октябрь 03, 2015, 07:48
А почему нельзя отрендерить это все в битмап и использовать значения яркости в нужных точках? Зачем решать именно аналитически?
Потому что даже скромная модель состоит из тысяч таких полигонов которые еще и повернуты в пр-ве как угодно

Градиент тогда считается просто, как разность интенсивности в начальной и конечной точках.
Начальную точку я нарисовал жирным кружком, это где находится центр поворачиваемого бруска. Но где "конечная"??? Ну и разность интенсивностей - это "скаляр" (т.е. одно число), а нужен "вектор" (3 числа)



Название: Re: Градиент (постановка)
Отправлено: Racheengel от Октябрь 03, 2015, 12:00
Стоп. Для определения градиентов нам достаточно интенсивности в картинке, нарисованной пользователем. Так?
Далее, вам просто надо определить bounding circle для бруска на плоскости картинки. Этот круг мы сегментируем, скажем, на 360 диаметров с поворотом в 1 градус. Далее для каждого отрезка-диаметра вычисляем разность интенсивности в его начале и конце. Это и есть градиент. Потом выбираем отрезок с максимальной разностью и это и будет вектор ориентации бруска.


Название: Re: Градиент (постановка)
Отправлено: Igors от Октябрь 03, 2015, 13:17
Стоп. Для определения градиентов нам достаточно интенсивности в картинке, нарисованной пользователем. Так?
Так

Далее, вам просто надо определить bounding circle для бруска на плоскости картинки. Этот круг мы сегментируем, скажем, на 360 диаметров с поворотом в 1 градус. Далее для каждого отрезка-диаметра вычисляем разность интенсивности в его начале и конце. Это и есть градиент. Потом выбираем отрезок с максимальной разностью и это и будет вектор ориентации бруска.
Опять Вы вернулись к неудачной (на мой взгляд) идее задействовать "весь брусок". А вместо него может быть напр стандартный teapot (чайник) или еще чего похлеще. И париться с "сегментацией" придется ой долго, да к тому же еще и неоднозначно.

[OFF]Тут обычно у слабонервных начинаются истерики. "Что это за задача??? Говорил "брусок", а теперь уже какой-то "чайник" приплел! Через жопу.. и.т.п.  :)[/OFF]

[OFF2]Уж 2 дня как сделал  :)[/OFF]


Название: Re: Градиент (постановка)
Отправлено: Racheengel от Октябрь 03, 2015, 15:59
Цитировать
А вместо него может быть напр стандартный teapot (чайник) или еще чего похлеще. И париться с "сегментацией" придется ой долго, да к тому же еще и неоднозначно

Так я не брусок сегментировать предлагал, а окружность вокруг него, внутри которой он будет повернут. Поэтому все равно, что за объект...

ЗЫ. И как сделал то?


Название: Re: Градиент (постановка)
Отправлено: Igors от Октябрь 04, 2015, 10:21
ЗЫ. И как сделал то?
Уперся в вычисление градиента (пост #15), но тоже не смог. Пара дней гугления ничего не дала. Тогда придумал так: считаем градиент в вертексах, а для точки интерполируем его так же как и цвет.

Расчет в вертексах оказался очень простым. См первый аттач, напр точку слева (или справа) от яркой. Для них вектор градиента будет направлен по ребру, соединяющему этот вертекс с ярким. Величина градиента прямо пропорциональна разнице яркостей и обратно пропорциональна длине ребра. Ну и общий градиент = сумме по ребрам. Напр в яркой точке он вероятно ноль (ребра компенсируют друг друга).

Потом разрулил с "полным" и "частичным" поворотом, там еще проще, ну и вот рез-т  на 2 аттаче. Тут один математик объяснил мне как же искать вектор что в посте #15 :)  Но поразмыслив я решил оставить "как есть". Оба способа имеют свои плюсы и минусы, но этот уже работает