和可视化 matrix 相关的函数,向量夹角、距离、变换等等。
计算两个二维向量之间的夹角。
- 计算两个二维向量之间的夹角
- 支持顺时针和逆时针方向的角度计算
- 使用 gl-matrix 库进行向量计算
- 返回弧度值(0 到 2π)
import { angleTo } from '@antv/util';
// 基本向量夹角
const v1: [number, number] = [1, 0];
const v2: [number, number] = [0, 1];
console.log(angleTo(v1, v2)); // π/2 (90度)
console.log(angleTo(v1, v2, true)); // 3π/2 (270度)
// 相同方向的向量
const v3: [number, number] = [1, 0];
const v4: [number, number] = [2, 0];
console.log(angleTo(v3, v4)); // 0
// 相反方向的向量
const v5: [number, number] = [1, 0];
const v6: [number, number] = [-1, 0];
console.log(angleTo(v5, v6)); // π (180度)
// 实际应用示例
function rotateVector(vector: [number, number], angle: number): [number, number] {
const cos = Math.cos(angle);
const sin = Math.sin(angle);
return [
vector[0] * cos - vector[1] * sin,
vector[0] * sin + vector[1] * cos
];
}
// 计算旋转后的向量夹角
const original: [number, number] = [1, 0];
const rotated = rotateVector(original, Math.PI / 4); // 旋转45度
console.log(angleTo(original, rotated)); // π/4 (45度)
| 参数 |
说明 |
类型 |
默认值 |
详细说明 |
| v1 |
第一个向量 |
[number, number] |
- |
起始向量 |
| v2 |
第二个向量 |
[number, number] |
- |
目标向量 |
| direct |
是否按逆时针方向计算 |
boolean |
false |
是否逆时针计算角度 |
| 参数 |
说明 |
类型 |
默认值 |
详细说明 |
| angle |
夹角弧度值 |
number |
- |
两个向量之间的夹角(0 到 2π) |
- 返回值是弧度制(0 到 2π)
- 默认顺时针方向计算角度
- direct 参数可以改变角度的计算方向
- 使用了 gl-matrix 库的 vec2.angle 计算基础角度
- 零向量可能导致计算结果不准确
计算两个向量之间夹角的方向(顺时针或逆时针)。
- 判断从向量 v1 到向量 v2 的旋转方向
- 使用向量叉积的方法计算方向
- 返回值大于等于 0 表示顺时针方向
- 返回值小于 0 表示逆时针方向
import { direction } from '@antv/util';
// 基本方向判断
const v1 = [1, 0];
const v2 = [0, 1];
console.log(direction(v1, v2)); // -1 (逆时针)
const v3 = [0, -1];
console.log(direction(v1, v3)); // 1 (顺时针)
// 共线向量
const v4 = [2, 0];
console.log(direction(v1, v4)); // 0 (共线)
// 实际应用示例
function getRotationDirection(startAngle: number, endAngle: number): string {
const start = [Math.cos(startAngle), Math.sin(startAngle)];
const end = [Math.cos(endAngle), Math.sin(endAngle)];
return direction(start, end) >= 0 ? '顺时针' : '逆时针';
}
// 测试不同角度的旋转方向
console.log(getRotationDirection(0, Math.PI / 2)); // '逆时针'
console.log(getRotationDirection(0, -Math.PI / 2)); // '顺时针'
// 在动画中使用
function animateRotation(element: HTMLElement, targetAngle: number) {
const currentVector = [1, 0];
const targetVector = [
Math.cos(targetAngle),
Math.sin(targetAngle)
];
const isClockwise = direction(currentVector, targetVector) >= 0;
// 根据方向选择最短路径旋转
element.style.transition = 'transform 1s';
element.style.transform = `rotate(${isClockwise ? '' : '-'}${targetAngle}rad)`;
}
| 参数 |
说明 |
类型 |
默认值 |
中文说明 |
| v1 |
第一个向量 |
number[] |
- |
起始向量 |
| v2 |
第二个向量 |
number[] |
- |
目标向量 |
| 参数 |
说明 |
类型 |
默认值 |
中文说明 |
| result |
方向判断值 |
number |
- |
>=0 表示顺时针,<0 表示逆时针 |
- 向量应该是二维的
- 返回值的正负表示旋转方向
- 返回值为 0 表示向量共线
- 计算基于向量叉积
- 坐标系采用数学标准坐标系(y 轴向上为正)
根据变换操作序列对矩阵进行变换。
- 支持平移(translate)、缩放(scale)、旋转(rotate)和矩阵乘法(multiply)操作
- 使用 gl-matrix 库进行矩阵运算
- 按顺序执行变换操作
- 支持初始矩阵输入
- 所有变换都是左乘方式进行
import { transform } from '@antv/util';
// 基本变换示例
const matrix = [1, 0, 0, 0, 1, 0, 0, 0, 1]; // 单位矩阵
// 平移变换
const translated = transform(matrix, [
['t', 100, 200] // 向右平移100,向下平移200
]);
// 缩放变换
const scaled = transform(matrix, [
['s', 2, 3] // x方向放大2倍,y方向放大3倍
]);
// 旋转变换
const rotated = transform(matrix, [
['r', Math.PI / 4] // 旋转45度
]);
// 组合变换
const combined = transform(matrix, [
['t', 100, 100], // 先平移
['r', Math.PI / 2], // 再旋转90度
['s', 2, 2] // 最后放大2倍
]);
// 实际应用示例
function createTransformMatrix(x: number, y: number, rotation: number, scale: number) {
return transform(null, [
['t', x, y],
['r', rotation],
['s', scale, scale]
]);
}
// 创建一个元素的变换矩阵
const elementTransform = createTransformMatrix(100, 100, Math.PI / 4, 2);
console.log(elementTransform);
// 应用到DOM元素
function applyMatrixToElement(element: HTMLElement, matrix: number[]) {
const cssMatrix = `matrix(${matrix[0]}, ${matrix[1]}, ${matrix[3]}, ${matrix[4]}, ${matrix[2]}, ${matrix[5]})`;
element.style.transform = cssMatrix;
}
| 参数 |
说明 |
类型 |
默认值 |
中文说明 |
| m |
初始矩阵 |
number[] |
[1,0,0,0,1,0,0,0,1] |
初始变换矩阵 |
| actions |
变换操作数组 |
any[][] |
- |
变换操作序列 |
| 参数 |
说明 |
类型 |
默认值 |
中文说明 |
| matrix |
变换后的矩阵 |
number[] |
- |
经过变换后的矩阵 |
| 操作符 |
说明 |
参数格式 |
示例 |
| t |
平移 |
['t', x, y] |
['t', 100, 200] |
| s |
缩放 |
['s', sx, sy] |
['s', 2, 3] |
| r |
旋转 |
['r', angle] |
['r', Math.PI/4] |
| m |
矩阵乘法 |
['m', matrix] |
['m', [1,0,0,0,1,0,0,0,1]] |
- 变换操作按数组顺序依次执行
- 所有变换都是左乘方式
- 旋转角度使用弧度制
- 矩阵使用 3x3 的形式存储
- 如果不提供初始矩阵,默认使用单位矩阵
计算二维向量的垂直向量。
- 计算给定二维向量的垂直向量
- 支持顺时针和逆时针方向的垂直向量计算
- 可以将结果存储在指定的数组中
- 返回垂直向量的引用
import { vertical } from '@antv/util';
// 基本使用
const v = [1, 0]; // 原始向量
const out = [0, 0]; // 用于存储结果的数组
// 逆时针垂直向量
vertical(out, v, true);
console.log(out); // [0, -1]
// 顺时针垂直向量
vertical(out, v, false);
console.log(out); // [0, 1]
// 对任意向量求垂直向量
const v2 = [3, 4];
const perpendicular = [0, 0];
vertical(perpendicular, v2, true);
console.log(perpendicular); // [4, -3]
// 实际应用示例
function createPerpendicularLine(point: number[], direction: number[], length: number) {
const perpendicular = [0, 0];
vertical(perpendicular, direction, true);
// 标准化垂直向量
const magnitude = Math.sqrt(perpendicular[0]**2 + perpendicular[1]**2);
perpendicular[0] = (perpendicular[0] / magnitude) * length;
perpendicular[1] = (perpendicular[1] / magnitude) * length;
return {
start: [
point[0] - perpendicular[0]/2,
point[1] - perpendicular[1]/2
],
end: [
point[0] + perpendicular[0]/2,
point[1] + perpendicular[1]/2
]
};
}
// 使用示例
const point = [100, 100];
const direction = [1, 0];
const perpendicularLine = createPerpendicularLine(point, direction, 50);
console.log(perpendicularLine);
| 参数 |
说明 |
类型 |
默认值 |
中文说明 |
| out |
结果向量 |
number[] |
- |
用于存储结果的数组 |
| v |
原始向量 |
number[] |
- |
需要计算垂直向量的原始向量 |
| flag |
方向标志 |
boolean |
- |
true 表示逆时针,false 表示顺时针 |
| 参数 |
说明 |
类型 |
默认值 |
中文说明 |
| result |
垂直向量 |
number[] |
- |
计算得到的垂直向量(与 out 相同) |
- 输入向量必须是二维的
- out 数组会被修改
- 返回的是 out 数组的引用
- flag 为 true 时逆时针旋转 90 度
- flag 为 false 时顺时针旋转 90 度