powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / Поворот фигуры
9 сообщений из 9, страница 1 из 1
Поворот фигуры
    #38315610
Damir_85
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Здравствуйте.
Если кто работал в графических редакторах, например, Corel Draw, то обратил внимание что при повороте фигуры меняются его габариты, т.е изменаются габаритная ширина и длина. Если кто не работал, то поясню. Возьмем например обычный прямоугольник. Если его повернуть на определенный угол, то габаритная рамка вокруг этого прямоугольника меняет свои длину и ширину. Я сделал небольшой макрос для Corel Draw который вращает фигуру в диапазоне от 0 до 360 градусов и ищет наименьшую ширину габаритной рамки. Если фигура сложная то тратится некоторое время на перерисовку фигуры. Можно ли вычислить угол, на который нужно повернуть фигуру , чтобы габаритная рамка имела наименьшую ширину? Вопрос конечно больше математический, но может кто сталкивался
...
Рейтинг: 0 / 0
Поворот фигуры
    #38315840
Damir_85,

это действительно вопрос математический, что-то из раздела дискретной математики и аналитической геометрии.

За оптимальность не поручусь, но, по ощущениям, можно сделать так:
- представляем фигуру в виде конечного множества точек (вершин);
- строим выпуклую оболочку ( convex hull ), например, методом Quickhull, и далее работаем с ней, а не с исходной фигурой;
- выбираем стартовую вершину и направление обхода (т. е. порядок перебора граней);
- берём стартовое значение минимума ширины габаритной рамки как заведомо большое число.
Далее цикл:
- осуществляем поворот и параллельный перенос выпуклой оболочки таким образом, чтобы текущая вершина попадала в начало координат (или хотя бы на ось ординат), следующая вершина лежала на оси ординат (т. е. текущая грань лежала на оси ординат);
- вычисляем максимальное удаление остальных вершин выпуклой оболочки от оси ординат (максимум X по модулю). Это будет ширина габаритной рамки для текущей грани. Если эта ширина меньше текущего минимума ширины габаритной рамки, запоминаем её как минимум, запоминаем угол поворота;
- переходим к следующей вершине (и грани) в выбранном направлении обхода.

Короче, лабораторная работа для студента 3-го курса специальности "Прикладная математика".
...
Рейтинг: 0 / 0
Поворот фигуры
    #38315974
Damir_85
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
13-й квартал,

Я в принципе так сделал (здесь код для VBA в Corel Draw и это пока набросок кода но он рабочий)
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
//Объявление переменных
Dim i, Ang As Integer
  Dim sh As Shape 
  Dim j, k As Double
Set sh = ActiveSelection  //Запоминаем в переменную выделенную фигуру которую будем вращать
  j = sh.SizeWidth  //Запоминаем в j начальную ширину габаритной рамки.
  For i = 1 To 360
    sh.Rotate 1 //Вращаем фигуру на 1 градус
    //Проверяем, если новая ширина габаритной рамки меньше старой ширины то запоминаем новое значение в j   
     If sh.SizeWidth < j Then 
      j = sh.SizeWidth
      Ang = i //Запоминаем новый градус
    End If
  Next i 
  sh.Rotate Ang //В итоге поворачиваем фигуру на тот градус, который дает наименьшую ширину габаритной рамки


В принципе код работает быстро, только когда сложные изображения бывает доходит до 10 сек и выше, поэтому я подумал нельзя ли сразу вычислить).
Еще что можно добавить в код, чтобы меньше тратить время на повороты и сравнения значений, это запоминать в переменной типа множество симметричные углы. Например при повороте на 45 градусов и на 135 градусов получается одна и та же ширина. Я думаю Ваш алгоритм будет полезен когда все функции поворота надо прописывать вручную. В Corel Draw просто уже автоматически встроены функции поворота и соотвественно сразу можно узнать через св-ва размеры габаритной рамки
...
Рейтинг: 0 / 0
Поворот фигуры
    #38316090
Фотография AndreTM
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Damir_85при повороте на 45 градусов и на 135 градусов получается одна и та же ширинаТогда вам достаточно проанализировать только половину окружности (до 179). Предположу также, что на осесимметричных фигурах - досточно анализировать только первую четверть (до 89).
...
Рейтинг: 0 / 0
Поворот фигуры
    #38316219
Damir_85
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AndreTM,

да, кстати, я пробовал этот вариант использовать только половину круга. Я эксперементировал с различными сложными фигурами и с некоторыми фигурами получилось вот что: если, например, используя диапазон (0..180) вращать против часовой стрелки , то находим определенное минимальное значение. Обозначим его A (ширина рамки). Если же вращать по часовой стрелки, то находим минимальное значение B, которое меньше A. Для других сложных фигур все может быть наоборот, так что приходится использовать от 1 до 360 градусов. А насчет симметрии я имею ввиду отсекать те симметричные углы которые не дали меньшего значения габарита чем текущий. А что касается осевой симметрии, то это надо получается как то определять что фигура имеет осевую сииметрию, т.к фигуры могуть быть какой угодно формы)
...
Рейтинг: 0 / 0
Поворот фигуры
    #38316594
_Дмит_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
авторна перерисовку фигуры.
для ускорения расчёта, надеюсь, отключаете перерисовку экрана ?

ps просто мысль - если считать самому, то в полярной системе координат решить будет проще. :)
...
Рейтинг: 0 / 0
Поворот фигуры
    #38318060
Damir_85
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Дмит_,

я вот незнаю есть ли в Corel Draw возможность отключения перерисовки, там просто все функции уже встроены и например при вызове метода Объект.Rotate [Градус] автоматически происходит перерисовка фигуры и ее поворот
да кстати насчет полярной не думал можно в принципе попробовать все сначала без фактического поворота просчитать каждый угол и размер , при этом не будет тратится время на перерисовку
...
Рейтинг: 0 / 0
Поворот фигуры
    #38318398
_Дмит_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Ни когда не работал с Corel Draw, попробуйте как в Excel'e

Application.ScreenUpdating = False
...
Ваш цикл по повороту и расчёту
...
Application.ScreenUpdating = True

и справка Вам в помощь. :)
...
Рейтинг: 0 / 0
Поворот фигуры
    #38318843
mdkChaos
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Как-то так :)
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
Sub Test()
Optimization = True
EventsEnabled = False

'Код программы

Optimization = False
EventsEnabled = True
End Sub
...
Рейтинг: 0 / 0
9 сообщений из 9, страница 1 из 1
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / Поворот фигуры
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]