Skip to content
Alexander Slis edited this page Mar 3, 2017 · 3 revisions

Автоморфизм это преобразование из себя в себя. авто = "себя" морфизм = "преобразование". Соответственно автоморфизм действительной оси - это преобразования, которые каждой точке оси сопоставляют какую-то точку той же оси.

viewZoomTransform.ts

class AR1

m - хранит преобразование, хранит аффинный автоморфизм действительной оси (OX или OY) в виде матрицы 2 х 1.

На языке координат у нас преобразование такое: x' = a * x + b и m хранит числа a и b.

Но полезно думать абстрактно что это преобразование и есть, без какой-то внутренней структуры.

m преобразет x в x'.

m' преобразует x' в x''.

m.composeWith(m') преобразует x в x''.

affine.maxima - как это выглядит на языке координат (http://maxima-online.org/).

composeWith - эта функция типа суммы автоморфизмов, преобразует два автоморфизма в третий. Композиция автоморфизмов - это автоморфизм, эквивалентный последовательному применению двух автоморфизмов. Т.е. берем точку и применяем к ней первый автоморфизм, получаем точку и применяем второй получаем вторую точку. А композиция это такой автоморфизм который из первой точки последнюю за 1 шаг получает. И полезно думать что автоморфизмы работают не с отдельными точками а со всеми точками оси сразу, т.е. с осями функции из осей в оси.

Одномерное аффинное пространство - это такое просторанство, для задания аффинных автоморфизмов которого достаточно 2*(N+1) точек. То есть например если у нас только сдвиги, то сдвиг однозначно определяется парой точек, то есть пространство сдвигов нульмерное, функция инверс по автоморфизму получает обратный. У нас есть преобразование из модельных координат в экранные. Применяя к нему inverse мы получаем преобразование из экранных в модельные. Это используется для получения индексов, соответствующих крайнему левому и крайнему правому пикселю.

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

О базисах полезно думать как об опорных точках. Преобразование между шкалами Цельсия и Фаренгейта требует 4 опорных точек. Например тепература кипения воды в цельсиях и температура замерзания в цельсиях образует базис. И те же самые точки но в фаренгейтах тоже образуют базис. И двух базисов (соответствия между 2 парами точек - первая точка первой пары соответствует первой точке второй как температура кипения соотвествует температуре кипения) нам достаточно для определения преобразования. Например у нас базисами являются (0, data.length - 1) и (0, width).

Для задания автоморфизма мы используем две пары точек, два базиса. А в каждом базисе по N+1 точек. Т.е. нам нужно внутри каждой "шкалы" по N+1 точек, а всего 2 (N+1).

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

viewPortPointsX это края вьюпорта по Х на экране, то есть в экранном аффинном пространстве, a viewWindowX это соответствующие им точки, края вьюпорта по Х но в модельном аффинном пространстве.

ViewPort - это экранные координаты, а ViewWindow - модельные.

this.viewPortPointsX = bScreenXVisible
this.viewPortPointsY = bScreenYVisible

Но следует думать не как о координатах а как о пространствах. Экранное аффинное пространство по Х и модельное аффинное пространство по Х. Вспомним что преобразования между пространствами задаются парой базисов. Соответственно у нас есть по Х два пространства, две пары базисов и одно преобразование между ними. А каждый базис состоит из 2 точек а каждая точка из 1 координаты. Такая матрешка абстракций, но нам следует работать на верхнем уровне пространств, базисов и преобразований. Т.е. временно забыть о внутренностях. bScreenXVisible лучше отражает суть. b = basis, screen = basis in screen space (есть ещё model space), X - по Х (есть ещё Y), visible = видимая область (есть ещё full - полная область).

onViewPortResize следует понимать как перемещение опорных точек в экранном пространстве. Мы не задаем ширину числом мы задаем крайние точки точками. Эти опорные точки естественно как-то двигаются в двух экранных аффинных пространствах когда мы меняем размеры окна. Считай что мы переопределили шкалу цельсия, теперь у нас опорные точки не температура кипения и замерзания воды, а температура плавления ртути и горения бумаги. У нас опорные точки это края. Левый и правый в пространствах по Х и верхний и нижний в пространствах по Y.


Есть 3 пространства и 2 матрицы между ними:

Пространство точки. Центр 0, правый край 1

A

Экранное пространство. Центр сx, правый край cx + r

B

Модельное пространство

Матрица А рассчитывается по двум парам базисов выше (по x и по y)

Матрица B уже есть готовая, см. внутрь fromScreenToModel

Вариант с компенсацией:

Точка "внутри" .view. Надо посчитать матрицу C = A * B и установить её трансформацией точки. Так что она будет транслировать из из (0, 1) в модельные, а дальше текущая трансформация .view трансформирует модельные в экранные.

Вариант без компенсации:

Точка "снаружи" view. Установить матрицу A трансформацией точки.