Системы координат и преобразовывают
Координатные пространства упрощают код для прорисовки, требуемый создать сложные интерфейсы. В стандартном приложении Mac окно представляет основную систему координат для рисования, и все содержание должно в конечном счете быть указано в том координатном пространстве, когда это отправляется в сервер окна. Для даже простых интерфейсов, однако, редко удобно указать координаты относительно источника окна. Когда окно изменяет размеры, даже расположение фиксированных элементов может изменить и потребовать перерасчета. Это - то, где Какао делает вещи простыми.
Каждое представление Cocoa, которое Вы добавляете к окну, обслуживает свою собственную систему локальной координаты для рисования. Вместо того, чтобы преобразовывать координатные значения в координаты окна, Вы просто рисуете использование системы локальной координаты, игнорируя любые изменения в позиции представления. Прежде, чем отправить Ваши команды рисования в сервер окна, Какао автоматически исправляет координатные значения и помещает их в основное координатное пространство.
Даже с присутствием пробелов локальной координаты, часто необходимо изменить координатное пространство временно для влияния на определенные способы поведения. Изменение координатного пространства сделано с помощью математических трансформаций (также известный, как преобразовывает). Преобразовывает преобразовывают координатные значения от одного координатного пространства до другого. Можно использовать, преобразовывает для изменения системы координат представления в пути, влияющем на последующие вызовы рендеринга, или можно использовать их для определения расположения точек в окне или другом представлении.
Следующие разделы предоставляют информацию о том, как Какао управляет системами локальной координаты Ваших представлений и как можно использовать, преобразовывает для влияния на среду получения.
Основы систем координат
Какао и Кварц используют ту же основную модель системы координат. Прежде чем можно будет нарисовать эффективно, необходимо понять это координатное пространство и как оно влияет команды рисования. Это также помогает знать пути, которыми можно изменить координатное пространство для упрощения кода для прорисовки.
Системы локальной координаты
Какао использует Декартову систему координат в качестве своей базовой модели для указания координат. Источник в этой системе расположен в нижнем левом углу текущего пространства получения с положительными значениями, расширяющимися вдоль осей и направо от точки источника. Корневой источник для всей системы расположен в нижнем левом углу экрана, содержащего строку меню.
Если бы Вы были вынуждены нарисовать все свое содержание в координатах экрана — система координат, источник которой расположен в нижнем левом углу основного экрана компьютера — то Ваш код был бы довольно сложен. Для упрощения вещей Какао устанавливает систему локальной координаты, источник которой равен источнику окна, или просмотрите, который собирается нарисовать. Последующие вызовы получения в окне или представлении имеют место относительно этой системы локальной координаты. Как только код заканчивает рисовать, Какао и базовая графическая система преобразовывают координаты в локальных координатах назад к координатам экрана так, чтобы содержание могло быть составлено с содержанием из других приложений и отправлено в аппаратное обеспечение машинной графики.
Рисунок 3-1 показывает точки источника системы координат экрана, окна и представления. В каждом случае значение к нижней левой части каждой точки является координатой, измеренной в ее системе координаты вышестоящего элемента. (Экран не имеет системы координаты вышестоящего элемента, таким образом, оба координатных значения 0). Родитель окна является экраном, и родитель представления является окном.
Отображение от координат экрана до локального окна или координат представления имеет место в текущей матрице преобразования (CTM) объекта контекста графики Какао. Какао применяет CTM автоматически к любым вызовам получения, которые Вы выполняете, таким образом, Вы не должны преобразовывать координатные значения сами. Можно изменить CTM, хотя сменить положение и ориентацию осей координат в представлении. (Для получения дополнительной информации посмотрите Операции Трансформации.)
Точки по сравнению с пикселями
Система получения в OS X основывается на модели рисования PDF, которая является основанной на векторе моделью получения. По сравнению с основанной на растре моделью получения, где команды рисования воздействуют на отдельные пиксели, команды рисования в OS X указаны, использовав пространство фиксированного чертежа в масштабе, известное как пользовательское координатное пространство. Система тогда отображает координаты в этом пространстве получения на фактические пиксели соответствующего целевого устройства, такие как монитор или принтер. Преимущество этой модели состоит в том, что графика, нарисованная с помощью векторных команд, масштабируется приятно к любому устройству разрешения. Когда разрешение устройства увеличивается, система в состоянии использовать любые дополнительные пиксели для создания более свежего взгляда к графике.
Для поддержания точности, свойственной с основанной на векторе системой получения, рисующие координаты указаны с помощью значений с плавающей точкой вместо целых чисел. Использование значений с плавающей точкой для координат OS X позволяет Вам указать расположение содержания Вашей программы очень точно. По большей части Вы не должны волноваться о том, как те значения в конечном счете отображаются на экране или другом устройстве вывода. Вместо этого Какао заботится об этом отображении для Вас.
Даже при том, что модель получения основывается на PDF, существуют все еще времена, когда необходимо представить основанное на пикселе содержание. Растровые изображения являются распространенным способом создать пользовательские интерфейсы, и Ваш код для прорисовки, возможно, должен внести специальные корректировки, чтобы гарантировать, что любые растровые изображения составлены правильно на различных устройствах разрешения. Точно так же можно хотеть гарантировать, чтобы даже основанная на векторе графика выровнялась должным образом вдоль границ пикселей так, чтобы у них не было сглаженного появления. OS X предоставляет многочисленные услуги, чтобы помочь Вам нарисовать основанное на пикселе содержание путем, Вы хотите его.
Следующие разделы обеспечивают больше подробности о координатных пространствах, используемых для рисования и рендеринга содержания. Там также следует некоторым советам о том, как иметь дело со специфичным для пикселя рендерингом в Вашем коде для прорисовки.
Пространство пользователя
Пользовательское координатное пространство в Какао является средой, которую Вы используете для всех своих команд рисования. Это представляет фиксированное координатное пространство масштаба, что означает, что команды рисования, которые Вы выпускаете в этом результате пространства в графике, размер которой является непротиворечивым независимо от разрешения базового устройства.
Модули в пространстве пользователя основываются на точке принтера, использовавшейся в издательском деле для измерения размера содержания на печатной странице. Единственная точка эквивалентна 1/72 дюйма. Точки были приняты более ранними версиями Mac OS как стандартное разрешение для содержания на экране. OS X продолжает использовать то же эффективное «разрешение» для получения пространства пользователя.
Несмотря на то, что единственная точка часто соответствовала непосредственно пикселю в прошлом в OS X, который может не иметь место. Точки не связываются к разрешению никакого определенного устройства. При рисовании прямоугольника, ширина которого и высота являются точно тремя точками, который не означает, что это будет представлено на экране как три пикселя прямоугольником на три пикселя. На экране на 144 точки на дюйм прямоугольник мог бы быть представлен с помощью шести пикселей за сторону, и на принтере на 600 точек на дюйм, прямоугольник потребует 25 пикселей за сторону. Фактический перевод от точек до пикселей зависим от устройств и обработан для Вас автоматически OS X.
Для всех практических целей пользовательское координатное пространство является единственным координатным пространством, о котором необходимо думать. Существуют некоторые исключения к этому правилу, однако, и те покрыты Выполнением Точного пикселем Получения.
Пространство устройства
Координатное пространство устройства относится к собственному координатному пространству, использованному целевым устройством, ли это быть экраном, принтером, файлом или некоторым другим устройством. Модули в координатном пространстве устройства указаны с помощью пикселей, и разрешение этого пространства зависимо от устройств. Например, большинство мониторов имеет разрешения в диапазоне на 100 точек на дюйм, но принтеры могут иметь разрешения чрезмерные 600 точек на дюйм. Существуют некоторые устройства, не имеющие фиксированного разрешения, как бы то ни было. Например, PDF и файлы EPS являются независимым разрешением и могут масштабировать их содержание к любому разрешению.
Для потребителей Какао координатное пространство устройства - что-то, о чем редко необходимо волноваться. Каждый раз, когда Вы генерируете команды рисования, Вы всегда указываете позиции с помощью координат пространства пользователя. Единственное время, когда Вы, возможно, должны были бы знать о координатах пространства устройства, - при корректировке нарисованного содержания для отображения более чисто на определенное целевое устройство. Например, Вы могли бы использовать координаты устройства для выравнивания пути или изображения к определенным границам пикселей для предотвращения нежелательного сглаживания. В такой ситуации можно скорректировать координаты пространства пользователя на основе разрешения базового устройства. Для получения информации о том, как сделать это, посмотрите Выполнение Точного пикселем Получения
Независимый от разрешения пользовательский интерфейс
В OS X v10.4 и ранее, Кварц и Какао всегда обрабатывал экранные устройства, как будто их разрешение всегда было 72 точки на дюйм, независимо от их фактического разрешения. Это означало, что для основанного на экране получения, одна точка в пространстве пользователя была всегда равна одному пикселю в пространстве устройства. Поскольку экраны совершенствовались на хорошо прошлые 100 точек на дюйм в разрешении, предположение, что одна точка равнялась одному пикселю, начало вызывать проблемы. Наиболее заметно все стало намного меньшим. В OS X v10.4, имели место первые шаги при разъединении отношения пикселя точки.
В OS X v10.4, поддержка была добавлена для независимости разрешения в пользовательских интерфейсах приложения. Начальное внедрение этой функции обеспечивает способ для Вас разъединить пространство пользователя Вашего приложения от пространства базового устройства вручную. Вы делаете это путем выбора масштабного коэффициента для пользовательского интерфейса. Масштабный коэффициент заставляет содержание пространства пользователя масштабироваться указанной суммой. Код, реализованный должным образом для независимости разрешения, должен выглядеть хорошо (хотя больше). Код, не реализованный должным образом, может видеть проблемы выравнивания или пиксельные трещины вдоль границ формы. Для включения независимости разрешения в приложении запустите Кварцевую Отладку и выберите Tools> Show User Interface Resolution, затем установите масштабный коэффициент. После изменения разрешения повторно запустите свое приложение, чтобы видеть, как это реагирует на новое разрешение.
По большей части приложениям Какао не придется сделать ничего специального для обработки независимого от разрешения UI. При использовании стандартных представлений Какао и команд рисования для рисования содержания, Какао автоматически масштабирует любое содержание, Вы рисуете использование текущего масштабного коэффициента. Для находящегося на пути содержания Ваш код для прорисовки должен потребовать минимальных изменений. Для изображений, тем не менее, Вы, возможно, должны предпринять шаги, чтобы удостовериться, что те изображения выглядят хорошими в более высоких масштабных коэффициентах. Например, Вы, возможно, должны были бы создать версии более высокого разрешения для использования в своих интересах увеличенного разрешения экрана. Вы, возможно, также должны были бы скорректировать позицию изображений для предотвращения пиксельных трещин, вызванных изображениями, нарисованными на неинтегральных границах пикселей.
Для подсказок относительно того, как удостовериться, Ваше содержание рисует хорошо в любом разрешении, посмотрите Выполнение Точного пикселем Получения. Для получения дополнительной информации о независимости разрешения и как это влияет на Ваш код, см. Инструкции по Высокому разрешению для OS X.
Преобразуйте основы
Преобразования являются инструментом для управления координатами (и системы координат) быстро и легко в Вашем коде. Рассмотрите прямоугольник, источник которого в (0, 0). Если бы Вы хотели изменить источник этого прямоугольника к (10, 3), то было бы довольно просто изменить источник прямоугольника и нарисовать его. Предположим, тем не менее, что Вы хотели изменить источник сложного контура, включившего десятки точек и несколько Кривых Безье с их связанными контрольными точками. Как простой это должно было бы повторно вычислить позицию каждой точки по тому пути? Это, вероятно, заняло бы много времени и потребовало бы некоторых довольно сложных вычислений. Войдите преобразовывает.
Преобразование является двумерным математическим массивом, используемым для отображения точек от одного координатного пространства до другого. Используя преобразования, можно масштабировать, повернуть, и перевести содержание свободно в двумерном пространстве с помощью только нескольких методов и отменить изменения столь же быстро.
Поддержка преобразований в Какао предоставлена NSAffineTransform
класс. Следующие разделы обеспечивают справочную информацию о преобразованиях и их эффектах. Для получения дополнительной информации о то, как использовать, преобразовывает в Ваш код, посмотрите Используя Преобразования в Вашем Коде.
Идентификационные данные преобразовывают
Самый простой тип преобразования является идентификационными данными, преобразовывают. Идентификационные данные преобразовывают карты любая точка к себе — т.е. это не преобразовывает точку вообще. Вы всегда запускаете с идентификационных данных, преобразовывают и добавляют трансформации к нему. Начиная с идентификационных данных преобразовывают гарантии, что Вы запускаете с известного состояния. Для создания идентификационных данных преобразовывают, Вы использовали бы следующий код:
NSAffineTransform* identityXform = [NSAffineTransform transform]; |
Операции трансформации
Для двумерного получения можно преобразовать содержание несколькими различными способами, включая перевод, масштабирование и вращение. Преобразовывает изменяют систему координат для текущей среды получения и влияют на все последующие операции рисования. Прежде, чем применить преобразование, рекомендуется сохранить текущее состояние графики.
Следующие разделы описывают каждый тип трансформации и как это влияет на представленное содержание.
Перевод
Перевод включает смещение источника текущей системы координат горизонтально и вертикально определенной суммой. Перевод, вероятно, используется больше всего, потому что он может использоваться для расположения графических элементов в текущее представление. Например, при создании пути, начальная точка которого всегда (0, 0), Вы могли использовать перевод, преобразовывают для перемещения того пути вокруг представления, как показано на рисунке 3-2.
Для перевода содержания используйте translateXBy:yBy:
метод NSAffineTransform
. Следующий пример изменяет источник текущего контекста от (0, 0) к (50, 20) в координатном пространстве представления:
NSAffineTransform* xform = [NSAffineTransform transform]; |
[xform translateXBy:50.0 yBy:20.0]; |
[xform concat]; |
Масштабирование
Масштабирование позволяет Вам расширить или уменьшить модули пространства пользователя вдоль осей x и y независимо. Обычно, один модуль в пространстве пользователя равен 1/72 дюйма. Если Вы многократный масштаб любой оси 2, один модуль на той оси становится равным 2/72 дюйма. Это делает содержание нарисованным с масштабными коэффициентами больше, чем 1, кажутся увеличенными и содержание, нарисованное с масштабными коэффициентами, меньше чем 1 кажется севшим.
Рисунок 3-3 показывает эффекты масштабирования на содержании. В числе перевод преобразовывает, был уже применен так, чтобы источник был расположен в (1, 1) в исходной системе координат пространства пользователя. После применения преобразования масштабирования Вы видите измененную систему координат и как это отображается на систему исходной координаты.
Несмотря на то, что Вы могли бы обычно масштабироваться пропорционально путем применения того же масштабного коэффициента и к горизонтальным и к вертикальным осям, можно присвоить различные масштабные коэффициенты каждой оси для создания расширенного или искаженного изображения. Для масштабирования содержания пропорционально используйте scaleBy:
метод NSAffineTransform
. Для масштабирования содержания по-другому вдоль осей X и y используйте scaleXBy:yBy:
метод. Следующий пример демонстрирует масштабные коэффициенты, показанные на рисунке 3-3:
NSAffineTransform* xform = [NSAffineTransform transform]; |
[xform scaleXBy:2.0 yBy:1.5]; |
[xform concat]; |
Вращение
Вращение изменяет ориентацию осей координат путем вращения их вокруг текущего источника, как показано на рисунке 3-4. Можно изменить ориентацию через полный круг движения.
Для вращения содержания используйте rotateByDegrees:
или rotateByRadians:
методы NSAffineTransform
. Положительные значения вращения продолжаются против часовой стрелки вокруг текущего источника. Например, для вращения текущей системы координат 45 градусов вокруг текущей точки источника (как показано на рисунке 3-4) Вы использовали бы следующий код:
NSAffineTransform* xform = [NSAffineTransform transform]; |
[xform rotateByDegrees:45]; |
[xform concat]; |
Упорядочивание трансформации
Реализация преобразований использует умножение матриц для отображения входящей координатной точки на измененное координатное пространство. Несмотря на то, что математика матриц покрыта Математикой Преобразования, важный фактор для замечания - то, что умножение матриц является не всегда коммутативной работой — т.е. a
времена b
не всегда равняется b
времена a
. Поэтому порядок, в котором Вы применяете преобразования, часто крайне важен для достижения желаемых результатов.
Рисунок 3-5 показывает, что эти две трансформации применились к пути двумя различными способами. В верхней части числа содержание переводится 60 точками вдоль оси X и затем повернуло 45 градусов. В нижней части числа те же самые трансформации инвертируются с вращением, предшествующим переводу. Конечный результат является двумя различными системами координат.
Предыдущее число демонстрирует ключевой аспект упорядочивания трансформации. Каждая последовательная трансформация применяется к системе координат, создаваемой предыдущими трансформациями. Когда Вы переводите и затем вращаетесь, вращение начинается вокруг источника переведенной системы координат. Точно так же, когда Вы поворачиваете и затем переводите, перевод происходит вдоль осей повернутой системы координат.
Для трансформаций того же типа не имеет значения порядок трансформаций. Например, три вращения подряд создает систему координат, заключительное вращение которой равно заключительной сумме этих трех углов вращения. Могут быть другие случаи (такие как масштабирование 1,0), где порядок преобразований не имеет значения, но необходимо обычно предполагать, что порядок является значительным.
Преобразуйте математику
Все преобразовывают операции, способствуют зданию математической матрицы, тогда использующейся графической системой для вычислений расположения на экране отдельных точек. NSAffineTransform
класс использует 3 x 3 матрицы для хранения значений преобразования. Рисунок 3-6 показывает эту матрицу и выявляет ключевые факторы, используемые для применения, преобразовывает. В то время как tx и ty управляют переводом, m11, m12, m21, и значения m22 управляют и факторами масштабирования и вращения.
Используя линейную алгебру, возможно умножить координатный вектор через матрицу преобразования для получения нового координатного вектора, позиция которого равна исходной точке в новой системе координат. Рисунок 3-7 показывает процесс умножения матриц и получающиеся линейные уравнения.
Если Вы уже знакомы со структурами преобразования и математикой, можно установить значения матрицы преобразования непосредственно с помощью setTransformStruct:
метод NSAffineTransform
. Этот метод заменяет шесть ключевых значений преобразования новыми, которые Вы указываете. Замена всех значений сразу намного быстрее, чем применение отдельных трансформаций по одному. Это действительно требует, чтобы Вы предварительно вычислили матричные значения, как бы то ни было.
Для получения дополнительной информации о математике позади умножений матриц, посмотрите Кварц 2D Руководство по программированию.
Используя преобразования в Вашем коде
Когда пора нарисовать, код в Вашем представлении drawRect:
метод должен определить, где нарисовать отдельные части содержания. Позиция некоторых элементов, таких как изображения и прямоугольники, может быть указана легко, но для сложных элементов как пути, преобразования являются простым способом изменить текущее местоположение получения.
Создание и применение преобразования
Для создания нового объекта преобразования вызовите transform
метод класса NSAffineTransform
. Возвращенный объект преобразования установлен в идентификационные данные, преобразовывают автоматически. После добавления всех желаемых трансформаций к объекту преобразования Вы вызываете concat
метод для применения их к текущему контексту. Вызов concat
добавляют Ваши трансформации к CTM текущего графического контекста. Модификации остаются в действительности, пока Вы явно не отменяете их, как описано в Отмене Трансформации, или восстанавливается предыдущее состояние графики.
Следующий пример создает новый объект преобразования и добавляет несколько трансформаций к нему.
NSAffineTransform* xform = [NSAffineTransform transform]; |
// Add the transformations |
[xform translateXBy:50.0 yBy:20.0]; |
[xform rotateByDegrees:90.0]; // counterclockwise rotation |
[xform scaleXBy:1.0 yBy:2.0]; |
// Apply the changes |
[xform concat]; |
Отмена трансформации
После того, как примененный, преобразование влияет на все последующие вызовы получения в текущем контексте. Для отмены ряда трансформаций можно или восстановить предыдущее состояние графики или применить обратное преобразование. И методы имеют свои преимущества и недостатки, таким образом, необходимо выбрать метод на основе потребностей и доступной информации.
Восстановление предыдущего состояния графики является самым простым способом отменить трансформацию, но имеет другие побочные эффекты. В дополнение к отмене преобразования, восстанавливая состояние графики возвращается все другие атрибуты в текущей среде получения назад к их предыдущему состоянию.
Если Вы хотите отменить только текущую трансформацию, можно добавить обратное преобразование к CTM. Обратное преобразование инвертирует эффекты данного набора трансформаций с помощью дополнительного набора трансформаций. Для создания обратного объекта преобразования Вы используете invert
метод желаемого объекта преобразования. Вы тогда применяетесь, это изменило, преобразовывают объект к текущему контексту, как показано в следующем примере:
NSAffineTransform* xform = [NSAffineTransform transform]; |
// Add the transformations |
[xform translateXBy:50.0 yBy:20.0]; |
[xform rotateByDegrees:90.0]; // counterclockwise rotation |
[xform concat]; |
// Draw content... |
// Remove the transformations by applying the inverse transform. |
[xform invert]; |
[xform concat]; |
Вы могли бы использовать этот последний метод для рисования многократных элементов с помощью тех же атрибутов получения, но в различных позициях в представлении. В зависимости от типа трансформаций Вы используете, Вы могли бы также быть в состоянии сделать инкрементные трансформации. Например, если Вы вызываете translateXBy:yBy:
только, чтобы изменить местоположение источника, Вы могли переместить источник инкрементно для каждого последовательного элемента. Следующий пример, показывает, как Вы могли бы расположить один элемент в (10, 10) и следующее в (15, 10):
[NSAffineTransform* xform = [NSAffineTransform transform]; |
// Draw item 1 |
[xform translateXBy:10.0 yBy:10.0]; |
[xform concat]; |
[item1 draw]; |
//Draw item 2 |
[xform translateXBy:5.0 yBy:0.0]; // Translate relative to the previous element. |
[xform concat]; |
[item2 draw]; |
Помните, что предыдущие методы используются в случаях, где Вы не хотите изменять свои исходные элементы непосредственно. Какао обеспечивает способы изменить геометрические координаты, не изменяя текущую матрицу преобразования. Для получения дополнительной информации посмотрите Координаты Преобразования.
Также стоит отметить, что эффективность обратного преобразования ограничивается математической точностью. Поскольку вращение преобразовывает, которые включают синусы взятия и косинусы желаемого угла вращения, обратное преобразование может не быть достаточно точным для отмены исходного вращения полностью. В такой ситуации можно хотеть просто сохранить и восстановить состояние графики для отмены преобразования.
Преобразование координат
Если Вы не хотите изменять систему координат текущей среды получения, но действительно хотите сменить положение или ориентацию отдельного объекта, у Вас есть несколько опций. NSAffineTransform
класс включает transformPoint:
и transformSize:
методы для изменения координаты оценивают непосредственно. Используя эти методы не изменяет CTM текущего графического контекста.
Если Вы хотите изменить координаты по пути, можно сделать настолько использующий transformBezierPath:
метод NSAffineTransform
. Этот метод возвращает преобразованную копию указанного объекта контуров Безье. Этот метод отличается немного от transformUsingAffineTransform:
метод NSBezierPath
, который изменяет исходный объект.
Преобразование из окна для просмотра координат
События, отправленные в Ваше представление операционной системой, отправляются с помощью системы координат окна. Прежде чем Ваше представление может использовать любые координатные значения, включенные с событием, оно должно преобразовать те координаты в свое собственное пространство локальной координаты. NSView
класс обеспечивает несколько функций для упрощения преобразования NSPoint
, NSSize
, и NSRect
структуры. Среди этих методов convertPoint:fromView:
и convertPoint:toView:
, которые преобразовывают точки в и от системы локальной координаты представления. Для полного списка методов преобразования см. Ссылку класса NSView.
Следующий пример преобразовывает расположение мыши события от нажатия мыши от координат окна до координат локального представления. Для преобразования в пространство локальной координаты представления Вы используете convertPoint:fromView:
метод. Второй параметр к этому методу указывает представление, в системе координат которого в настоящее время указывается точка. Указание nil
поскольку второй параметр говорит текущему представлению преобразовывать точку из системы координат окна.
NSPoint mouseLoc = [theView convertPoint:[theEvent locationInWindow] fromView:nil]; |
Зеркально отраженные системы координат
Одной темой, часто подходящей в Какао и Кварце, является использование зеркально отраженных систем координат для рисования. По умолчанию Какао использует стандартную Декартову систему координат, где положительные значения расширяются и направо от источника. Возможно, однако, «зеркально отразить» систему координат, так, чтобы положительные значения расширились вниз и направо от источника, и сам источник расположен в верхний левый угол текущего представления или окна, как показано на рисунке 3-8.
Зеркальное отражение системы координат может сделать получение проще в некоторых ситуациях. Текстовые системы в определенном использовании зеркально отразили координаты для упрощения размещения текстовых строк, вытекающих от начала до конца в большинстве систем письменности. Несмотря на то, что Вы призваны использовать стандартную Декартову (незеркально отраженную) систему координат, когда это возможно, можно использовать зеркально отраженные координаты, если выполнение так проще поддерживать в коде.
Конфигурирование представления для использования зеркально отраженных координат влияет только на содержание, которое Вы рисуете непосредственно в том представлении. Зеркально отраженные системы координат не наследованы дочерними представлениями. Содержание, которое Вы рисуете в представлении, однако, должно быть ориентировано правильно на основе текущей ориентации представления. Сбой принять во внимание ориентацию текущего представления может привести к неправильно расположенному содержанию или содержанию, которое перевернуто.
Следующие разделы предоставляют информацию о поддержке Какао зеркально отраженных координат и некоторые проблемы, с которыми можно встретиться при использовании зеркально отраженных систем координат. Везде, где возможно, эти разделы также предлагают руководство о том, как решить проблемы, возникающие вследствие зеркально отраженных систем координат.
Конфигурирование представления для Использования зеркально отраженных координат
Первый шаг, который необходимо сделать для реализации зеркально отраженных координат, должен решить ориентацию по умолчанию представления. Если Вы предпочитаете использовать зеркально отраженные координаты, существует два способа сконфигурировать систему координат Вашего представления до получения:
Переопределите свое представление
isFlipped
метод и возвратYES
.Примените зеркально отраженное преобразование к своему содержанию сразу до рендеринга.
Если Вы планируете нарисовать все содержание своего представления использование зеркально отраженных координат, переопределяя представление isFlipped
метод является безусловно предпочтительным вариантом. Переопределение этого метода позволяет Какао знать, что Ваше представление хочет использовать зеркально отраженные координаты по умолчанию. Когда представление isFlipped
возвраты метода YES
, Какао автоматически вносит несколько корректировок для Вас. Самое значимое изменение - то, что Какао добавляет, что надлежащее преобразование преобразовывает к CTM прежде, чем вызвать Ваше представление drawRect:
метод. Это поведение избавляет от необходимости Ваш код для прорисовки применять зеркально отраженное преобразование вручную. Кроме того, много объектов Какао автоматически корректируют свой код для прорисовки для учета системы координат текущего представления. Например, NSFont
объект автоматически принимает ориентацию во внимание системы координат при установке текущего шрифта. Это препятствует тому, чтобы текст казался перевернутым, когда нарисовано в Вашем представлении.
При рисовании только подмножества содержания представления использование зеркально отраженных координат можно использовать зеркально отраженное преобразование (вместо переопределения isFlipped
) изменить систему координат вручную. Зеркально отраженное преобразование позволяет Вам скорректировать текущую систему координат временно и затем отменить ту корректировку, когда это больше не необходимо. Вы применили бы это преобразование к системе координат своего представления сразу до рисования соответствующего зеркально отраженного содержания. Для получения информации о том, как создать зеркально отраженное преобразование, посмотрите Создание Зеркально отраженного Преобразования.
Рисование содержания в зеркально отраженной системе координат
Большая часть работы, которую Вы выполняете для поддержки зеркально отраженных координат, происходит в коде для прорисовки приложения. Если Вы приняли решение использовать зеркально отраженные координаты в определенном представлении, возможности - оно, был то, потому что оно сделало Ваш код для прорисовки проще реализовать. Рисование в зеркально отраженной системе координат требует Вас к элементам позиции по-другому относительно экрана, но является иначе довольно прямым. Следующие разделы обеспечивают некоторые подсказки, чтобы помочь Вам гарантировать, что любое представленное содержание появляется способ, которым Вы хотите его.
Рисование примитивов фигур
Нет никаких реальных проблем с рисованием примитивов фигур в зеркально отраженных системах координат. Примитивы фигур, такие как прямоугольники, овалы, дуги и Кривые Безье могут быть нарисованы столь же легко в зеркально отраженных или незеркально отраженных системах координат. Единственные различия между этими двумя системами координат - то, где формы расположены и их вертикальная ориентация. Разметка Ваших форм заранее для определения их координатных точек должна решить любую ориентацию, выпускает Вас обнаружение.
Рисование с функциями набора приложения
Платформа Набора Приложения содержит многочисленные функции для того, чтобы быстро нарисовать определенное содержание. Среди этих функций NSRectFill
, NSFrameRect
, NSDrawGroove
, NSDrawLightBezel
, и т.д. При рисовании с этими функциями Какао принимает во внимание ориентацию целевого представления. Таким образом, если Ваше использование представления зеркально отразило координаты, эти функции продолжают представлять правильно в том зеркально отраженном координатном пространстве.
Рисование изображений
При рендеринге изображений в пользовательских представлениях необходимо обратить внимание на относительную ориентацию представления и любых изображений, которые Вы рисуете в том представлении. Если Вы рисуете изображение в зеркально отраженном представлении с помощью drawInRect:fromRect:operation:fraction:
метод, Ваше изображение казалось бы перевернутым в Вашем представлении. Вы могли решить эту проблему с помощью одного из нескольких методов:
Вы могли сразу применить зеркально отраженное преобразование до рисования изображения; посмотрите Создание Зеркально отраженного Преобразования.
Вы могли использовать один из
compositeToPoint
методыNSImage
сделать получение.Вы могли инвертировать сами данные изображения. (Несмотря на то, что подходящая фиксация, это обычно не очень практично.)
Используя зеркально отраженное преобразование для отрицания эффектов зеркально отраженного представления гарантирует, что содержимые изображения представляются правильно во всех случаях. Этот метод сохраняет любые предыдущие трансформации к системе координат, включая масштабы и вращения, но удаляет инверсию, вызванную зеркально отражаемым представлением. Если необходимо было нарисовать изображение с помощью, необходимо особенно использовать этот метод drawInRect:fromRect:operation:fraction:
метод NSImage
. Этот метод позволяет Вам масштабировать свое изображение для адаптации целевому прямоугольнику и является одним из более обычно используемых методов рисования для изображений.
Несмотря на то, что compositeToPoint
методы NSImage
предоставьте Вам способ ориентировать изображения должным образом без зеркально отраженного преобразования, их использование не рекомендуется. Существуют некоторые побочные эффекты, делающие получение с этими методами более сложным. compositeToPoint
методы работают путем удаления любых пользовательских факторов масштабирования или вращения, что Вы применились к CTM. Эти методы также удаляют любое масштабирование (но не переводы) примененный любым зеркальным отражением преобразовывает, было ли преобразование предоставлено Вами или Какао. (Методы также не удаляют масштабный коэффициент в действительности из независимости разрешения.) Любые пользовательские факторы перевода Вы применились к CTM, сохраняются, как бы то ни было. Несмотря на то, что это поведение разработано, чтобы гарантировать, что изображения не отсекаются ограничительным прямоугольником Вашего представления, если Вы не компенсируете фактор перевода зеркально отраженного преобразования, отсечение может все еще произойти.
Рисунок 3-9 показывает то, что происходит, когда Вы представляете изображение в незеркально отраженном представлении, и затем в зеркально отраженном представлении, с помощью compositeToPoint:fromRect:operation:
метод. В незеркально отраженном представлении изображение представляет как ожидалось в указанной точке в представлении. В зеркально отраженном представлении удален масштабный коэффициент для оси y, но фактор перевода не, который приводит к изображению, отсекаемому, потому что это появляется частично вне видимых границ представления. Для компенсации необходимо было бы скорректировать y-источник изображения путем вычитания исходного значения из высоты представления для получения скорректированной позиции.
Проблемы, связанные с получением изображений в зеркально отраженной системе координат, чрезвычайно независимы от того, как Вы создаете те изображения во-первых. Изображения используют отдельную систему координат внутренне для ориентации данных изображения. Загружаете ли Вы данные изображения из существующего файла или создаете изображение путем блокировки внимания на него, как только данные изображения загружаются, или Вы разблокировали фокус, данные изображения установлены. В той точке необходимо выбрать надлежащий метод рисования или скорректировать систему координат сами до рисования для исправления для зеркально отраженных проблем ориентации.
Для получения дополнительной информации об изображениях и их внутренних системах координат, посмотрите Системы координат Изображения.
Рисование текста
Текст, представляющий средства в Какао, берет их сигналы для текстовой ориентации от текущего представления. Если Ваше представление isFlipped
возвраты метода YES
, Какао автоматически инвертирует текст, составленный в том представлении для компенсации его зеркально отраженную систему координат. При применении зеркально отраженного преобразования вручную от кода для прорисовки, однако, Какао не знает для компенсации при рисовании текста. Любой текст, который Вы представляете после применения зеркально отраженного преобразования вручную поэтому, кажется перевернутым в Вашем представлении. Эти правила применяются, используете ли Вы текстовую систему Какао или средства получения NSString
составлять Ваш текст.
Если Вы блокируете внимание на изображение и вовлекаете некоторый текст в него, Какао использует внутреннюю систему координат NSImage
объект определить корректную ориентацию для текста. Как с другим содержимым изображения при последующем рендеринге изображения в зеркально отраженном представлении, текст Вы нарисовали, зеркально отражается вместе с остальной частью данных изображения.
Для получения дополнительной информации о работе с текстом, см. текст.
Создание зеркально отраженного преобразования
Если Вы хотите зеркально отразить систему координат своего представления временно, можно создать зеркально отраженное преобразование и применить его к текущему графическому контексту. Зеркально отраженное преобразование NSAffineTransform
объект сконфигурировал с двумя трансформациями: трансформация масштаба и переводить трансформация. Зеркально отраженное преобразование работает путем зеркального отражения направления оси y (использующий трансформацию масштаба) и затем переводящий источник в вершину представления.
Перечисление 3-1 показывает a drawRect:
метод, создающий зеркально отраженное преобразование и применяющий его к текущему контексту. Зеркально отраженное преобразование, показанное здесь, переводит источник сначала прежде, чем изменить направление вертикальной оси. Вы могли также реализовать это преобразование путем инвертирования вертикальной оси сначала и затем перевода источника в отрицательном направлении — т.е. использования отрицаемого значения высоты кадра.
Перечисление 3-1 , Зеркально отражающее систему координат вручную
- (void)drawRect:(NSRect)rect |
{ |
NSRect frameRect = [self bounds]; |
NSAffineTransform* xform = [NSAffineTransform transform]; |
[xform translateXBy:0.0 yBy:frameRect.size.height]; |
[xform scaleXBy:1.0 yBy:-1.0]; |
[xform concat]; |
// Draw flipped content. |
} |
Зеркально отраженное преобразование просто переключает ориентацию текущей системы координат. Если Ваше представление уже рисует использование зеркально отраженные координаты, потому что isFlipped
возвраты метода YES
, применение зеркально отраженного преобразования возвращается система координат назад к стандартной ориентации.
Использование какао зеркально отраженных координат
Некоторые классы Какао по сути поддерживают зеркально отраженные координаты, и некоторые не делают. При использовании неизмененных представлений Какао и средств управления в пользовательском интерфейсе он не должен иметь значения для кода ли то использование представлений и средств управления зеркально отраженные координаты. Если Вы разделяете на подклассы, однако, важно знать ориентацию системы координат. Следующие средства управления и представления в настоящее время используют зеркально отраженные координаты по умолчанию:
Некоторая поддержка классов Какао зеркально отразила координаты, но не используйте их все время. Следующий список включает известные случаи, где поддержка зеркально отраженной координаты зависит от других факторов смягчения.
Изображения не используют зеркально отраженные координаты по умолчанию; однако, можно зеркально отразить внутреннюю систему координат изображения вручную с помощью
setFlipped:
методNSImage
. Все представленияNSImage
возразите используют ту же ориентацию. Для получения дополнительной информации об изображениях и зеркально отраженных координатах, посмотрите Системы координат Изображения.Текстовая система Какао берет сигналы от текущего контекста, чтобы определить, должен ли быть зеркально отражен текст. Если текст должен быть выведен на экран в
NSTextView
объект, текстовые системные объекты (такой какNSFont
) также использование зеркально отразило координаты, чтобы гарантировать, что текст представляется правой стороной. При рисовании текста в пользовательском представлении, что координата стандарта использования, текстовые системные объекты не используют зеркально отраженные координаты.NSClipView
объект определяет, использовать ли зеркально отраженные координаты путем рассмотрения системы координат его представления документа. Если использование представления документа зеркально отразило координаты, представление клипа - также. Используя ту же систему координат гарантирует, что источник прокрутки соответствует источник границ представления документа.Графические функции удобства, такие как объявленные в
NSGraphics.h
, примите зеркально отраженные системы координат во внимание при рисовании. Для получения информации о доступных графических функциях удобства посмотрите Ссылку Функций AppKit.
Поскольку новые средства управления и представления представлены в Какао, те объекты могут также поддерживать зеркально отраженные координаты. Проверьте документацию ссылки класса на любые примечания разделения на подклассы по тому, поддерживает ли класс зеркально отраженные координаты. Можно также вызвать представление isFlipped
метод во время выполнения, чтобы определить, использует ли это зеркально отраженные координаты.
Выполнение точного пикселем получения
Несмотря на то, что возможно создать приложения с помощью только представления, средства управления и изображения, предоставленные Какао, приложениям свойственно использовать одно или более пользовательских представлений или изображения. И несмотря на то, что Какао обеспечивает поведение по умолчанию для разметки пользовательского содержания, существует много раз, когда можно хотеть скорректировать позицию отдельных представлений или изображений для предотвращения визуальных артефактов. Это - особенно истина при мозаичном размещении или рисовании растровых изображений на устройствах с высокой разрешающей способностью (таких как принтеры) или устройствах, где разрешение независимые масштабные коэффициенты имеет силу.
Следующие разделы обеспечивают инструкции и практический совет для того, как предотвратить визуальные артефакты, которые могут произойти во время получения с высокой разрешающей способностью. Для получения дополнительной информации о независимости разрешения и как адаптировать Ваш код для поддержки различных масштабных коэффициентов, см. Инструкции по Высокому разрешению для OS X.
Подсказки для разрешения независимое получение в какао
Приложения какао обеспечивают огромную сумму поддержки рендеринга к устройствам с высокой разрешающей способностью. Несмотря на то, что большая часть этой поддержки является автоматической, все еще необходимо выполнить некоторую работу, чтобы гарантировать, что содержание выглядит хорошим. Следующий список включает некоторые подходы для взятия при разработке интерфейса:
Используйте изображения с высокой разрешающей способностью.
Во время расположения удостоверьтесь, представления и изображения расположены на интегральные границы пикселей.
Когда создание разместило фоновые изображения рядом для пользовательских элементов управления, используйте
NSDrawThreePartImage
иNSDrawNinePartImage
методы для рисования фона вместо того, чтобы пытаться нарисовать его самостоятельно.Используйте сглаженные текстовые режимы рендеринга для неинтегральных масштабных коэффициентов и обязательно разметьте Ваши текстовые представления о границах пикселей.
Протестируйте свои приложения с неинтегральными масштабными коэффициентами такой как 1,25 и 1.5. Эти факторы имеют тенденцию генерировать нечетные числа пикселей, которые могут показать потенциальные пиксельные трещины.
При использовании OpenGL для рисования необходимо также знать это в OS X v10.5, ограничительный прямоугольник представления, вовлеченного NSOpenGLContext
измеряется в пикселях а не в точках (как это находится в не ситуации OpenGL). Эта поддержка может измениться в будущем, однако, таким образом, разработчики OpenGL, несомненно, должны будут преобразовать координаты непосредственно с помощью координатных методов преобразования NSView
. Например, следующий код преобразования для объекта представления, как гарантируют, возвратит правильные значения, необходимые OpenGL.
NSSize boundsInPixelUnits = [self convertRect:[self bounds] toView:nil]; |
glViewport(0, 0, boundsInPixelUnits.size.width, boundsInPixelUnits.size.height); |
Для получения дополнительной информации о независимости разрешения и как это влияет на представленное содержание, см. Инструкции по Высокому разрешению для OS X.
Доступ к текущему масштабному коэффициенту
Знание текущего масштабного коэффициента может помочь Вам принять решения относительно того, как лучше всего представить Ваше содержание. NSWindow
и NSScreen
классы оба включают a userSpaceScaleFactor
метод, который можно вызвать для получения текущего масштабного коэффициента, если таковые имеются, для приложения. В OS X v10.5 и ранее, этот метод обычно возвращается 1.0, указывая, что пространство пользователя и пространство устройства имеют то же разрешение (где одна точка равняется одному пикселю). В некоторый момент, хотя, этот метод может возвратить значение, которое больше, чем 1,0. Например, в то время как значение 2,0 укажет разрешение экрана 144 точек на дюйм, значение 1,25 указало бы разрешение экрана приблизительно 90 точек на дюйм.
Если Вы хотите знать фактическое разрешение определенного экрана, NSScreen
класс включает информацию о разрешении дисплея в его словаре описания устройства (получил доступ к использованию deviceDescription
метод). Можно использовать эту информацию (вместо того, чтобы умножить масштабные коэффициенты) для определения надлежащего разрешения для использования для изображений.
Корректировка расположения содержания
Поскольку экраны являются устройствами относительно с низкой разрешающей способностью, рисующие незначительные сбои часто более примечательны на экране, чем они находятся на устройствах более высокого разрешения, таких как принтеры. Рисование незначительных сбоев может произойти при рендеринге содержания в пути, требующем, чтобы тонкая настройка соответствовала базовые пиксели, отправленные в экран. Например, изображения и формы, продвинутые, неграницы пикселей могли бы потребовать искажения и поэтому могли бы появиться меньше хрустящего картофеля, чем нарисованные точно на границах пикселей. Кроме того, масштабируя изображение для вписывания разного размера область требует интерполяции, которая может представить артефакты и зернистость.
Несмотря на то, что проблемы пиксельного выравнивания могут произойти на любой версии OS X, они, более вероятно, произойдут, когда операционная система изменяется на независимость разрешения поддержки. Под независимостью разрешения модули в пользовательском координатном пространстве и координатном пространстве устройства больше не требуются, чтобы поддерживать непосредственные отношения. Для экранов с высокой разрешающей способностью это означает, что единый блок в пространстве пользователя может быть поддержан многократными пикселями в пространстве устройства. Таким образом, даже если Ваши координаты пространства пользователя падают на границы встроенного блока, они могут все еще быть неправильно выровнены в пространстве устройства. Присутствие дополнительных пикселей может также привести к пиксельным трещинам, происходящим, когда неправильно выровненные формы оставляют маленькие разрывы, потому что они не заполняют намеченную область получения полностью.
Если Ваши изображения или формы не рисуют способ, которым Вы ожидаете, или если Ваше графическое содержание выводит на экран доказательство пиксельных трещин, можно удалить многие из этих проблем путем корректировки координаты, оценивает Вас использование для рисования содержания. Если бы текущий масштабный коэффициент 1.0, но требовался бы для других масштабных коэффициентов, следующие шаги не требуются.
Преобразуйте точку пространства пользователя, размер, или прямоугольник оценивает координатам пространства устройства.
Нормализуйте значение в пространстве устройства так, чтобы это было выровненное к надлежащей границе пикселей.
Преобразуйте нормализованное значение назад в пространство пользователя.
Нарисуйте свое содержание с помощью скорректированного значения.
Лучший способ получить корректный прямоугольник пространства устройства состоит в том, чтобы использовать centerScanRect:
метод NSView
. Этот метод берет прямоугольник в координатах пространства пользователя, выполняет необходимые вычисления для корректировки позиции прямоугольников на основе текущего масштабного коэффициента и устройства, и возвращает получающийся прямоугольник пространства пользователя. Для расположения можно также использовать методы, описанные в Преобразовании Координатных Значений.
Если Вы хотите больше управления точным расположением элементов в пространстве устройства, можно также скорректировать координаты сами. OS X обеспечивает несколько функций для нормализации координатных значений, как только они находятся в пространстве устройства, включая NSIntegralRect
и CGRectIntegral
функции. Можно также использовать ceil
и floor
функции в math.h
округлять в большую сторону координаты пространства устройства или вниз по мере необходимости.
Преобразование координатных значений
В OS X v10.5, несколько методов были добавлены к NSView
упростить преобразование между координатами пространства пользователя и пространства устройства:
Эти удобные методы позволяют преобразовать значения в и от основы (устройство) система координат. Они принимают во внимание текущую конфигурацию запоминающего устройства для представления, включая то, поддерживается ли это уровнем.
Изменить координатные значения NSPoint
структура, начало Вашего представления drawRect:
метод мог бы иметь код, подобный следующему:
- (void)drawRect:(NSRect)rect |
{ |
NSPoint myPoint = NSMakePoint(1.0, 2.0); |
CGFloat scaleFactor = [[self window] userSpaceScaleFactor]; |
if (scaleFactor != 1.0) |
{ |
NSPoint tempPoint = [self convertPointToBase:myPoint]; |
tempPoint.x = floor(tempPoint.x); |
tempPoint.y = floor(tempPoint.y); |
myPoint = [self convertPointFromBase:tempPoint]; |
} |
// Draw the content at myPoint |
} |
Вам решать для определения, какая функция нормализации подходит лучше всего для кода для прорисовки. Предыдущий пример использует floor
функция для нормализации источника данной формы, но Вы могли бы использовать комбинацию floor
и ceil
в зависимости от позиции другого содержания в Вашем представлении.