所以平移矩阵:
旋转矩阵
v(x, y) 点绕原点旋转θ到v'(x', y')
则有:
x = r * cos(? )
y = r * sin(? )
x' = r * cos(θ + ?) = r * cos(θ) * cos(?) - r * sin(θ) * sin(? ) // 余弦公式
y' = r * sin(θ + ?) = r * sin(θ) * cos(?) + r * cos(θ) * sin(? ) // 正弦公式
所以:
x' = x * cos(θ) - y * sin(θ)
y' = x * sin(θ) + y * cos(θ)
所以旋转矩阵:
伸缩矩阵
假设x轴,y轴的伸缩率分别是kx, ky。 则有:
x' = x * kx
y' = y * ky
所以:
复合变换
如果是对p(x, y)先平移(变换矩阵A), 然后旋转(变换矩阵B), 然后伸缩(变换矩阵C)呢?
p' =C(B(Ap)) ==> p' = (CBA)p //矩阵乘法结合率
现在任意角度o的箭头就很简单了:
先把p旋转45度 成为 菱形, 变换为 M1 伸缩x轴, y轴 :
x' = size * cos(o/2) = x * √2 * cos(o/2) y' = size * sin(o/2) = y * √2 * sin(o/2)
即: kx = √2 * cos(o/2); ky = √2 * sin(o/2) 这样就得到了任意角度的箭头。 变换为 M2
如果箭头的方向不是指向右侧, 在进行一次旋转就可以得到任意方向的箭头。变换为 M3
那么由于 p' =C(B(Ap)) ==> p' = (CBA)p
, 我们就可以先计算出 M3 M2 M1,然后对p进行相应的变换,就可以得到任意角度, 任意方向的箭头了。
p的width和height就是箭头的边长, 通过调整可以获取任意边长的箭头。
React组件
为了方便使用, 这个箭头被封装为了一个 React组件。
示例
简单箭头
模拟select
发散箭头
props
name | type | default | description |
---|---|---|---|
degree | number | 90 | 箭头的张角, 角度制 |
offsetDegree | number | 0 | 箭头的方向,默认指向右边 |
color | string | - | 箭头的颜色 |
size | string | 10px | 箭头边长 |
安装使用
npm install rc-arrow --save
import Arrow from 'rc-arrow' class Hw extends Component { render() { return ( <Arrow size="20px" color="red"/> ) } }