Алгоритм зума 2D сетки
От: Аноним  
Дата: 26.10.07 13:11
Оценка:
Помогите, совсем я запутался.

Рисуется в окне сетка,которая является образом реальной математической сетки: размер одной ячейки в пикселях на экране — А (тип int), размер одной ячейки реальной сетки — В (тип float). Через каждые 10 ячеек рисуются жирные линии и пишется число (В*номер ячейки)

Так вот, во всем этом деле надо реалтизовать зум.

Как я делаю:

if (A>50)
{
   A=10;
   B/=10;
}
else
   if (A<3)
  {
     A=30;
     B*=10;
  }
  else
      if (zoom_in)
      {
          A++;
      }   
      else
      if (zoom_out)
      {
          A--;
      }


И получаеться полная ерунда. Основная сложность, что при резких скачках у нас не только сетка умельчается (увеличивается), а мы еще улетаем не в те значения где были

Кто-нить сталкивался с такой задачей?
Re: Алгоритм зума 2D сетки
От: Кодт Россия  
Дата: 26.10.07 14:56
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>Рисуется в окне сетка,которая является образом реальной математической сетки: размер одной ячейки в пикселях на экране — А (тип int), размер одной ячейки реальной сетки — В (тип float). Через каждые 10 ячеек рисуются жирные линии и пишется число (В*номер ячейки)


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




Критерий шага штрихов такой:
— он должен быть "красивым" (чтобы большим штрихам соответствовали более-менее круглые числа)
— он должен быть наиболее частым из всех допустимых
— мелкие штрихи должны идти с шагом не менее 2 пикселов

Первый пункт даёт нам семейства вида
*1 -- 1,2,3,4,5,6,7,8,9,10
*2 -- 2,4,6,8,10,12,14,16,18,20
*5 -- 5,10,15,20,25,30,35,40,45,50
*10 и т.д. вверх
/2
/5
/10 и т.д. вверх

То есть, нужно решить уравнение вида
units_per_pixel*2 <= units_per_stroke,
где units_per_pixel определено текущим масштабом (1/zoom, попросту),
а units_per_stroke ищется среди { 10^±p, 2*10^±p, 5*10^±p }

1/zoom*2 <= {1,2,5}*10^p
1/zoom*2/{1,2,5} <= 10^p
lg(1/zoom*2/{1,2,5}) <= p
-lg(zoom)+{lg 2, 0, lg 0.4} <= p
p — целое




Тупое предложение ряда масштабов — это степени двойки. Интуитивно они очень просты: zoom in/out — приблизить/удалить в два раза.
Зато числа получаются некрасивыми. Ладно 1600%, а каково 6.25%?
Поэтому опять же, можно предложить десятичную шкалу: *1, *2, *5, *10, ... и /2, /5, /10, ...
Зная текущую величину масштаба,
— находим его логарифм l = lg(zoom)
— округляем до ближайшего целого+{lg 0, lg 2, lg 5} — вверх при zoom in, вниз при zoom out




Ну а определившись с математикой, далее можем пользоваться или логарифмами-экспонентами, или рукодельными функциями нахождения ближайшей степени.
... << RSDN@Home 1.2.0 alpha rev. 655>>
Перекуём баги на фичи!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.