distance-angle
本文回答:基础几何 =
distance(p1, p2)/getAngleBetweenPoints(p1, p2)(弧度)/getMidPoint(p1, p2)/polarToCartesian(center, angle, dist)/normalizeAngle(rad)/GeometryCalculator.witchSidePointToLine/GeometryCalculator.adjustAngle / eq / pos,外加calculatePolygonArea(points)等。
一、距离
import { distance, Point2D } from 'vjcad';
distance(new Point2D(0, 0), new Point2D(100, 100)); // 141.42...
点到直线距离没有内置一行函数,但文档给了实现:
function pointToLineDistance(point, lineStart, lineEnd) {
const A = point.x - lineStart.x;
const B = point.y - lineStart.y;
const C = lineEnd.x - lineStart.x;
const D = lineEnd.y - lineStart.y;
const dot = A * C + B * D;
const lenSq = C * C + D * D;
let param = -1;
if (lenSq !== 0) param = dot / lenSq;
let xx, yy;
if (param < 0) { xx = lineStart.x; yy = lineStart.y; }
else if (param > 1) { xx = lineEnd.x; yy = lineEnd.y; }
else { xx = lineStart.x + param * C; yy = lineStart.y + param * D; }
return Math.sqrt((point.x - xx) ** 2 + (point.y - yy) ** 2);
}
MCP 参考:vjcad/doc/geometry/calculations.md、vjcad/example/geometry/01distance.js。
二、角度
import { getAngleBetweenPoints, normalizeAngle } from 'vjcad';
const ang = getAngleBetweenPoints(p1, p2); // 弧度
const norm = normalizeAngle(ang); // [0, 2π)
const deg = ang * 180 / Math.PI; // 弧度→度
const rad = deg * Math.PI / 180; // 度→弧度
MCP 参考:vjcad/doc/geometry/calculations.md、vjcad/example/geometry/02angle.js。
三、中点
import { getMidPoint } from 'vjcad';
const m = getMidPoint(new Point2D(0, 0), new Point2D(100, 100)); // (50, 50)
MCP 参考:vjcad/doc/geometry/calculations.md、vjcad/example/geometry/03midpoint.js。
四、极坐标 → 笛卡尔
import { polarToCartesian, Point2D } from 'vjcad';
const center = new Point2D(0, 0);
const angle = Math.PI / 4;
const r = 100;
const end = polarToCartesian(center, angle, r); // ≈ (70.71, 70.71)
MCP 参考:vjcad/doc/geometry/calculations.md。
五、GeometryCalculator 工具
import { GeometryCalculator } from 'vjcad';
// 点在直线哪一侧(叉积):1 = 行进方向左侧 / 0 = 线上 / -1 = 右侧
// 坑位:返回值 = cross 积符号——线 (0,0)→(+x) 时点 (+y 侧) 返回 1。
// 即 +1 是"行进方向左手边",与本节旧版注释(-1 左/1 右)相反;勿按直觉记反。
GeometryCalculator.witchSidePointToLine(lineStart, lineEnd, testPoint);
// 角度归一化到 [0, 2π)
GeometryCalculator.adjustAngle(-Math.PI / 2); // 3π/2
// 数值比较带容差
GeometryCalculator.eq(1.0001, 1.0002, 0.001); // true
// 值在区间的位置
GeometryCalculator.pos(50, 0, 100);
// 'center' | 'Left' | 'Right' | 'EqualLeft' | 'EqualRight'
MCP 参考:vjcad/doc/geometry/calculations.md、vjcad/example/geometry/06pointside.js。
六、面积 / 点在多边形内
import { calculatePolygonArea } from 'vjcad';
const points = [
new Point2D(0, 0),
new Point2D(100, 0),
new Point2D(100, 80),
new Point2D(0, 80)
];
const area2x = calculatePolygonArea(points); // 16000 —— 注意是【双倍面积】
const area = area2x / 2; // 8000
坑位:
calculatePolygonArea返回的是 shoelace 公式的未除 2 结果——10×10 正方形返回200而非100(源码注释自称"双倍面积",库内调用方如Edge.area均自行/2)。拿到手务必除以 2。
点在多边形内(射线法)见 vjcad/example/geometry/08pointinpolygon.js,文档 vjcad/doc/geometry/area.md、vjcad/doc/geometry/selection.md。
七、垂足
vjcad/example/geometry/14perpendicular.js 演示了点到直线的垂足计算。一般通过:
function projectPointToLine(point, lineStart, lineEnd) {
const dx = lineEnd.x - lineStart.x;
const dy = lineEnd.y - lineStart.y;
const t = ((point.x - lineStart.x) * dx + (point.y - lineStart.y) * dy) / (dx * dx + dy * dy);
return new Point2D(lineStart.x + t * dx, lineStart.y + t * dy);
}
MCP 参考:vjcad/doc/geometry/point2d.md、vjcad/example/geometry/14perpendicular.js。
反例
getAngleBetweenPoints拿到当度数:是弧度。- 不归一化
normalizeAngle:< 0或> 2π比较两个角度大小会出错。 calculatePolygonArea传开放路径 / 自相交多边形:结果不一定是直观面积,提前确保闭合。
参考(官方文档 MCP)
- 文档:
vjcad/doc/geometry/calculations.md、vjcad/doc/geometry/area.md、vjcad/doc/geometry/point2d.md - 示例:
vjcad/example/geometry/01distance.js、02angle.js、03midpoint.js、06pointside.js、07area.js、08pointinpolygon.js、14perpendicular.js