Вопрос:
Как объединить эти алгоритмы?
Чтобы можно было масштабировать по мышке (или любой другой точке, например центру формы) и в тоже время передвигать вектор (той же мышкой)
Парюсь 2 дня получается не понять что =(, все время, куда то вектор улетает не туда =(
Получается только раздельно, либо нормально двигать, либо нормально масштабировать, а вместе никак 8(
Здравствуйте, z12, Вы писали:
z12>Вопрос: z12>Как объединить эти алгоритмы? z12>Чтобы можно было масштабировать по мышке (или любой другой точке, например центру формы) и в тоже время передвигать вектор (той же мышкой)
Странный код и не менее странный вопрос.
Слабо себе представляю одновременное двиганье вектора мышкой с изменением масштаба. Имеется ввиду двиганье одного из концов вектора что ли?
Ну так и задай вектор как две точки (Х1, Y1) и (Х2, Y2) и двигай одну из них, а потом уже из значений концов вектора получаешь его направление (X2-X1,Y2-Y1).
Или я чего-то не понял?
Здравствуйте, Dimonka, Вы писали:
D>Странный код и не менее странный вопрос. D>Слабо себе представляю одновременное двиганье вектора мышкой с изменением масштаба. Имеется ввиду двиганье одного из концов вектора что ли? D>Ну так и задай вектор как две точки (Х1, Y1) и (Х2, Y2) и двигай одну из них, а потом уже из значений концов вектора получаешь его направление (X2-X1,Y2-Y1). D>Или я чего-то не понял?
аа совсем забыл, что нормальные люди понимают под векторами =))
имелась ввиду “векторная графика”, т.е. линии, круги, квадраты...
Re: Масштабирование и сдвиг вектора
От:
Аноним
Дата:
13.09.07 16:37
Оценка:
Если в тупую, то сначала сделать mas[i].x1 := mas[i].x1 — mouse.X, а потом запустить 1 "алгоритм" с дельтами равными мышке.
А по хорошему почитать книжку про компьютерную графику.
Поскольку на плоскости практически любое преобразование задается матрицей 3x3 и вычисляется простым умножением вектора на эту матрицу.
А разные преоразования комбинируются элементарным перемножением матриц.
Здравствуйте, Аноним, Вы писали:
А>Если в тупую, то сначала сделать mas[i].x1 := mas[i].x1 — mouse.X, а потом запустить 1 "алгоритм" с дельтами равными мышке.
так работать не будет
А>А по хорошему почитать книжку про компьютерную графику. А>Поскольку на плоскости практически любое преобразование задается матрицей 3x3 и вычисляется простым умножением вектора на эту матрицу. А>А разные преоразования комбинируются элементарным перемножением матриц.
да наверно придется, проста с матрицами медленнее, вот и откладывал
Здравствуйте, z12, Вы писали:
z12>Есть два алгоритма:
z12>1)масштабирует (от начала координат) и сдвигает вектор
z12>Вопрос: z12>Как объединить эти алгоритмы? z12>Чтобы можно было масштабировать по мышке (или любой другой точке, например центру формы) и в тоже время передвигать вектор (той же мышкой)
А если попробовать написать функцию которая бы масштабировала твой вектор?
например:
void Zumm(int* mas, int x, int y){
int x1,y1,x2,y2;
x1 = Round((mas.x1 — x) * zuum + x);
y1 = Round((mas.y1 — y) * zuum + y);
x2 = Round((mas.x2 — x) * zuum + x);
y2 = Round((mas.y2 — y) * zuum + y);
}
в нее сотв-но загоняешь свои новые координаты (или мышки или начала координат).
Думаю прокатит.. это так, навскидку
Здравствуйте, vodolas, Вы писали:
V>А если попробовать написать функцию которая бы масштабировала твой вектор? V>в нее сотв-но загоняешь свои новые координаты (или мышки или начала координат). V>Думаю прокатит.. это так, навскидку
На вызов функции уходит какое-то время, учитывая то, что нужно обработать большое кол-во точек, задержка получается существенная.
Здравствуйте, z12, Вы писали:
z12>Здравствуйте, vodolas, Вы писали:
V>>А если попробовать написать функцию которая бы масштабировала твой вектор? V>>в нее сотв-но загоняешь свои новые координаты (или мышки или начала координат). V>>Думаю прокатит.. это так, навскидку
z12>На вызов функции уходит какое-то время, учитывая то, что нужно обработать большое кол-во точек, задержка получается существенная.
А мы когда-нить слышали о режиме INTERLACED. Т.е.
1. можно вызывать не каждую точку.
2. среднее разрешение экрана 1024*768. То есть если пользовательне играетется, то ресурсов среднего компа волне хватит
А если делать по вумному, то можно попробовать прикрутить DirectX или OpenGl — там, насколько я помню, подобного рода операции сделаны достаточно эффективно
Здравствуйте, z12, Вы писали:
z12>аа совсем забыл, что нормальные люди понимают под векторами =)) z12>имелась ввиду “векторная графика”, т.е. линии, круги, квадраты...
Ну так а какие проблемы с кругами и квадратами?
Их можно тоже представить векторами в виде их Bounding Box-ов. Что конкретно не получается масштабироват/перемещать?
Здравствуйте, vodolas, Вы писали:
V>А мы когда-нить слышали о режиме INTERLACED. Т.е.
первый раз слышу 8)
V>1. можно вызывать не каждую точку. V>2. среднее разрешение экрана 1024*768. То есть если пользовательне играетется, то ресурсов среднего компа волне хватит V>А если делать по вумному, то можно попробовать прикрутить DirectX или OpenGl — там, насколько я помню, подобного рода операции сделаны достаточно эффективно
У меня и с обычным GDI достаточно быстро перерисовывается, ну 140000 полилиний, с объщим кол-вом точек более 3000000, порядка секунды на пересчет и вывод всего на экран (ясно дело при масштабировании вектор фильтруется, и перерисовка фактически мгновенная).
Скорость пока устраивает, но начинаю думать на тему DirectX-а.
Проблема была в совмещении "масштабирования с крысы" и "сдвига".
z12>Матрица точки P: z12>[ x y 1 ] z12>Конечная матрица z12>Mt := P * Md * (T1 * Mz * T2)
z12>почему получается херня, где я напутал?
Линейную алгебру уже тыщу лет не вспоминал, но ИМХО:
1) конечная матрица преобразования не должна включать точку:
Mt := Md * (T1 * Mz * T2)
2) чтобы теперь ею пользоваться, надо представить исходные точки P(i) как _вертикальные_ матрицы и ставить их справа:
P'(i) := Mt * P(i)
Здравствуйте, a18, Вы писали:
a18>2) чтобы теперь ею пользоваться, надо представить исходные точки P(i) как _вертикальные_ матрицы и ставить их справа:
так и сделано (вроде):
Матрица точки P:
[ x y 1 ]
тобиш x, y это координаты из точки P
a18>1) конечная матрица преобразования не должна включать точку
под конечной матрицей я понимал не матрицу преобразования, матрицу, включающую точку, умноженную на матрицы преобразования
ведь разницы нет (вроде):
///
Mt = Md * (T1 * Mz * T2)
Mt = Mt * P
///и
Mt = P * Md * (T1 * Mz * T2)
///
а из Mt патом извлекаем координаты, кстати, а как их извлечь
z12> Матрица точки P: z12> [ x y 1 ] z12>тобиш x, y это координаты из точки P
Всё правильно, только матрица должна быть вертикальной, и ставить её нужно всегда справа.
z12>под конечной матрицей я понимал не матрицу преобразования, матрицу, включающую точку, умноженную на матрицы преобразования z12>ведь разницы нет (вроде): z12>/// z12> Mt = Md * (T1 * Mz * T2) z12> Mt = Mt * P z12>///и z12> Mt = P * Md * (T1 * Mz * T2) z12>///
В последнем случае P надо поставить с правой стороны (умножение матриц некоммутативно).
В итоге получим вектор P' = (Md * T1 * Mz * T2) * P
P' — это будет тоже вертикальная матрица, содержащая итоговые координаты: (x', y', 1)
Для простоты — конкретный пример для http://matri-tri-ca.narod.ru/
1) в левую матрицу A вбиваем матрицу переноса на 5 единиц по вертикали и горизонтали:
[ 1 0 5 ]
[ 0 1 5 ]
[ 0 0 1 ]
2) в правую матрицу вбиваем в левом столбце координаты нашей точки (3,6), остальные ячейки оставляем пустыми:
[ 3 ]
[ 6 ]
[ 1 ]
(последняя координата 1 — фиктивная, но она нужна)
3) нажимаем кнопку "A*B"
4) в результате получаем тоже вертикальную матрицу (вектор-столбец):
[ 8 ]
[ 11 ]
[ 1 ]
Т.е. преобразованные координаты точки — (8, 11).
Вместо матрицы A может быть любая матрица преобразования или их произведение:
Md, Md * T1, Md * T1 * Mz и т.п. (они все должны быть квадратные!)
Можно взять матрицы из Gdi+. Они вроде используют аппаратное ускорение. Во всяком случае я когда-то сравнивал рукописный класс матрицы и Gdiplus::Matrix, и рукописный проигрывал на порядки на операции трансформации точки.
Я так понимаю, вы используете GDI. Есть целочисленная версия Matrix::TransformPoints, которой можно подсунуть POINT-ы.
Оказалось все проще простого — при перетаскивании после отпускания картинки, из всех координат вычитается дельта
а в момент перерисовки вектор масштабируется от центра окна...