@logicflow/core
Version:
LogicFlow, help you quickly create flowcharts
66 lines (65 loc) • 2.04 kB
JavaScript
import { distance } from './node';
var SAMPLING_FREQUENCY = 100;
var normal = {
x: 1,
y: 0,
z: 0,
};
// 采样三次贝塞尔曲线上的点, 假设采样频率为SAMPLING_FREQUENCY, 取倒数第1-6/SAMPLING_FREQUENCY个点即t=1-6/SAMPLING_FREQUENCY
export function sampleCubic(p1, cp1, cp2, p2, offset) {
var program = function (t) {
if (t < 0 || t > 1) {
throw new RangeError('The value range of parameter "t" is [0,1]');
}
return {
x: p1.x * Math.pow((1 - t), 3) +
3 * cp1.x * t * Math.pow((1 - t), 2) +
3 * cp2.x * Math.pow(t, 2) * (1 - t) +
p2.x * Math.pow(t, 3),
y: p1.y * Math.pow((1 - t), 3) +
3 * cp1.y * t * Math.pow((1 - t), 2) +
3 * cp2.y * Math.pow(t, 2) * (1 - t) +
p2.y * Math.pow(t, 3),
};
};
// fix: https://github.com/didi/LogicFlow/issues/951
// 计算贝塞尔曲线上与终点距离为offset的点,作为箭头的的垂点。
var arrowDistance = 0;
var t = 2;
var x1 = p2.x, y1 = p2.y;
var point = p2;
while (arrowDistance < offset && t < 50) {
point = program(1 - t / SAMPLING_FREQUENCY);
var x2 = point.x, y2 = point.y;
arrowDistance = distance(x1, y1, x2, y2);
t++;
}
return point;
}
function crossByZ(v, v1) {
return v.x * v1.y - v.y * v1.x;
}
function dot(v, w) {
var v1 = [v.x, v.y, v.z];
var v2 = [w.x, w.y, w.z];
return v2.reduce(function (prev, cur, index) { return prev + cur * v1[index]; });
}
function angle(v1, v2) {
var negative = crossByZ(v1, v2);
var r = Math.acos(dot(normalize(v1), normalize(v2)));
return negative >= 0 ? r : -r;
}
function normalize(v) {
var len = Math.hypot(v.x, v.y);
return {
x: v.x / len,
y: v.y / len,
z: 0,
};
}
export function getThetaOfVector(v) {
return angle(normal, v);
}
export function degrees(radians) {
return radians * (180 / Math.PI);
}