Russian Qt Forum
Ноябрь 22, 2024, 12:27 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: Редактирование кривых  (Прочитано 9509 раз)
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« : Декабрь 21, 2017, 16:37 »

Добрый день

Давно заметил что любые манипуляции со временем воспринимаются очень трудно. Во всяком случае, меня капитально клинит - возможно это тот самый случай.

На первом скриншоте 2 графика X и Y от времени. Кривые имеют по 3 контрольных точки (рисуются если кривая выбрана). Каждая точка имеет синие ручки которые юзер может драгать (часто называют knot(s)) и таким образом управлять кривизной. У каждой контрольной точки 2 параметра

angle - угол наклона синего отрезка относительно горизонтали (времени)
weight - длина синего отрезка (чем больше тем мощнее кривизна)

Как пересчитать angle и weight  если юзер двигает синие точки на концах отрезка? Ну ясно, отняли от синей точки саму контрольную, получили вектор (половинка синего отрезка). И просто atan2 - получили angle, а weight = длине отрезка. Элементарщина.

А теперь мы рисуем путь (второй скриншот). Ну или "траекторию". И тут у нас есть кноты, мы их рисуем просто взяв высоты синих отрезков из первого скриншота, т.е.
Код:
x = sin(curve_x.point[1].angle) * curve_x.point[1].weight; 
y = sin(curve_y.point[1].angle) * curve_y.point[1].weight;
Да, но как же теперь пересчитать angle и weight если юзер двигает кноты Непонимающий Ведь времени по второй оси уже нет. Правду сказать, совсем растерялся солдат  Улыбающийся

Спасибо


« Последнее редактирование: Декабрь 21, 2017, 16:45 от Igors » Записан
ssoft
Программист
*****
Offline Offline

Сообщений: 584


Просмотр профиля
« Ответ #1 : Декабрь 22, 2017, 07:53 »

Зря вы связались с отдельными компонентами x и y, лучше выписывать зависимости в общем параметрическом виде прямо в точках пространства P = {x, y, ...} в виде зависимости P = P(t).
Тогда все будет выражаться не в углах и весах, а в полиномах, их производных и координатах узловых точек.
Полином для производной по t даст направление касательной в каждой точке кривой.

Как только будет понятно какой вид кривых Вы рисуете (Безье, NURBS, В-сплайны или др.), можно будет помочь с вычислением интересующих параметров.

Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #2 : Декабрь 22, 2017, 09:14 »

Тогда все будет выражаться не в углах и весах, а в полиномах, их производных и координатах узловых точек.
Полином для производной по t даст направление касательной в каждой точке кривой.
А здесь обратная задача - юзер "задает производную" (ну управляет углом наклона касательной). Задание углов и весов - изменить не могу, тем более это стандартная практика.

Как только будет понятно какой вид кривых Вы рисуете (Безье, NURBS, В-сплайны или др.), можно будет помочь с вычислением интересующих параметров.
Ладно, я тоже блесну эрудицией Улыбающийся Это F-Curve. Синие вектора вычисляются без затей (на основании угла и веса). Но интерполяция почему-то не обычной эрмитной матрицей, а полиномом Бернштейна (не знаю почему). Но никакого отношения к теме это не имеет  Улыбающийся

Может вообще решения нет, ну т.е. получить вектор из угла и веса - пожалуйста, но не наоборот. Уже засомневался.

Да, а где же научные работники, аспиранты и др? Ну как всегда.... заняты "сессией", гульками с собачкой и рисованием темплейтов - не дождесся  Плачущий
Записан
ViTech
Гипер активный житель
*****
Offline Offline

Сообщений: 858



Просмотр профиля
« Ответ #3 : Декабрь 22, 2017, 14:37 »

На самом деле концепция времени достаточно проста:



Путём нехитрых манипуляций по удалению лишних временных размерностей получаем следующую модель:



Далее избавляемся от времени вовсе:



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



Нет пространства - нет проблем. Задача решена, можем расходиться на выходные.

...

Или нет?

Сингулярность может породить альтернативную вселенную. Она даже может переплетается с нашей вселенной:



В этой вселенной человечество уже  сталкивалось с подобными задачами и успешно их решало. Доказательством этого могут послужить различные графические редакторы, которые работают с такими кривыми (за альтернативную вселенную мы точно про существование таких редакторов не знаем, но можем предполагать, что они таки там есть). Возможно то человечество умеет работать с проекциями. Одно можно утверждать совершенно точно: человечество в альтернативной вселенной намного ответственней, чем в нашей. Научные работники (как старшие, так и младшие) сидят на своих рабочих местах и корпят над решением глобальных проблем вселенной (как своей, так и других). Аспиранты им в этом усердно помогают: строят сечения и проекции многомерных пространств, и ломают голову, как из нулевого пространства развернуть хотя бы трёхмерное. Собачки понимают ответственность своей вселенной перед другими и сами себя выгуливают. Заодно приносят горячие обеды и бутерброды для перекуса своим хозяевам.

Есть ли в этой альтернативной вселенной Igors? Наверняка есть, эту задачу уже решил и теперь спешит к своему побратиму на помощь:



Igors в нашей вселенной остаётся только написать правила преобразования координат между пространствами различной размерности. Чтобы из нулевого пространства, порождённого сингулярностью чёрной дыры из альтернативной вселенной, "распаковать"  пространство достаточной размерности, в котором альтер Igors сможет показать решение поставленной задачи настоящему Igors.

Кстати. Если есть комната-библиотека, самое время туда заглянуть, может решение там уже есть:



Решение может быть в бинарном виде, но мыжпрограммисты!
Записан

Пока сам не сделаешь...
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4747



Просмотр профиля WWW
« Ответ #4 : Декабрь 22, 2017, 16:09 »

лучший пост года (а то и всего форума)
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #5 : Декабрь 23, 2017, 06:59 »

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

Воспользоваться "готовыми проверенными решениями" - а он, ленивец, не хочет гуглу открыть! Это всего лишь "удобное объяснение", в таких ситуациях шансов найти что-то стоящее немного - задачка "не так популярна".

И вообще, верна ли постановка? Ведь если нет - то любые поиски ничего не дадут. И еще вполне возможный вариант - решается простейшими школьными знаниями. Хорошо, зафиксируем weight и пусть он одинаков для X и Y, т.е. драг юзера меняет только angle(s). Опять все элементарно, углы вычисляются через asin или atan(2). Значит как минимум одно решение уже есть - сделать один драг для углов, другой (с зажатой клавишей - а шо делать) для весов. Это конечно не очень удобно, хотелось бы обойтись одним. Но возможно ли?

Все-таки странно что такие простейшие соображения не приходят в голову(?) людям занятыми глобальными проблемами и чьи знания в 100 раз больше. Ладно, (тактично) предположим они слишком увлечены своими делами  Улыбающийся
« Последнее редактирование: Декабрь 23, 2017, 07:04 от Igors » Записан
ssoft
Программист
*****
Offline Offline

Сообщений: 584


Просмотр профиля
« Ответ #6 : Декабрь 25, 2017, 08:49 »

А здесь обратная задача - юзер "задает производную" (ну управляет углом наклона касательной). Задание углов и весов - изменить не могу, тем более это стандартная практика.

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

В случае, если пользователь не передвигает узловые точки, а явно задает веса и углы в GUI, то нужно в аналитическом виде, исходя из параметрического вида кривой, выразить зависимость координат узловых через веса и углы.
Такой подход не очень то гибкий, особенно, если рассматривать больше 2-х измерений. Если с зависимостями между углами и координатами крайних узловых точек все достаточно ясно (тангенс угла - отношение разниц координат по X и Y), то с другими параметрами формулы могут оказаться намного сложнее.

И все-таки хотелось бы увидеть аналитическую форму кривой, чтобы хоть что-то помочь сделать). Без нее любые советы будут только общими словами.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #7 : Декабрь 25, 2017, 10:40 »

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

В случае, если пользователь не передвигает узловые точки, а явно задает веса и углы в GUI,
Да, здесь задача стоит именно так.

то нужно в аналитическом виде, исходя из параметрического вида кривой, выразить зависимость координат узловых через веса и углы.
Такой подход не очень то гибкий, особенно, если рассматривать больше 2-х измерений. Если с зависимостями между углами и координатами крайних узловых точек все достаточно ясно (тангенс угла - отношение разниц координат по X и Y), то с другими параметрами формулы могут оказаться намного сложнее.
Тут я Вас не понял. См аттач, обычный кубический Безье. Всего 4 точки, 2 из них лежат на самой кривой (контрольные/узловые), 2 других "управляющие"(точки на концах синего вектора). Юзер может двигать любую из них НО это вовсе не меняет другие автоматом. Напр изменение управляющей точки изменит только ее саму, изменение узловой - не изменит вектор узловая-управляющая (он просто будет сдвинут). Здесь узловые задаются углом + весом, т.е. по сути все то же.

И все-таки хотелось бы увидеть аналитическую форму кривой, чтобы хоть что-то помочь сделать). Без нее любые советы будут только общими словами.
А что здесь "аналитическая форма"? Как вычисляются начальные вектора:
Код:
point[i].angle = atan2(point[i + 1].value - point[i - 1].value, point[i + 1].time - point[i - 1].time);
Ну так это всего лишь default, дальше юзер меняет его как угодно.

Рисование кривой (значение от времени): находится сегмент кривой, для него есть 4 точки, первая и последняя - сами контрольные точки кривой, 2 другие - управляющие (синий вектор). Время приводится к относительному: t = 0 первая точка, t = 1 последняя. Дальше так (псевдокод)
Код
C++ (Qt)
double k[4];
Calculate(t, k);
return p0.value * k[0] + p1.value * k[1] + p2.value * k[2] + p3.value * k[3];
 
Собсно вся "аналитика" в ф-ции Calculate - как считать коэффициенты сплайна, углубляться в нее необязательно. И все хорошо, юзер может менять value для X, Y и Z на отрисованном пути, но каким angle+weight это соответствует для каждой компоненты? Ведь нужно предъявить не только путь, но и график каждой от времени.

Думал взять производную в начальной и конечной точках (это ведь и есть тангенс угла). Но тогда что делать с weight (вес один на всех)?

Та же проблема возникает и при другом раскладе. Для Безье сплайна нет "угол + вес", а есть просто "вектор". И опять хз как рисовать "компоненту от времени".

[off]ssoft, меня порадовал Ваш ответ. Уже думал типа "что толку постить? Ото увидело "atan2" и убежало саттера читать". Ан нет, есть нормальные люди![/off]
Записан
ssoft
Программист
*****
Offline Offline

Сообщений: 584


Просмотр профиля
« Ответ #8 : Декабрь 25, 2017, 15:16 »

Судя по описанию, в задаче используется кривая в виде NURBS https://en.wikipedia.org/wiki/Non-uniform_rational_B-spline, а никакой не Безье).
Сплайн 3-го порядка с весами для каждой из 4-х узловых точек. А угол в каждой точке кривой определяется годографом - производной, которая является сплайном 2-го порядка (навряд ли нужен в Вашей задаче).

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

Может следует ограничиться только интерактивным перемещением точек и явным заданием весов? Все сразу намного проще становится).

Цитировать
И опять хз как рисовать "компоненту от времени".

Здесь то все предельно просто. Параметрический вид - это и есть зависимость от "времени" t. Вместо точки нужно брать значение соответствующей компоненты.
К сожалению не могу много времени уделить Вашему вопросу, конец года)). Попробуйте разобраться пока сами. Я буду подключаться по мере возможности.
Записан
ssoft
Программист
*****
Offline Offline

Сообщений: 584


Просмотр профиля
« Ответ #9 : Декабрь 25, 2017, 15:33 »

Вот еще).
Параметрический вид Вашей кривой наверное такой.

Записан
ViTech
Гипер активный житель
*****
Offline Offline

Сообщений: 858



Просмотр профиля
« Ответ #10 : Декабрь 25, 2017, 15:49 »

Параметрический вид Вашей кривой наверное такой.

Это вряд ли. В формуле atan2 должон быть, иначе не страшно.
Записан

Пока сам не сделаешь...
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #11 : Декабрь 26, 2017, 10:52 »

Для этого представления веса для точек задаются только явно. Никакое перемещение точек на веса не влияет.
Для изменения углов не понятен способ использования - пользователь вводит значение угла для конечных точек? для всех точек? ожидается влияние на саму точку? на следующую? на предыдущую?
Для каждого сегмента кривой есть 4 точки. При изменении юзером любой из них все остальные остаются неизменны, меняется лишь кривизна сегмента (см примеры в аттаче). Я могу рисовать синие вектора как на параметрических графиках x(t), y(t), z(t), так и на пути в 3D окне (для простоты на плоскости XOZ, здесь принципиальной разницы 2D и 3D нет). Все рисуется корректно НО мне надо интерактивно редактировать и там и сям - а я не сообразю как это делать

Здесь то все предельно просто. Параметрический вид - это и есть зависимость от "времени" t. Вместо точки нужно брать значение соответствующей компоненты.
Для пути используется только значение компонент(ы). Для параметрического графика - значение и время t (то же самое выражается углом + длиной). Имея "только значение" (для Безье) я могу спокойно редактировать кривизну пути, но как отразить эти изменения в параметрическом графике? А имея угол+вес (для F-Curve) - как я должен их менять при редактировании пути?

Параметрический вид Вашей кривой наверное такой.
Да наверняка есть и такой, там сплайнов целая свора, и, конечно, не я их писал. Все эти длинные сопли формул я имею - ну и что с ними делать?
Записан
ssoft
Программист
*****
Offline Offline

Сообщений: 584


Просмотр профиля
« Ответ #12 : Декабрь 26, 2017, 16:13 »

Я так понял, что хотелось бы реализовать что-то подобное https://www.lynda.com/CINEMA-4D-tutorials/F-curve-manipulation/508543/550216-4.html

Судя по видео реализовано что-то типа:

* Произведена разбивка на интервалы времени интерполяции путем установки ключевых кадров. Причем разбивка по компонентам может быть различная.
* На каждом отрезке интервал времени нормируется в диапазон [0,1] (линейный закон, чтобы значение времени перевести в параметр сплайна).
* Для нормированного диапазона задается аналитический вид (формула с весами). По-умолчанию все веса равны 1.
* Движение точки ключевого кадра вверх/вниз влияет только на компоненту крайней ключевой точки. Движение вправо/влево - на время ключевого кадра.
* Движение точки вектора вверх/вниз влияет на компоненту внутренней ключевой точки. Движение вправо/влево - на вес внутренней ключевой точки (веса крайних точек не изменяются).

Если разбивка по компонентам независимая, то изменение одного графика никак не влияет на другой (я бы реализовал так).
Если компоненты образуют единый сплайн, то на графиках все точки имеют одинаковую координату по времени, а значения не редактируемых компонент корректируются, чтобы сохранялось w*X = const  (X - корректируемая компонента).

И вопрос - Вам нужно точно математически повторить функциональность или достаточно сделать похоже?
Можно открыть исходники blander какого-нибудь.
« Последнее редактирование: Декабрь 26, 2017, 17:05 от ssoft » Записан
ssoft
Программист
*****
Offline Offline

Сообщений: 584


Просмотр профиля
« Ответ #13 : Декабрь 26, 2017, 17:11 »

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

Остается только для нужного времени вычислить значение параметра, с помощью аналитического решения кубического уравнения.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #14 : Декабрь 27, 2017, 13:19 »

Я так понял, что хотелось бы реализовать что-то подобное
Берем выше - уже реализовано, шлифуем детали  Улыбающийся

* Произведена разбивка на интервалы времени интерполяции путем установки ключевых кадров. Причем разбивка по компонентам может быть различная.
* На каждом отрезке интервал времени нормируется в диапазон [0,1] (линейный закон, чтобы значение времени перевести в параметр сплайна).
* Для нормированного диапазона задается аналитический вид (формула с весами). По-умолчанию все веса равны 1.
* Движение точки ключевого кадра вверх/вниз влияет только на компоненту крайней ключевой точки. Движение вправо/влево - на время ключевого кадра.
* Движение точки вектора вверх/вниз влияет на компоненту внутренней ключевой точки. Движение вправо/влево - на вес внутренней ключевой точки (веса крайних точек не изменяются).
Да, все так, это делают все, изобрести что-то другое трудно, да и не нужно

Если разбивка по компонентам независимая, то изменение одного графика никак не влияет на другой (я бы реализовал так).
Трудно представить "зависимую", это как? Редактирование X(t) каким-то образом влияет на Y(t)? Таких задач у меня нет.

И вопрос - Вам нужно точно математически повторить функциональность или достаточно сделать похоже?
Не знаю что повторять. Если компонент 2 или 3, то мне нужно редактировать как кривизну пути, так и кривизну каждой компоненты от времени. Вот собсно и вся задача/проблема

Можно открыть исходники blander какого-нибудь.
Наверное "Blender'a". А Вы сами пробовали их открывать?  Улыбающийся Я да, раз 5 (не по этой теме конкретно). И всякий раз, после пары дней разборок - ну да, что-то новое узнал, но чего-то конкретного не получил ни разу.  Код задроченый капитально (даже для моих либеральных мерок). Дело не в том что я (якобы) "не хочу искать", а в том что неясно "что искать", и есть ли оно вообще.

Еще вариант, если компоненту "время" ввести в точку к пространственным координатам.
Тогда любой график - это двумерная проекция (или отдельный сплайн) одной пространственной координаты и времени.
Не понял. Юзер выбрал любую контрольную точку на пути. Разумеется известно какому времени она соответствует. И... что с того?

И не нужно никаких весовых коэффициентов, можно обойтись чистым Безье.
У меня нет свободы выбора "чем обойтись", есть 2 сплайна позволяющие редактировать путь (F-Curve и Безье), ф-ционал должен быть реализован для обоих
Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.174 секунд. Запросов: 22.