唯杰地图 logo唯杰地图
VJMAP
EN

distance-angle

vjcad/references/geometry/distance-angle.md 5.0 KB137 行
原文

本文回答:基础几何 = 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