几种坐标系定义与坐标系转换
坐标系类型
坐标系 | 说明 | ID |
---|---|---|
空坐标系 | 空 | NULL |
画布坐标系 | 画布的绝对坐标系 | CAN |
组件坐标系 | 以组件布局中心为原点的绝对坐标系 | COM |
组件相对坐标系 | 以图形中心为原点,以图形矩形区域长宽为 [ − 1 , 1 ] [-1,1] [−1,1]的相对坐标系 | COMR |
点坐标系 | 以一点 a a a作为原点的绝对坐标系 | POI |
点相对坐标系 | 以一点 a a a作为原点,另一点 b b b作为 ( 1 , 1 ) (1,1) (1,1)的相对坐标系 | POIR |
向量坐标系 | 以一点 a a a作为原点, a b → \overrightarrow{ab} ab作为x轴的绝对坐标系 | VEC |
向量相对坐标系 | 以一点 a a a作为原点,另一点 b b b作为 ( 1 , 0 ) (1,0) (1,0)的相对坐标系 | VECR |
画布坐标系
表示各组件(包括图形和文字)在画布上的绝对位置。这里的画布并非指<canvas>组件,而是指一个虚拟存在的画布。组件通过布局被映射到画布,画布容纳了一个流程图中全部的组件。
画布坐标系没有参照物,是全局的绝对坐标系。原点、轴与刻度为全局的参考单位。(类似于世界坐标系)
组件坐标系
组件自身使用的坐标系。组件通过布局(Arrange)被映射到画布中(也可以反向映射)。其原点是布局中心,轴取决于布局旋转,刻度同画布坐标系。
组件坐标系的原点,就是布局的中心,也是旋转中心。并且组件在画布中的坐标,就是布局中心在画布中的坐标。它们的结果是一致的,但是范畴不同。
- 组件坐标系下:外接矩形中心、组件坐标系原点。
- 画布坐标系:布局中心、旋转中心、画布位置。
更新对布局的影响
-
内部更新(关键点、文字更新)
内部更新的直接更新对象是组件内部的图像或文字。内部更新中布局是间接更新对象,且不涉及旋转,只涉及移动。设布局旋转对应的从组件坐标系到画布坐标系的映射为 M M M.
设当前组件坐标系原点为 O = ( 0 , 0 ) O=(0,0) O=(0,0)。每次内部更新后,重新计算组件在组件坐标系下的外接矩形,随后得到一个外接矩形中心 O ′ O' O′。接下来令该中心为新的组件坐标系原点,即所有组件内部的svg整体移动 O ′ O → \overrightarrow{O'O} O′O。
布局中心始终与组件坐标系原点重新。因此上述更新使得组件在画布坐标系上来看,改变后仍然整体移动了 M × O ′ O → M×\overrightarrow{O'O} M×O′O。为了消除影响,需要更新布局,将布局移动 M × O O ′ → M×\overrightarrow{OO'} M×OO′。
-
布局更新(旋转、移动)
-
旋转
布局中心不变,只是改变组件中各svg到组件svg的线性变换方式。 -
移动
对布局中心,也就是画布位置简单地进行平移。也就是对两个分量进行数值加减。
-
组件相对坐标系
一种组件坐标系的变种,刻度以组件外接矩形的长宽映射为 [ − 1 , 1 ] [-1,1] [−1,1],原点与轴同组件坐标系。可以以坐标表示比例。
点坐标系
相对某点的坐标系,称该点为原点(origin)。轴与刻度同原点所处的坐标系。
点相对坐标系
点坐标系的变种。引入另外一点顶点(vertex),作为该坐标系中的(1,1),它必须与原点在同一坐标系下。此时可以以坐标表示比例。
向量坐标系
以某向量为基准的坐标系。其中起点 A A A为原点,向量方向 A B → ∣ A B ∣ \frac{\overrightarrow{AB}}{|AB|} ∣AB∣AB为x轴,刻度取决于向量所在的坐标系。
向量相对坐标系
向量坐标系的变种。其中 B B B表示(1,0)。此时可以以坐标表示比例。
空坐标系
引入空坐标系表示默认与错误。
坐标系转换
上述定义的各个坐标系间能实现两两相互转换,转换方式与参照物相关。
点属于一个坐标系,如果另一个坐标系又参考该点,则会出现一条链,这导致该坐标系转换到其他坐标系需要先进行化简,以及其他坐标系转换到该坐标系需要层层复合变换。将不以点为参照的坐标系称为点无关坐标系(Point Irrelevant Coordinate),以点为参照的坐标系称为点相关坐标系(Point Relevant Coordinate)。
点无关坐标系 PIC
参照物不涉及到点,我们直接使用其中的信息进行转换。
转换(只考虑组件和画布坐标系)
设组件的外接矩形长 w w w宽 h h h,布局中心的画布位置 o o o,布局旋转对应的变换为 M M M。
如果顺时针旋转角度为 θ \theta θ,则:
M = ( cos θ sin θ − sin θ cos θ ) M=\left(\begin{matrix}\cos{\theta}&\sin{\theta}\\-\sin{\theta}&\cos{\theta}\end{matrix}\right) M=(cosθ−sinθsinθcosθ)
- 画布坐标系到组件坐标系
p ′ = M − 1 ( p − o ) p'=M^{-1}(p-o) p′=M−1(p−o) - 组件坐标系到画布坐标系
p ′ = M p + o p'=Mp+o p′=Mp+o - 组件坐标系到组件相对坐标系
p ′ = p / ( w , h ) − ( w 2 , h 2 ) p'=p/(w,h)-(\frac{w}{2},\frac{h}{2}) p′=p/(w,h)−(2w,2h) - 组件相对坐标系到组件坐标系
p ′ = p ∗ ( w , h ) + ( w 2 , h 2 ) p'=p*(w,h)+(\frac{w}{2},\frac{h}{2}) p′=p∗(w,h)+(2w,2h)
点相关坐标系 PRC
以点为参照,坐标系转换时需要用到点的坐标系,因此只能向上化简或复合迭代。
坐标系链
对于该坐标系,以参照点的坐标系为父亲,知道某个点无关坐标系为根,可构成一条“点-坐标系”的链。仅考虑坐标系,得到一个单向的链。
于是坐标系变换存在两个方向:
- 向下:到子点相关坐标系。正变换。
- 向上:到父点相关坐标系或点无关坐标系。逆变换。
转换
对于向量坐标系,已知 A B → = ( a , b ) \overrightarrow{AB}=(a,b) AB=(a,b),则将x轴旋转为 A B → \overrightarrow{AB} AB方向的旋转矩阵为:
M = ( a − b b a ) / a 2 + b 2 M=\left(\begin{matrix}a&-b\\b&a\end{matrix}\right)/\sqrt{a^2+b^2} M=(ab−ba)/a2+b2
-
向下正变换
- 点坐标系
p ′ = p − o r i g i n p'=p - origin p′=p−origin - 点相对坐标系
p ′ = ( p − o r i g i n ) / ( v e r t e x − o r i g i n ) p'=(p - origin) / (vertex - origin) p′=(p−origin)/(vertex−origin) - 向量坐标系
p ′ = M − 1 ∗ ( p − A ) p'=M^{-1} * (p - A) p′=M−1∗(p−A) - 向量相对坐标系
p ′ = M − 1 ∗ ( p − A ) / ∣ A B ∣ p'=M^{-1} * (p - A) / |AB| p′=M−1∗(p−A)/∣AB∣
- 点坐标系
-
向上逆变换
- 点坐标系
p ′ = p + o r i g i n p'=p + origin p′=p+origin - 点相对坐标系
p ′ = p ∗ ( v e r t e x − o r i g i n ) + o r i g i n p'=p * (vertex - origin) + origin p′=p∗(vertex−origin)+origin - 向量坐标系
p ′ = M ∗ p + A p'=M * p + A p′=M∗p+A - 向量相对坐标系
p ′ = M ∗ p ∗ ∣ A B ∣ + A p'=M * p * |AB| + A p′=M∗p∗∣AB∣+A
- 点坐标系
相互转换逻辑
分四种情况讨论:
-
转化对象在PIC,目标是PIC
直接进行PIC转换,调用已经定义的转换函数。
-
转化对象在PIC,目标是PRC
先对转化对象到根进行PIC转换。再对PRC的坐标系链递归向下,反复使用向下正变换。
-
转化对象在PRC,目标是PIC
对转化对象的坐标系链递归向上,反复使用向上逆变换。最后进行PIC转换。
-
转化对象在PRC,目标是PRC
先递归向上,再递归向下。