vislite
Version:
灵活、快速、简单的数据可视化交互式跨端前端库
66 lines (58 loc) • 2 kB
text/typescript
import type HermiteType from '../../types/Hermite'
class Hermite implements HermiteType {
readonly name: string = 'Hermite'
private __u: number // 张弛系数
private __MR: number[]
private __a: number
private __b: number
constructor(u: number = 0.5) {
this.__u = u
}
/**
* 设置点的位置
* @param {Number} x1 左边点的位置
* @param {Number} y1
* @param {Number} x2 右边点的位置
* @param {Number} y2
* @param {Number} s1 两个点的斜率
* @param {Number} s2
*/
setP(x1: number, y1: number, x2: number, y2: number, s1: number, s2: number) {
if (x1 < x2) {
// 记录原始尺寸
this.__a = x1
this.__b = x2
const p3 = this.__u * s1,
p4 = this.__u * s2
// 缩放到[0,1]定义域
y1 /= (x2 - x1)
y2 /= (x2 - x1)
// MR是提前计算好的多项式通解矩阵
// 为了加速计算
// 如上面说的
// 统一在[0,1]上计算后再通过缩放和移动恢复
// 避免了动态求解矩阵的麻烦
this.__MR = [
2 * y1 - 2 * y2 + p3 + p4,
3 * y2 - 3 * y1 - 2 * p3 - p4,
p3,
y1
]
} else throw new Error('The point x-position should be increamented!')
return this
}
/**
* 根据x值返回y值
* @param {Number} x
*/
use(x: number) {
if (this.__MR) {
const sx = (x - this.__a) / (this.__b - this.__a),
sx2 = sx * sx,
sx3 = sx * sx2
const sResult = sx3 * this.__MR[0] + sx2 * this.__MR[1] + sx * this.__MR[2] + this.__MR[3]
return sResult * (this.__b - this.__a)
} else throw new Error('You shoud first set the position!')
}
}
export default Hermite