Форум программистов, компьютерный форум, киберфорум
Программирование мультимедиа
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.89/18: Рейтинг темы: голосов - 18, средняя оценка - 4.89
3 / 3 / 3
Регистрация: 10.03.2015
Сообщений: 62

Матрица поворота. Вращение прямоугольника вокруг точки пересечения диагоналей

17.12.2015, 19:44. Показов 3441. Ответов 11

Студворк — интернет-сервис помощи студентам
Нужно сделать вращение прямоугольника вокруг его центра. Написал метод, где в цикле каждая из координат сначала переводится в систему с началом в определённой точке, вращается с помощью матрицы поворота и переводится обратно в систему координат окна.
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// вращение будет происходить вокруг точки around
                for (int i = 0; i < points.Length; i++)
                {// перебираем точки многоугольника
                    PointF pt = points[i];
                    pt.X -= around.X;       // преобразование координат в систему координат с началом в точке around
                    pt.Y -= around.Y;
 
                    PointF temp = new PointF(
                        (float)(pt.X * cos_alpha + pt.Y * sin_alpha),
                        (float)(pt.Y * cos_alpha - pt.X * sin_alpha)
                        );      // применяем матрицу поворота
 
                    temp.X += around.X;     // обратное преобразование координат
                    temp.Y += around.Y;
 
                    points[i] = temp;
                }
Всё прекрасно работает и вращается так, как надо. Решил к этому добавить вращение вокруг центра прямоугольника. Для этого добавил свойство Center, где при каждом запросе вычисляется точка пересечения диагоналей прямоугольника (решая систему уравнений двух прямых, проходящих через 2 точки).
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public override PointF Center
{
    get
    {
        float       // приводим координаты прямоугольника в систему координат с началом в левом верхнем его углу
            x1 = points[0].X - points[0].X,     // верхняя левая вершина
            y1 = points[0].Y - points[0].Y,
 
            x2 = points[2].X - points[0].X,     // нижняя правая
            y2 = points[2].Y - points[0].Y,
 
            n1 = points[3].X - points[0].X,     // нижняя левая
            m1 = points[3].Y - points[0].Y,
 
            n2 = points[1].X - points[0].X,     // верхняя правая
            m2=points[1].Y - points[0].Y
        ;
        float X = 
            ((x1*y1+x1*y1)/(x2-x1)+(n1*m2+n1*m1)/(n2-n1)+m1-y1)/
            ((y2-y1)/(x2-x1)-(m2-m1)/(n2-n1))
            ;       // эту формулу я вывел из уравнения прямой, проходящей через две точки
        float Y = 
            ((X-x1)*(y2-y1))/
            (x2-x1)
            +y1;        // всё из того же уравнения получаем Y
        X += points[0].X;       // обратное преобразование координат
        Y += points[0].Y;
 
        return new PointF(X, Y);        // возвращаем точку пересечения диагоналей
    }
}
И работает оно правильно до тех пор, пока не повернёшь прямоугольник... При вращении точка начинает смещаться по одной из диагоналей в сторону первой вершины.
Исходник и exe файл Debug.rar
Может кто знает, в чём ошибка?
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
17.12.2015, 19:44
Ответы с готовыми решениями:

Как произвести вращение вокруг локальной оси, если система координат задана матрицей поворота?
Есть локальная координатная система, которая задана одной матрицей поворота 3x3. Пространство трёхмерное. Чтобы получить координаты точки...

Вращение прямоугольника вокруг точки
Помогите пожалуйста, прямоугольник вращается, Но, &quot;след&quot; за собой оставляет, не стирается предыдущее положение прямоугольника. Вроде должна...

Вращение прямоугольника вокруг точки
Здравствуйте, такой вопрос. Допустим, у меня есть TShape прямоугольник. Как можно сделать так, чтобы при нажатии стрелок &quot;Вверх&quot;...

11
 Аватар для snake32
3508 / 1691 / 236
Регистрация: 26.02.2009
Сообщений: 8,427
Записей в блоге: 6
18.12.2015, 16:23
Лучший ответ Сообщение было отмечено sereja322 как решение

Решение

Цитата Сообщение от sereja322 Посмотреть сообщение
где при каждом запросе вычисляется точка пересечения диагоналей прямоугольника (решая систему уравнений двух прямых, проходящих через 2 точки).
Не проще ли искать центр фигуры(прямоугольника) по ограничивающему прямоугольнику?:
Delphi
1
2
3
4
5
6
7
8
9
10
11
boundrect.min := vec2( MaxFloat, MaxFloat );
boundrect.max := vec2( -MaxFloat, -MaxFloat );
for i:=0 to Length( points )-1 do
begin
  if points[i].x < boundrect.min.x then boundrect.min.x := points[i].x;
  if points[i].x > boundrect.max.x then boundrect.max.x := points[i].x;
  if points[i].y < boundrect.min.y then boundrect.min.y := points[i].y;
  if points[i].y > boundrect.max.y then boundrect.max.y := points[i].y;
end;
 
center := ( boundrect.max - boundrect.min ) * 0.5 + boundrect.min;
1
64 / 17 / 3
Регистрация: 09.11.2013
Сообщений: 120
18.12.2015, 23:29
прикол ) задачу не решил,и под видом "че проще" еще 1 задачу задал ...типа сиди ломай голову студент,и свою реши и его неизвестный код реши)))
0
3 / 3 / 3
Регистрация: 10.03.2015
Сообщений: 62
18.12.2015, 23:34  [ТС]
Intronessia, не понял Вас..
0
64 / 17 / 3
Регистрация: 09.11.2013
Сообщений: 120
18.12.2015, 23:48
Intronessia, не понял Вас..
я через это проходил на форумах,лет 9 назад :

приходит новичок на форум-задает простой вопрос,и ему прогеры ошалелые задают навстречу 2 заумных встречных вопроса,то есть ставят в тупик еще на начале разговора...И сиди думай ))

я утром прочитал тему...подумал ...скачал файл-но решил что не помогу,1.не понял проблему.2.не понял задачу.3.включил программу-черный квадрат идет вверх,решил что как нибудь залезу в код - и сделаю координату ИГРЕК статическую ...и еще надо сделать автономное вращение квадрата - без кнопочки...и тогда сразу прогу включишь - и будет видно автоматом по вращению че не так...

а то кликать кнопку 40 раз замучаешься при тестировании...

я такие штуки делал...там были длиннющие формулы по расчету иксов и игреков ... из 2д формы рисовал 3д фигуры на бейсике вращалка 2007 г.

обьясни ка че не так ,какое задание было...Я вижу крутится прямоугольник ... ты код кинул а че не так не понял я
0
3 / 3 / 3
Регистрация: 10.03.2015
Сообщений: 62
19.12.2015, 00:59  [ТС]
Прикольно, свой opengl?) Сам исходник скинул на крайний случай, так как я его должным образом не комментировал ещё. Я сделал класс Rectangle, где прямоугольник представляется четырьмя точками и в этом классе метод void Rotate(double degree, PointF around), который вращает каждую точку прямоугольника вокруг точки around. Там применяется матрица поворота и всё прекрасно работает. Проблема в том, что неправильно вычисляется точка пересечения диагоналей прямоугольника при его повороте(точка начинает сдвигаться по первой диагонали в сторону первой вершины прямоугольника). Скорее всего что-то не то в формуле, которая используется во втором куске кода.

Добавлено через 31 секунду
snake32, т.е. по прямоугольнику описанному вокруг исходного? Их центр всегда будет совпадать?
0
 Аватар для snake32
3508 / 1691 / 236
Регистрация: 26.02.2009
Сообщений: 8,427
Записей в блоге: 6
19.12.2015, 01:23
Intronessia, говнокодер, я предложил альтернативный вариант вычисления центра фигуры, так как именно там по мнению автора темы ошибка.
А что предложил ты? Похвастался устаревшим opengl'ем?

Добавлено через 5 минут
Их центр всегда будет совпадать?
По-идеи, да.
0
3 / 3 / 3
Регистрация: 10.03.2015
Сообщений: 62
19.12.2015, 01:32  [ТС]
Спасибо, пойду посплю, а завтра подумаю на эту тему. Если центр будет всегда совпадать, то сделаю именно так, потому что в этом методе вычислений по меньше будет, следовательно скорость работы выше.
0
 Аватар для snake32
3508 / 1691 / 236
Регистрация: 26.02.2009
Сообщений: 8,427
Записей в блоге: 6
19.12.2015, 01:49
sereja322, быстрее будет если центр вычислить 1 раз и сохранить вместе с фигурой. А потом вращать её сколь угодно раз.

Добавлено через 3 минуты
Или хотя бы в процессе вращения не вычислять каждый раз
0
64 / 17 / 3
Регистрация: 09.11.2013
Сообщений: 120
19.12.2015, 01:53
ага,давай давай,свои пупер аргументы ))

боевой арсенал - 1.Назвать быдло кодером,2.Назвать программы устаревшими,
3.написать пару раз "ФЕЙСПАЛМ",4.задать навстречу пару тупых тупиковых вопросов,
5.и потом забанить оппонента ,если посмеет ответить

)) я же сказал я знаком с такой темой лет 9,уже знаю кто такие "игорь3д",снаке32,и какой то еххеле91 ...))

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

эти трое только в каждой теме вредят ,а список одобрений аж на 1400 )) годами висят тут бездельники по 5000 сообщений пишут

бомбанитесь все трое,докажите великую теорию про быдло кодера ))
0
3 / 3 / 3
Регистрация: 10.03.2015
Сообщений: 62
19.12.2015, 21:19  [ТС]
Размер фигуры тоже может меняться. Я думал сначала сделать вычисление каждый раз, потестить, а потом уже вызывать метод только тогда, когда меняется размер или координаты фигуры.

Добавлено через 1 минуту
Intronessia,
Цитата Сообщение от Intronessia Посмотреть сообщение
эти трое только в каждой теме вредят
Ну не знаю, мне он помог)

Добавлено через 19 часов 19 минут
Сделал так,
C#
1
2
3
4
5
6
7
8
9
public override PointF GetCenter()
{
    float left = Math.Min(Math.Min(points[0].X, points[1].X), Math.Min(points[2].X, points[3].X));
    float right = Math.Max(Math.Max(points[0].X, points[1].X), Math.Max(points[2].X, points[3].X));
    float top = Math.Min(Math.Min(points[0].Y, points[1].Y), Math.Min(points[2].Y, points[3].Y));
    float bottom = Math.Max(Math.Max(points[0].Y, points[1].Y), Math.Max(points[2].Y, points[3].Y));
 
    return new PointF((right + left) / 2, (bottom + top) / 2);
}
работает отлично, вызываю метод, когда меняется размер фигуры и в конструкторе. Спасибо!

Добавлено через 4 минуты
Как думаете, есть ли смысл сделать координаты вершин в системе координат от центра прямоугольника, т.е. центр(500,500), А(-15,-15), В(15,-15), С(15,15), D(-15,15). Или от некой другой точки. В данный момент они все от начала координат т.е. левого верхнего угла контейнера.
0
 Аватар для snake32
3508 / 1691 / 236
Регистрация: 26.02.2009
Сообщений: 8,427
Записей в блоге: 6
20.12.2015, 15:35
Цитата Сообщение от sereja322 Посмотреть сообщение
Как думаете, есть ли смысл сделать координаты вершин в системе координат от центра прямоугольника
Однозначного ответа, наверное, быть не может - всё зависит от конкретной задачи. Если сделаете от центра, то значит в отрисовке придётся каждый раз прибавлять каждый кадр к каждой вершине смещение. Хотя в OpenGL/D3D это обычное дело и выполняется на стороне GPU очень быстро, то при отрисовке силами CPU имхо кажется лишней работой, так как ему это даётся гораздо сложнее чем специализированному GPU(видеокарте).

Добавлено через 14 минут
Цитата Сообщение от Intronessia Посмотреть сообщение
забанить оппонента
Единственная хорошая идея от тебя! С момента регистрации никого не минусовал. Сейчас думаю самое время принять санкции к неадеквату.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
20.12.2015, 15:35
Помогаю со студенческими работами здесь

Расстояние от точки пересечения диагоналей до большей стороны прямоугольника
Перпендикуляр, опущенный из вершины угла А прямоугольника ABCD на не проходящий через эту вершину диагонали, делит ее в отношении 1 : 3...

Вращение объекта вокруг оси. Матрицы поворота.
добрый день, нужно сделать программу вращение куба вокруг оси z. Применил матрицу поворота к точкам и они далеко отошли От заданных. Не...

Процедура: рисование ромба по заданным координатам точки пересечения диагоналей и длинам диагоналей
Напишите процедуру рисования ромба по заданным координатам точки пересечения центров диагоналей ромба (x, y), и длинам двух...

Вращение прямоугольника вокруг оси
Программа должна вращать прямоугольник с заданными параметрами длины и ширины, вокруг оси. Общий алгоритм приведен ниже. Вопрос: как...

Вращение прямоугольника вокруг центра
Помогите,пожалуйста. Прямоугольник нарисовала без проблем)как вращать вокруг одной из вершин знаю, а как вокруг центра без понятия.помогите...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
Новые блоги и статьи
Установка Emscripten SDK (emsdk) и CMake на Windows для сборки C и C++ приложений в WebAssembly (Wasm)
8Observer8 30.01.2026
Чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. Система контроля версиями Git. . .
Подключение Box2D v3 к SDL3 для Android: физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
Загрузка PNG с альфа-каналом на SDL3 для Android: с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 28.01.2026
Содержание блога SDL3 имеет собственные средства для загрузки и отображения PNG-файлов с альфа-каналом и базовой работы с ними. В этой инструкции используется функция SDL_LoadPNG(), которая. . .
Загрузка PNG с альфа-каналом на SDL3 для Android: с помощью SDL3_image
8Observer8 27.01.2026
Содержание блога SDL3_image - это библиотека для загрузки и работы с изображениями. Эта пошаговая инструкция покажет, как загрузить и вывести на экран смартфона картинку с альфа-каналом, то есть с. . .
Влияние грибов на сукцессию
anaschu 26.01.2026
Бифуркационные изменения массы гриба происходят тогда, когда мы уменьшаем массу компоста в 10 раз, а скорость прироста биомассы уменьшаем в три раза. Скорость прироста биомассы может уменьшаться за. . .
Воспроизведение звукового файла с помощью SDL3_mixer при касании экрана Android
8Observer8 26.01.2026
Содержание блога SDL3_mixer - это библиотека я для воспроизведения аудио. В отличие от инструкции по добавлению текста код по проигрыванию звука уже содержится в шаблоне примера. Нужно только. . .
Установка Android SDK, NDK, JDK, CMake и т.д.
8Observer8 25.01.2026
Содержание блога Перейдите по ссылке: https:/ / developer. android. com/ studio и в самом низу страницы кликните по архиву "commandlinetools-win-xxxxxx_latest. zip" Извлеките архив и вы увидите. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru