Как использовать полосу прокрутки для плавного масштабирования графика или изображения

#delphi #graphics #scaling

#delphi #графика #масштабирование

Вопрос:

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

Например, возможно, график представляет собой синусоидальную волну с пиком 1,0. Перетаскивая полосу прокрутки, пользователь должен иметь возможность увеличить пиковое значение до 2,0, 200 или уменьшить его до 0,5 и т.д.

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

Я не совсем понимаю математику здесь. Я обеспокоен тем, что управление элементом управления не будет плавным или интуитивно понятным для пользователя. Здесь есть что-то, связанное с экспонентами или журналами, не так ли? Не будет ли середина полосы прокрутки помечена как 1.0, со значениями выше шага (в интервале между журналами) вверх, а ниже 1.0, с шагом вниз?

Я помню ноль из моего логарифмического / экспоненциального математического опыта почти четыре десятилетия назад.

Мой язык — Delphi, но некоторые фрагменты кода в псевдокоде были бы полезны.

TIA

PS Пожалуйста, не стесняйтесь добавлять дополнительные теги к этому вопросу, чтобы его увидела наиболее подходящая аудитория…

Комментарии:

1. Есть ли веская причина, по которой вы не используете сам элемент управления диаграммой для масштабирования? И ваш вопрос граничит с неопровержимым / неопределенным / нечетким / неопределенным.

Ответ №1:

Я думаю, вы уже ответили на большую часть вопроса. Вы знаете, что хотите использовать логарифмическую шкалу. Таким образом, у вас будут отметки с одинаковым интервалом, 0.01, 0.1, 1.0, 10.0, 100.0, скажи.

Вместо полосы прокрутки вам следует использовать полосу отслеживания. Значения на панели дорожек приведены в логарифмическом масштабе. Итак, вы хотите, чтобы что-то вроде 0 соответствовало 0,01, 100 соответствовало 0,1, 200 соответствовало 1,0 и так далее. Это дает вам полосу прокрутки с минимальным значением 0, максимальным значением 400 и начальной позицией 200, то есть 1.0.

Теперь осталось сопоставить положение полосы прокрутки с масштабом. Вам нужно Scale(0) равняться 0.01, Scale(100) равняться 0.1 и так далее. Для этого используется возведение в степень 10.

 function Scale(const Position: Integer): Double;
var
  Exponent: Double;
begin
  Exponent := (Position-200)/100.0;
  Result := Power(10.0, Exponent);
end;
  

Другой путь включает в себя логарифмы и перестановку.

 function Position(const Scale: Double): Integer;
begin
  Result := Round(100.0*Log10(Scale))   200;
end;
  

Естественно, если выбранные мной цифры и минимальные / максимальные значения вас не устраивают, вы можете достаточно легко изменить их, чтобы они соответствовали.

Комментарии:

1. 1. Однако по чисто «семантическим» причинам я бы использовал const перед Position: Integer аргументом. (Да, это было самое серьезное возражение, которое я мог придумать!)

2. @Andreas Я бы тоже, но я не потрудился напечатать это здесь. Я рад, что вы отредактировали его для меня !! 😉

3. 1. Ваша математика кажется прекрасной. Кстати, это наш друг. Вчера вечером я отклонил сообщение, и сегодня моя репутация снизилась на 6 (без объяснений ни на одном из dv), а его на 4. Мне было интересно, кто был получателем другого понижающего голоса; Я думаю, теперь мы знаем. Ты думаешь, он когда-нибудь вырастет и станет менее инфантильным?

4. 1, попробуйте сбалансировать голосование «против». В последнее время я видел, как происходили случайные отклонения, в том числе и для меня. Кто-нибудь знает, кто / почему? Я не знаю способа узнать, кто за что проголосовал по вопросу или ответу.