Форум программистов, компьютерный форум, киберфорум
Алгоритмы
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.81/21: Рейтинг темы: голосов - 21, средняя оценка - 4.81
1 / 1 / 0
Регистрация: 19.01.2014
Сообщений: 20

Подобрать коэффициент масштабирования

04.01.2015, 20:36. Показов 4609. Ответов 11
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Задача: вывести на экран точки (вершины графа) по их координатам. Координаты заданы относительно (т.е. без привязки к какому-нибудь конкретному монитору) и имеют разброс:
X: 0.000 .. 1000.000
Y: 0.000 .. 1000.000

Например, пара координат может иметь следующий вид:
30.000, 40.000
Или:
0.250, 0.900

Соответственно, если выводить как есть, картинка будет ненаглядной: либо точки скучены, либо не все помещаются на экран (вывожу на канву компонента Image (1000 на 700 пикселей) в RAD Studio).

Как сделать, чтобы граф размещался по центру Image в максимальном масштабе, но при этом не вылезал за пределы Image?

Спасибо.
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
04.01.2015, 20:36
Ответы с готовыми решениями:

Алгоритм масштабирования изображения
Дорогие форумчане помогите придумать алгоритм масштабирования изображения. Чтобы описание алгоритма было понятным программисту, т.е. Четки...

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

Алгоритм масштабирования графика по оси OY
Доброго времени суток, есть массив нормированных данных от 0 до 1. Необходимо сделать масштабирование по оси OY. Масштабирование должно...

11
294 / 265 / 48
Регистрация: 09.04.2013
Сообщений: 1,038
05.01.2015, 12:31
Сначала находишь минимумы и максимумы по вертикали и горизонтали.
Если хочешь чтобы при масштабировании сохранялись пропорции - смотришь на отношение получившихся сторон (Xmax-Xmin)/(Ymax-Ymin), если отношение больше чем отношение сторон канваса - значить далее мы будем работать только с шириной, если наоборот меньше - то только с высотой (т.е. будем ориентироваться на бОльшую сторону, иначе она не влезет на канвас). Если сохранение пропорций несущественно - работаем и с высотой и с шириной независимо.
Пусть мы выбрали сторону по ширине. Пусть Х - координата точки, ранее нашли Мах и Мin. Строим отображение интервала (Min;Max) на интервал (0;Width), где Width - ширина канваса
X -> (Min;Max)
(X-Min) -> (0;Max-Min)
(X-Min)/(Max-Min) -> (0;1)
Width*(X-Min)/(Max-Min) -> (0;Width)
При сохранении пропорций не забыть сдвинуть точки картинки по Y = (Y-Ymin), потом применить ту же формулу - Width*Y/(Max-Min), после этого можно даже отцентрировать, но тут с формулой я не разобрался.

Естественно, если у нас будет большая сторона по высоте, то надо поступать аналогично.

Надеюсь я ни где не ошибся.

Добавлено через 12 минут
Для центрирования, скорее всего, нужно сдвинуть на ( Height - Width * (Ymax-Ymin)/(Xmax-Xmin) )/2, но возможно это неправильная формула.
1
1 / 1 / 0
Регистрация: 19.01.2014
Сообщений: 20
05.01.2015, 19:42  [ТС]
Что означает -> в вашей логике?
Про Xmax, Xmin, Ymax, Ymin уже дошло, они используются.
На данный момент граф отцентрирован на Image1, осталось его отмасштабировать,

Добавлено через 5 часов 26 минут
wingblack, ваши формулы понятны, но неясна логика их применения. Вы хотите сказать, что Width*(X-Min)/(Max-Min) - это и есть коэффициент масштабирования?
0
1968 / 824 / 115
Регистрация: 01.10.2012
Сообщений: 4,850
Записей в блоге: 2
07.01.2015, 10:10
Пусть есть значения x и y что надо нарисовать, т.е. перевести в пиксельные координаты (x_pixel, y_pixel). Тогда (пропорции сохраняем)

x_pixel = (x - x_min) * scale;
y_pixel = (y_min - y) * scale; // т.к. на экране y направлен вниз

C x_min и у_min проблем нет, вычисляем scale по x и y на основании размеров окна screen_x и screen_y

scale_x = screen_x / (x_max - x_min);
scale_y = screen_y / (y_max - y_min);

И берем меньший

scale = min(scale_x, scale_y);
1
294 / 265 / 48
Регистрация: 09.04.2013
Сообщений: 1,038
07.01.2015, 16:08
С помощью "->" я указываю диапазон значений, в котором будут точки при использовании текущей формулы.
Согласен, не очень удачный выбор.
0
1 / 1 / 0
Регистрация: 19.01.2014
Сообщений: 20
09.01.2015, 20:15  [ТС]
Igor3D, если выводить вершину по вашей формуле в координаты (scale*исходный_x, scale*исходный_y), то часть вершин (а иногда - все) вылезает за пределы области вывода.
А если в
Цитата Сообщение от Igor3D Посмотреть сообщение
x_pixel = (x - x_min) * scale;
y_pixel = (y_min - y) * scale; // т.к. на экране y направлен вниз
то вершин почти не видно, только парочку у верхнего края Image
0
1968 / 824 / 115
Регистрация: 01.10.2012
Сообщений: 4,850
Записей в блоге: 2
10.01.2015, 12:34
Замените
C++
1
y_pixel = (y_min - y) * scale; // т.к. на экране y направлен вниз
На
C++
1
y_pixel = (y_max - y) * scale; // т.к. на экране y направлен вниз
И еще - предполагается что область вывода - экран, имеет координаты (0, 0) левого верхнего угла. Если это не так, добавьте нужные смещения, полные формулы
C++
1
2
x_pixel = (x - x_min) * scale + x_offset; 
y_pixel = (y_max - y) * scale + y_offset;
И они не мои, а получаются исходя из здравого смысла
0
1 / 1 / 0
Регистрация: 19.01.2014
Сообщений: 20
16.01.2015, 14:06  [ТС]
Igor3D, большое спасибо. Действительно, алгоритм довольно простой, но не пришёл мне в голову.
Однако есть одна накладочка, причём в буквальном смысле: в отмасштабированном графе вершины иногда накладываются друг на друга со 100%-й точностью. Приведу пример:

Имеем вершины
А (1.000, 0.000), в списке вершин этой серии x_min=0, x_max=1, y_min=0, y_max=1
Б (0.545, 0.416), в списке вершин этой серии x_min=0.144, x_max=0.545, y_min=0.416, y_max=0.817
Масштабируем их по формулам:
x_pixel = (x - x_min) * scale + x_offset;
y_pixel = (y_max - y) * scale + y_offset;
scale_x = screen_x / (x_max - x_min);
scale_y = screen_y / (y_max - y_min);
scale = min(scale_x, scale_y);
screen_x = Image1Width-30 = 971
screen_y = Image1Height-60 = 641
x_offset, y_offset считаем равными нулю.

Вершина А:
scale_x = 971 / (1-0) = 971
scale_y = 641 / (1-0) = 641
scale = min(971, 641) = 641
x_pixel = (1.000 - 0)*641 = 641
y_pixel = (1 - 0.000)*641 = 641
Вершина Б:
scale_x = 971 / (0.545-0.144) = 971/0.401 = 2421,4463840399002493765586034913
scale_y = 641 / (0.817-0.416) = 641/0.401 = 1598,5037406483790523690773067332
scale = 1598,5037406483790523690773067332
x_pixel = (0.545 - 0.144)*1598,5037406483790523690773067332 = 640.(9)
y_pixel = (0.817 - 0.416)*1598,5037406483790523690773067332 = 640.(9)
Итого: вершины А и Б накладываются друг на друга практически со 100%-й точностью, на экране это видно безупречно. Кроме того, бывают накладки чуть менее точные - на 99% и т.п.
Как избежать этого?
0
1968 / 824 / 115
Регистрация: 01.10.2012
Сообщений: 4,850
Записей в блоге: 2
18.01.2015, 09:34
Цитата Сообщение от Aireo Посмотреть сообщение
Однако есть одна накладочка, причём в буквальном смысле: в отмасштабированном графе вершины иногда накладываются друг на друга со 100%-й точностью. Приведу пример:
Это нормально, ведь рисуются 2 независимых набора, у каждого свои min, max, scale, поэтому да, точки могут совпадать. Вычисляйте min, max по обоим наборам чтобы они рисовались в одном масштабе.
0
1 / 1 / 0
Регистрация: 19.01.2014
Сообщений: 20
18.01.2015, 12:58  [ТС]
Так ведь min и max и сейчас вычисляются по обоим наборам (пример выше)?
0
1968 / 824 / 115
Регистрация: 01.10.2012
Сообщений: 4,850
Записей в блоге: 2
19.01.2015, 15:49
Цитата Сообщение от Aireo Посмотреть сообщение
Так ведь min и max и сейчас вычисляются по обоим наборам (пример выше)?
Ну как же по обоим если Вы пишете
Цитата Сообщение от Aireo Посмотреть сообщение
Имеем вершины
А (1.000, 0.000), в списке вершин этой серии x_min=0, x_max=1, y_min=0, y_max=1
Б (0.545, 0.416), в списке вершин этой серии x_min=0.144, x_max=0.545, y_min=0.416, y_max=0.817
Тут по разным для первой и второй серии, каждая имеет свой x(y)_min(max) - а надо "одно одеяло на всех"
1
1 / 1 / 0
Регистрация: 19.01.2014
Сообщений: 20
21.01.2015, 21:22  [ТС]
Igor3D, точно! Свёл все вершины в один набор и уже там вычислил минимумы и максимумы - всё рисуется корректно
Спасибо.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
21.01.2015, 21:22
Помогаю со студенческими работами здесь

Алгоритм масштабирования картинки, представленной виде массива байт
есть картинка- напрямую расположенная в памяти(делаю буферизацию) как byte array никак не могу придумать вменяемого механизма изменения...

Анимация масштабирования
Всем привет! Ищу плагин, либо просто скрипт, либо хотя-бы пример анимации масштабирования. Например в верхнем левом углу есть Кнопка. На...

Отмена масштабирования
Всем привет Есть такая проблема: есть картинка и лежит она в drawable. Если запускать программу, то Android "подгоняет"...

Формула масштабирования
Добрый вечер! Столкнулась с такой проблемой: нужно знать, как масштабировалась картинка, какие имеет размеры, но не получается их...

Масштабирования фигуры.
Вообщем дали задание розработать прогу которая выводить на экран фигуру, через подпрограммы в которых должны максимально использоваться...


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

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
Установка 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 - это библиотека я для воспроизведения аудио. В отличие от инструкции по добавлению текста код по проигрыванию звука уже содержится в шаблоне примера. Нужно только. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru