JavaScript. Подробное руководство, 6-е издание, стр. 360

Метод

<b>setTransform()</b>
позволяет напрямую определять матрицу преобразований холста, но обычно преобразования системы координат проще определять как последовательность операций смещения, вращения и масштабирования. Влияние этих операций на систему координат холста иллюстрируются на рис. 21.7. Программа, с помощью которой был получен этот рисунок, семь раз подряд использовала одно и то же изображение осей координат. Единственное, что изменялось каждый раз, - это текущее преобразование. Обратите внимание, что преобразования оказывают влияние не только на рисование линий, но и на вывод текста.

Метод

<b>translate()</b>
просто смещает начало системы координат влево, вправо, вверх или вниз. Метод
<b>rotate()</b>
выполняет вращение осей координат по часовой стрелке на указанный угол. (Прикладной интерфейс объекта
<b>Canvas</b>
всегда измеряет углы в радианах. Чтобы преобразовать градусы в радианы, необходимо разделить значение в градусах на 180 и умножить на
<b>Math.PI</b>
.) Метод
<b>scale()</b>
растягивает или сжимает расстояния по оси X или Y.

Передача отрицательного коэффициента масштабирования методу

<b>scale()</b>
переворачивает соответствующую ему ось относительно начала системы координат, создавая зеркальное ее отражение. Именно это преобразование можно наблюдать внизу слева на рис. 21.7: вызов метода
<b>translate()</b>
сместил начало координат в левый нижний угол холста, а вызов метода
<b>scale()</b>
перевернул ось Y так, что значения координаты Y стали увеличиваться в направлении снизу вверх. Такая перевернутая система координат должна быть знакома вам по школьному курсу алгебры, и она может пригодиться для рисования графиков и диаграмм. Отметьте, однако, что текст после такого преобразования очень трудно читать!

JavaScript. Подробное руководство, 6-е издание - i_059.jpg

21.4.4.1. Математический смысл преобразований

На мой взгляд, проще всего разбираться с преобразованиями, имея их геометрическое представление, когда действие методов

<b>translate(), rotate()</b>
и
<b>scale()</b>
можнo представить в виде преобразований координатных осей, как показано на рис. 21.7. Преобразования можно также представить алгебраически, в виде системы уравнений, отображающих координаты точки (х,у) в преобразованной системе координат в координаты той же точки (х',у') в исходной системе координат.

Вызов метода

<b>c.translate(dx,dy)</b>
можно описать следующими уравнениями:

<b>х' = х + dx; // Значение 0 координаты X в новой системе координат</b>

<b>             // соответствует значению dx в старой системе координат</b>

<b>у' = у + dy;</b>

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

<b>c.scale(sx.sy)</b>
можно описать следующим образом:

<b>х' = sx * х;</b>

<b>У' = sy * у;</b>

Операция вращения выглядит несколько сложнее. Вызов

<b>с.rotate(a)</b>
описывается следующими тригонометрическими уравнениями:

<b>х' = х * cos(a) - у * sin(a);</b>

<b>у’ = у * cos(a) + х * sin(a);</b>

Обратите внимание, что порядок выполнения преобразований имеет большое значение. Допустим, что изначально используется система координат холста по умолчанию, после чего выполняется смещение и затем масштабирование. Чтобы отобразить координаты точки (х,у) в текущей системе координат обратно в координаты (х",у") в системе координат по умолчанию, необходимо сначала применить уравнения масштабирования, чтобы отобразить координаты точки в промежуточные координаты (х',у') точки в смещенной, но не масштабированной системе координат, а затем применить уравнения смещения, чтобы отобразить эти промежуточные координаты точки в координаты (х",у"). В результате получим следующую систему уравнений:

<b>х'' = sx*x + dx; </b>

<b>у'' = sy*y + dy;</b>

Если же к исходной системе координат сначала применялся метод

<b>scale ()</b>
, а затем
<b>translate(),</b>
мы придем к другой системе уравнений:

<b>х&quot; = sx*(x + dx); </b>

<b>у&quot; = sy*(у + dy);</b>

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

Преобразования, поддерживаемые холстом, известны как аффинные преобразования. Аффинные преобразования могут изменять расстояния между точками и углы между линиями, но параллельные линии всегда остаются параллельными после любых аффинных преобразований - с помощью аффинных преобразований нельзя, например, создать эффект искажения типа «рыбий глаз». Любое аффинное преобразование можно описать с помощью шести параметров от а до f, как показано в следующих уравнениях:

<b>х' = ах + су + е</b>

<b>у' = bx + dy + f</b>

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

<b>transform()</b>
. На рис. 21.7 показаны два типа преобразований - сдвиг и вращение вокруг указанной точки - которые можно реализовать с помощью метода
<b>transfоrm()</b>
, как показано ниже:

<b>// Сдвиг:</b>

<b>//х' = х + кх*у;</b>

<b>//У' = У + ку*х;</b>

<b>function shear(c, кх, ку) { с.transform(1, ку, кх, 1, 0, 0); }</b>

<b>// Вращение на theta радиан по часовой стрелке вокруг точки (х,у). Это преобразование</b>