Математика и Java - найти доступный индекс по значению масштаба - PullRequest
2 голосов
/ 28 февраля 2012

Опять же, извиняюсь за плохой заголовок - очень трудно описать.

Я использовал тег Java, так как это язык, который я использую для этого проекта, но это действительно применимо к любому языку.

Я буду использовать упрощенный пример для ясности.

Допустим, я показываю графику, которая может быть "увеличена", и я могу получить доступ к плавающей запятой между 0 и 1, котораяпредставляет масштаб.

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

Каждая из этих версий в два раза меньше следующей более крупной версии.Самый крупный план был бы эквивалентен уровню масштабирования 1.

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

Так что, когдапользователь увеличивает масштаб изображения, мне нужно проверить, достигли ли они точки, когда было бы лучше отображать другую версию.Если бы они не достигли этой точки, я бы просто показал уменьшенную (уменьшенную) версию предыдущего уровня.

Например, скажем, есть 5 разных версий (хотя может быть любое число), вмассив, от наименьшего к наибольшему (хотя я мог бы изменить это, если бы это было проще), поэтому версии [4] - самые большие, а версии [0] - самые маленькие.

Например,

  • при увеличении 1, показать версии [4]
  • при увеличении 0,5, показать версии [3]
  • при 0,25, показать версии [2]
  • при0.125, показать версии [1]
  • в 0.0625, показать версии [0]

Поскольку нет версии, доступной для половины версий [0], я все равно покажу версии [0] но в половину размера.Если бы была добавлена ​​другая версия, она показала бы, когда общий масштаб (увеличение) был бы равен 0,03125 или меньше.

Для интервалов между масштабами я должен показать следующее наибольшее изображение, но с уменьшенным размером.

Например,

  • При увеличении 1 я бы показал наибольший (версии [4]), немасштабированный.
  • При увеличении 0,8 по-прежнему отображаетсянаибольший, но в масштабе 0,8
  • При увеличении 0,5, показывать версии [3] без масштабирования
  • При увеличении 0,3 показывать версии [3] в масштабе 0,6
  • приувеличение 0,2, показать версии [2] в масштабе 0,8
  • При увеличении 0,1 показать версии [1] в масштабе 0,8

Я мог бы, вероятно, взломать это вместе с условиямиили связывание и Math.abs, и т. д., но я бы поспорил, что есть очень элегантный и эффективный способ справиться с этим с помощью чистой математики - это просто над моей головой.Если нет, то любые предложения относительно подхода, использующего чистый, предсказуемый код, также приветствуются.

Повторно - цель состоит в том, чтобы найти версию (индекс массива) версии для показа, а такжеОтносительный масштаб, в котором он должен отображаться, полностью основанный на «глобальном» масштабе.

TYIA.

Ответы [ 3 ]

4 голосов
/ 28 февраля 2012
int indexToUse = 0-Math.round(Math.log(zoom)/Math.log(2));
double zoomToUse = zoom/Math.pow(2, -indexToUse);

При этом используется информация, что каждое изображение ровно в 2 раза больше предыдущего.Это экспоненциальная шкала, поэтому ее обратный логарифм используется для поиска используемого индекса.

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

(Поскольку вы работаете с масштабированием, который всегда находится между 0 и 1, журнал всегда будет отрицательным, поэтому я пошел дальше и отрицал его.изображения для этого могут быть проще, или вы можете просто вычесть из длины, чтобы получить фактический индекс для использования.)

BigMoMo отметил, что Math.log Java является естественным журналом.Кроме того, как он указал, вы можете получить log2, разделив натуральный логарифм на натуральный логарифм 2. Я отразил это в примере кода.

Чтобы ответить на ваш дополнительный вопрос,

double getZoom(int index, double zoomOnImage){
    return Math.pow(2, -index) * zoomOnImage;
}
0 голосов
/ 28 февраля 2012

Если обратный порядок, например:

при увеличении 1, показать версии [0] (самая большая); при увеличении 0,5, показать версии [1]; в 0,25, показать версии [2]; в 0.125, показать версии [3]; в 0.0625 показывают версии [4]; ...

Мы ясно видим, что индекс i = log (zoom) / log (0.5) ; или zoom = pow (0.5, i). Для тех случаев, когда увеличение не является точно степенью 0,5, мы просто берем часть ceil или integar, например когда zoom = 0,4, log (0,4) / log (0,5) = 1,32192, тогда индекс должен быть равен 1. Итак, простым индексом является внутренняя часть log (zoom) / log (0.5).

Фактическое увеличение: zoom / z [i] (i - индекс, z - массив масштабирования {1, 0,5, 0,25, 0,125, 0,0625})

Продолжите приведенный выше пример для данного увеличения 0,4, индекса = 1 (сверху) и конечного увеличения: 0,4 / z [i] = 0,4 / z [1] = 0,4 / 0,5 = 0,8.

Чтобы получить индекс на практике / в реализации, вам не нужно вычислять log (x), просто сравните значение масштабирования, чтобы увидеть, в какой слот / индекс он подходит (используя своего рода стратегию двоичного поиска). Как только индекс найден, окончательный масштаб вычисляется как zoom / z [i].

0 голосов
/ 28 февраля 2012

Если вы попробуете интерфейс, такой как Карты Google , вы заметите, что он не непрерывно масштабируется.Вместо этого он перемещается пошагово.

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

  Zoom  Tileset  Scale
   1       1       0.5
   2       1       1
   3       2       0.25
   4       2       0.5
   5       2       1
   ...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...