Форум программистов, компьютерный форум, киберфорум
Наши страницы
Алгоритмы
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.82/11: Рейтинг темы: голосов - 11, средняя оценка - 4.82
Aireo
1 / 1 / 0
Регистрация: 19.01.2014
Сообщений: 20
1

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

04.01.2015, 20:36. Просмотров 1987. Ответов 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
QA
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
04.01.2015, 20:36
Ответы с готовыми решениями:

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

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

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

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

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

11
wingblack
281 / 255 / 45
Регистрация: 09.04.2013
Сообщений: 955
05.01.2015, 12:31 2
Сначала находишь минимумы и максимумы по вертикали и горизонтали.
Если хочешь чтобы при масштабировании сохранялись пропорции - смотришь на отношение получившихся сторон (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
Aireo
1 / 1 / 0
Регистрация: 19.01.2014
Сообщений: 20
05.01.2015, 19:42  [ТС] 3
Что означает -> в вашей логике?
Про Xmax, Xmin, Ymax, Ymin уже дошло, они используются.
На данный момент граф отцентрирован на Image1, осталось его отмасштабировать,

Добавлено через 5 часов 26 минут
wingblack, ваши формулы понятны, но неясна логика их применения. Вы хотите сказать, что Width*(X-Min)/(Max-Min) - это и есть коэффициент масштабирования?
0
Igor3D
1229 / 596 / 74
Регистрация: 01.10.2012
Сообщений: 2,844
07.01.2015, 10:10 4
Пусть есть значения 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
07.01.2015, 10:10
wingblack
281 / 255 / 45
Регистрация: 09.04.2013
Сообщений: 955
07.01.2015, 16:08 5
С помощью "->" я указываю диапазон значений, в котором будут точки при использовании текущей формулы.
Согласен, не очень удачный выбор.
0
Aireo
1 / 1 / 0
Регистрация: 19.01.2014
Сообщений: 20
09.01.2015, 20:15  [ТС] 6
Igor3D, если выводить вершину по вашей формуле в координаты (scale*исходный_x, scale*исходный_y), то часть вершин (а иногда - все) вылезает за пределы области вывода.
А если в
Цитата Сообщение от Igor3D Посмотреть сообщение
x_pixel = (x - x_min) * scale;
y_pixel = (y_min - y) * scale; // т.к. на экране y направлен вниз
то вершин почти не видно, только парочку у верхнего края Image
0
Igor3D
1229 / 596 / 74
Регистрация: 01.10.2012
Сообщений: 2,844
10.01.2015, 12:34 7
Замените
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
Aireo
1 / 1 / 0
Регистрация: 19.01.2014
Сообщений: 20
16.01.2015, 14:06  [ТС] 8
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
Igor3D
1229 / 596 / 74
Регистрация: 01.10.2012
Сообщений: 2,844
18.01.2015, 09:34 9
Цитата Сообщение от Aireo Посмотреть сообщение
Однако есть одна накладочка, причём в буквальном смысле: в отмасштабированном графе вершины иногда накладываются друг на друга со 100%-й точностью. Приведу пример:
Это нормально, ведь рисуются 2 независимых набора, у каждого свои min, max, scale, поэтому да, точки могут совпадать. Вычисляйте min, max по обоим наборам чтобы они рисовались в одном масштабе.
0
Aireo
1 / 1 / 0
Регистрация: 19.01.2014
Сообщений: 20
18.01.2015, 12:58  [ТС] 10
Так ведь min и max и сейчас вычисляются по обоим наборам (пример выше)?
0
Igor3D
1229 / 596 / 74
Регистрация: 01.10.2012
Сообщений: 2,844
19.01.2015, 15:49 11
Цитата Сообщение от 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
Aireo
1 / 1 / 0
Регистрация: 19.01.2014
Сообщений: 20
21.01.2015, 21:22  [ТС] 12
Igor3D, точно! Свёл все вершины в один набор и уже там вычислил минимумы и максимумы - всё рисуется корректно
Спасибо.
0
21.01.2015, 21:22
Answers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
21.01.2015, 21:22

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

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

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


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

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.