Масштабирование и сдвиг вектора
От: z12  
Дата: 13.09.07 15:03
Оценка:
Есть два алгоритма:

1)масштабирует (от начала координат) и сдвигает вектор

for i := 0 to length(mas) - 1 do begin
   x1 := Round(mas[i].x1 * zuum + dX);
   y1 := Round(mas[i].y1 * zuum + dY);
   x2 := Round(mas[i].x2 * zuum + dX);
   y2 := Round(mas[i].y2 * zuum + dY);
   bmp.Canvas.Rectangle(x1, y1, x2, y2);
end;


2)масштабирует(по мышке)
for i := 0 to length(mas) - 1 do begin
   x1 := Round((mas[i].x1 - mouse.X) * zuum + mouse.X);
   y1 := Round((mas[i].y1 - mouse.Y) * zuum + mouse.Y);
   x2 := Round((mas[i].x2 - mouse.X) * zuum + mouse.X);
   y2 := Round((mas[i].y2 - mouse.Y) * zuum + mouse.Y);
   bmp.Canvas.Rectangle(x1, y1, x2, y2);
end;


Вопрос:
Как объединить эти алгоритмы?
Чтобы можно было масштабировать по мышке (или любой другой точке, например центру формы) и в тоже время передвигать вектор (той же мышкой)

Парюсь 2 дня получается не понять что =(, все время, куда то вектор улетает не туда =(
Получается только раздельно, либо нормально двигать, либо нормально масштабировать, а вместе никак 8(
Re: Масштабирование и сдвиг вектора
От: Dimonka Верблюд  
Дата: 13.09.07 15:58
Оценка:
Здравствуйте, z12, Вы писали:

z12>Вопрос:

z12>Как объединить эти алгоритмы?
z12>Чтобы можно было масштабировать по мышке (или любой другой точке, например центру формы) и в тоже время передвигать вектор (той же мышкой)

Странный код и не менее странный вопрос.
Слабо себе представляю одновременное двиганье вектора мышкой с изменением масштаба. Имеется ввиду двиганье одного из концов вектора что ли?

Ну так и задай вектор как две точки (Х1, Y1) и (Х2, Y2) и двигай одну из них, а потом уже из значений концов вектора получаешь его направление (X2-X1,Y2-Y1).
Или я чего-то не понял?
Re[2]: Масштабирование и сдвиг вектора
От: z12  
Дата: 13.09.07 16:03
Оценка:
Здравствуйте, 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 и вычисляется простым умножением вектора на эту матрицу.
А разные преоразования комбинируются элементарным перемножением матриц.
Re[2]: Масштабирование и сдвиг вектора
От: z12  
Дата: 13.09.07 17:33
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Если в тупую, то сначала сделать mas[i].x1 := mas[i].x1 — mouse.X, а потом запустить 1 "алгоритм" с дельтами равными мышке.


так работать не будет

А>А по хорошему почитать книжку про компьютерную графику.

А>Поскольку на плоскости практически любое преобразование задается матрицей 3x3 и вычисляется простым умножением вектора на эту матрицу.
А>А разные преоразования комбинируются элементарным перемножением матриц.

да наверно придется, проста с матрицами медленнее, вот и откладывал
Re: Масштабирование и сдвиг вектора
От: vodolas  
Дата: 14.09.07 06:43
Оценка:
Здравствуйте, 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);
}

в нее сотв-но загоняешь свои новые координаты (или мышки или начала координат).
Думаю прокатит.. это так, навскидку
... << RSDN@Home 1.2.0 alpha rev. 745>>
Re[2]: Масштабирование и сдвиг вектора
От: z12  
Дата: 14.09.07 07:42
Оценка:
Здравствуйте, vodolas, Вы писали:

V>А если попробовать написать функцию которая бы масштабировала твой вектор?

V>в нее сотв-но загоняешь свои новые координаты (или мышки или начала координат).
V>Думаю прокатит.. это так, навскидку

На вызов функции уходит какое-то время, учитывая то, что нужно обработать большое кол-во точек, задержка получается существенная.
Re[3]: Масштабирование и сдвиг вектора
От: vodolas  
Дата: 14.09.07 10:15
Оценка:
Здравствуйте, z12, Вы писали:

z12>Здравствуйте, vodolas, Вы писали:


V>>А если попробовать написать функцию которая бы масштабировала твой вектор?

V>>в нее сотв-но загоняешь свои новые координаты (или мышки или начала координат).
V>>Думаю прокатит.. это так, навскидку

z12>На вызов функции уходит какое-то время, учитывая то, что нужно обработать большое кол-во точек, задержка получается существенная.

А мы когда-нить слышали о режиме INTERLACED. Т.е.
1. можно вызывать не каждую точку.
2. среднее разрешение экрана 1024*768. То есть если пользовательне играетется, то ресурсов среднего компа волне хватит

А если делать по вумному, то можно попробовать прикрутить DirectX или OpenGl — там, насколько я помню, подобного рода операции сделаны достаточно эффективно
Re[3]: Масштабирование и сдвиг вектора
От: Dimonka Верблюд  
Дата: 14.09.07 11:46
Оценка:
Здравствуйте, z12, Вы писали:

z12>аа совсем забыл, что нормальные люди понимают под векторами =))

z12>имелась ввиду “векторная графика”, т.е. линии, круги, квадраты...

Ну так а какие проблемы с кругами и квадратами?
Их можно тоже представить векторами в виде их Bounding Box-ов. Что конкретно не получается масштабироват/перемещать?
Re[4]: Масштабирование и сдвиг вектора
От: z12  
Дата: 14.09.07 15:57
Оценка:
Здравствуйте, vodolas, Вы писали:

V>А мы когда-нить слышали о режиме INTERLACED. Т.е.

первый раз слышу 8)

V>1. можно вызывать не каждую точку.

V>2. среднее разрешение экрана 1024*768. То есть если пользовательне играетется, то ресурсов среднего компа волне хватит
V>А если делать по вумному, то можно попробовать прикрутить DirectX или OpenGl — там, насколько я помню, подобного рода операции сделаны достаточно эффективно

У меня и с обычным GDI достаточно быстро перерисовывается, ну 140000 полилиний, с объщим кол-вом точек более 3000000, порядка секунды на пересчет и вывод всего на экран (ясно дело при масштабировании вектор фильтруется, и перерисовка фактически мгновенная).

Скорость пока устраивает, но начинаю думать на тему DirectX-а.
Проблема была в совмещении "масштабирования с крысы" и "сдвига".
Re: Масштабирование и сдвиг вектора
От: z12  
Дата: 17.10.07 11:51
Оценка:
Таки тема опять поднялась.
Решил, не парится, и сделать как все через матрицы.
Тема всю жизнь была простая, но от чего-то нифига не сделать.

Почитал книжки и сделал следующее:
Матрица переноса Md:
[ 1 0 dx ]
[ 0 1 dy ]
[ 0 0 1 ]
Матрица переноса в начало координат T1:
[ 1 0 0 ]
[ 0 1 0 ]
[ -x0 -y0 1 ]
Матрица переноса начала координат в (x0, y0) T2:
[ 1 0 0 ]
[ 0 1 0 ]
[ x0 y0 1 ]
Матрица масштабирования Mz:
[ zx 0 0 ]
[ 0 zy 0 ]
[ 0 0 1 ]
Матрица точки P:
[ x y 1 ]
Конечная матрица
Mt := P * Md * (T1 * Mz * T2)

почему получается херня, где я напутал?
Re[2]: Масштабирование и сдвиг вектора
От: a18 Россия  
Дата: 18.10.07 07:28
Оценка:
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)

Потренироваться можно тут:
http://matri-tri-ca.narod.ru/
А тут — теория по пространственным преобразованиям:
http://en.wikipedia.org/wiki/Transformation_matrix
Re[3]: Масштабирование и сдвиг вектора
От: z12  
Дата: 18.10.07 09:14
Оценка:
Здравствуйте, 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 патом извлекаем координаты, кстати, а как их извлечь
Re[4]: Масштабирование и сдвиг вектора
От: a18 Россия  
Дата: 18.10.07 14:19
Оценка:
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 и т.п. (они все должны быть квадратные!)
Re[4]: Масштабирование и сдвиг вектора
От: SuhanovSergey  
Дата: 19.10.07 11:12
Оценка:
Можно взять матрицы из Gdi+. Они вроде используют аппаратное ускорение. Во всяком случае я когда-то сравнивал рукописный класс матрицы и Gdiplus::Matrix, и рукописный проигрывал на порядки на операции трансформации точки.
Я так понимаю, вы используете GDI. Есть целочисленная версия Matrix::TransformPoints, которой можно подсунуть POINT-ы.
Re[5]: Масштабирование и сдвиг вектора
От: z12  
Дата: 29.10.07 08:36
Оценка:
Здравствуйте, a18

Оказалось все проще простого — при перетаскивании после отпускания картинки, из всех координат вычитается дельта
а в момент перерисовки вектор масштабируется от центра окна...
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.