Скос контура/формы в Core Graphics

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

Я включил свою реализацию ниже. Я использую три переменные для определения скоса: CGFloat bevelSize, UIColor highlightColor, UIColor shadow. Обратите внимание, что угол источника света всегда равен 135 градусам. Я еще не закончил это реализовывать, но вот, по сути, то, что я пытаюсь сделать, разбитое на две части. Часть первая, создайте фокусы:

  1. Я нахожу биссектрисы углов между соседними линиями пути.
  2. Для дуг биссектриса — это линия, перпендикулярная линии, созданной двумя конечными точками дуги, начинающейся из средней точки. Это должно позаботиться о большинстве ситуаций, в которых используется дуга. Я не беру биссектрису дуги и прямой. В этих случаях биссектриса дуги должна работать нормально.
  3. Затем я вычисляю фокальные точки на основе пересечения каждой соседней биссектрисы.
  4. Если фокальная точка находится внутри формы, она используется, в противном случае она отбрасывается.

Цель создания фокусных точек — пропорционально «сжать» форму.

Вторая часть немного сложнее. Мне необходимо создать каждую сторону/сегмент скошенной формы. Я делаю это, рисуя «в» (с помощью bevelSize) каждую точку исходной формы по радиусу линии, которая проходит от ближайшего фокуса к рассматриваемой точке. Когда у меня есть два последовательных «bevelPoints», я создаю UIBezierPath, который простирается от bevelPoints до исходных точек и обратно до bevelPoints (обратите внимание, это включает дуги). Это создает «сторону/сегмент», который я могу использовать для заполнения. На прямых сторонах я просто заливаю либо тенью, либо цветом блика, в зависимости от угла стороны. Для дуг я определяю «дугу» в радианах. Если эта дуга содержит угол перехода (M_PI_4 или M_PI + M_PI_4), я заполняю ее градиентом (от тени к блику или от блика к тени, в зависимости от того, что подходит). В противном случае я заполняю его сплошным цветом.

Обновить

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


person Aaron Hayman    schedule 19.03.2012    source источник
comment
Вопрос длинный и включает в себя много деталей. Можно ли вообще упростить?   -  person Dan Rosenstark    schedule 16.04.2012
comment
Вроде, как бы, что-то вроде. Первая часть вопроса - главный вопрос: кто-нибудь знает, как скосить произвольную форму в core-graphics? Остальное — просто подробное описание того, как я сам реализовал фаску (с которой я уже закончил). Он работает нормально на нескольких формах (но не на всех). Я оставляю вопрос открытым, если у кого-то есть метод.   -  person Aaron Hayman    schedule 16.04.2012
comment
Я думал опубликовать свое решение, но это всего около 400 строк кода... кажется, что это много.   -  person Aaron Hayman    schedule 16.04.2012
comment
Хорошо, я обновил пост. Он включает в себя весь код, который я использовал для скоса своих путей.   -  person Aaron Hayman    schedule 16.04.2012
comment
Извините, я не был ясен. Я имел в виду, что вопрос длинный и включает в себя СЛИШКОМ много деталей, поэтому МОЖЕТ быть, поэтому никто на него не ответил. Но кто знает, может быть, они появятся сейчас? Удачи с этим.   -  person Dan Rosenstark    schedule 16.04.2012
comment
Да, на Stack Exchange есть и другие вопросы, касающиеся скоса основной графики. Я хотел предоставить детали реализации на случай, если кто-то захочет сделать это самостоятельно или у него есть идеи, как сделать это лучше.   -  person Aaron Hayman    schedule 16.04.2012
comment
Так это больше не вопрос?   -  person Dan Rosenstark    schedule 16.04.2012
comment
Нет, это вопрос. Мое решение не идеально. В нем отсутствуют некоторые желаемые функции (это работает не со всеми фигурами), которые я не знаю, как реализовать. Но я не могу спросить, как реализовать функциональность, не включив детали моей текущей реализации. Другими словами, я не могу задать вопрос, не вдаваясь в технические подробности. Я знаю, что на него могут никогда не ответить, и многие люди даже не удосужятся его прочитать, но это не значит, что я откажусь от него. Кроме того, моя текущая реализация работает во многих случаях и может оказаться полезной для других.   -  person Aaron Hayman    schedule 16.04.2012
comment
Хорошо. Поскольку вы настаиваете, вы могли бы также включить несколько изображений, показывающих, что сломано, если это возможно.   -  person Dan Rosenstark    schedule 17.04.2012
comment
Я посмотрю, как это сделать. Но мой пост на самом деле на пределе. Я не думаю, что они позволят мне добавить больше.   -  person Aaron Hayman    schedule 17.04.2012
comment
Лично я бы сделал где-нибудь статью в блоге, а затем сослался бы на нее в вопросе. В противном случае вопрос будет/должен быть закрыт.   -  person Dan Rosenstark    schedule 17.04.2012
comment
На самом деле это очень хорошая идея. Спасибо :)   -  person Aaron Hayman    schedule 17.04.2012
comment
@Yar Я добавил ответ со ссылкой на блог, который я написал, который включает мою реализацию этого, если вам интересно.   -  person Aaron Hayman    schedule 30.05.2012


Ответы (1)


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

ОБНОВЛЕНИЕ

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

Я объясню код и процесс, который я использовал для скашивания, здесь: Скос фигур в основной графике< /а>

Вот код: Github: CGPathBevel.

Код не идеален: я открыт для предложений/исправлений/лучших способов ведения дел.

person Aaron Hayman    schedule 29.05.2012
comment
статья выглядит отлично. Я должен буду попробовать это в ближайшее время. Спасибо! +1 - person Dan Rosenstark; 30.05.2012