Нарисуйте радиальные данные на iPhone с помощью CoreGraphics

Я пытаюсь нарисовать данные радара поверх карты с помощью CoreGraphics. Раньше я пытался нарисовать каждую точку данных индивидуально, прокладывая путь вокруг каждой отдельной точки данных и затем заполняя соответствующий цвет. Итак, для этого метода мне нужно было иметь 4 точки местоположения и значение данных для каждой точки данных. Выполнение этого способа оказалось слишком дорогостоящим, поскольку для каждого изображения требуется от 30 000 до 80 000 точек данных.

Данные радара хранятся в радиальном формате (360 радиалов, каждый из которых содержит 230 точек данных). Поэтому вместо того, чтобы перебирать каждую точку данных, я перебираю только радиалы. И вместо пути вокруг каждой точки данных у меня есть путь вокруг каждого радиала. Затем я создаю и рисую линейный градиент (CGGradientCreateWithColors), используя массив цветов для этого конкретного градиента.

Этот метод отрисовывает намного быстрее, чем раньше, но он все еще недостаточно быстр. Другой проблемой является «гладкость» данных при увеличении масштаба. Градиент смешивается между каждой точкой данных в радиале, поэтому вы не можете видеть отдельные пиксели. Я не хочу этого делать. Я думаю, что именно здесь мой самый большой удар производительности (вычисление градиента между каждой точкой данных). Я бы предпочел, чтобы каждая точка данных была нарисована отдельным цветом. Это выглядело бы лучше и должно работать лучше.

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

Заранее спасибо, Росс

РЕДАКТИРОВАТЬ

Первое изображение - это оригинальный способ, которым я рисовал (рисовал каждую точку данных отдельно). Вот так я хочу, чтобы все выглядело в итоге.

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

Это

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


person Ross Kimes    schedule 28.07.2011    source источник
comment
это случайно сейчас приложение в магазине?   -  person valexa    schedule 17.08.2012
comment
Да, это называется Storm Spotter.   -  person Ross Kimes    schedule 17.08.2012


Ответы (1)


У меня проблемы с представлением того, что вы пытаетесь нарисовать (трудно представить, чтобы нарисовать 80000 чего-либо на экране iPhone и каждая вещь была бы больше пикселя ...), но вот некоторые мысли на вашем пути.

Во-первых, если у вас есть постоянный объект, который нужно рисовать несколько раз, поместите его на CGLayer. Не CALayer, а CGLayer. Это аппаратно-оптимизированный объект для многократной "штамповки" одного и того же. Если вам нужно изменить цвета или даже применить градиент, вы можете применить их, используя маску или составив CGImage (последнее, как правило, быстрее, если вы затем можете повторно использовать полученное изображение и не должны ничего масштабировать).

Насколько это возможно, предварительно вычислите свои градиенты и сохраните их в структурах данных. Попытка вычислить их за drawRect: часто сильно снижает производительность. Точно так же предварительно вычислите свои пути, чтобы вам не приходилось строить их каждый раз, когда вы рисуете.

Если вы можете избежать масштабирования слоев, вы можете установить для них shouldRasterize значение YES, что обычно улучшает производительность, когда у вас есть сложные слои. С другой стороны, если вам нужно выполнить масштабирование или другие преобразования, рисование на CALayer и применение необходимого преобразования может быть очень быстрым. Вы также можете применять преобразования ко всему UIView, но если вам нужно преобразовать множество отдельных вещей, то это суть CALayer. (Что касается предыдущего пункта, вы, конечно, можете нарисовать CGLayer на CALayer.)

Я не понимаю, что вы имеете в виду, говоря «незаметно». Путь - это непрерывная линия, определяемая контрольными точками.


РЕДАКТИРОВАТЬ. На основании ваших правок я рекомендую поэкспериментировать с индексированным цветовым пространством (CGColorSpaceCreateIndexed()). Таким образом, ваш градиент не должен включать промежуточные цвета, а вычисления должны выполняться быстрее для всего рисунка.

Вам также следует взглянуть на CGShading. (Я считаю, что это доступно для iOS, а не только для Mac.) Это может быть ближе к тому, что вы хотите, чем CGGradient.

person Rob Napier    schedule 28.07.2011
comment
Это должно сработать. Спасибо! - person Ross Kimes; 02.08.2011