2d-geometry

中文文档
3.0.0发布于 2024/06/09MITTypeScriptES Module零依赖近 30 天下载 2264

按打字符排列的表演者和工程学2D几何

中文使用文档
文档目录15 节
  1. 为什么是叉子?
  2. 安装
  3. 使用量
  4. 高性能使用个案
  5. 图书馆的内容
  6. 多边形
  7. 多线
  8. 绘图集
  9. 转换
  10. 交叉点
  11. 形状之间的距离
  12. 交叉模型(DE-9IM)
  13. 关系上游
  14. 布尔操作
  15. 序列化

2d 几何

2d 几何 是一个叉子 平调 专注于性能,人机学和打字.

这个库本意是用来操纵诸如点,向量和圆等抽象几何形状的完整解决方案. 它还提供了许多有用的方法和算法,例如寻找相交点,检查包含,计算距离,应用affine转换,进行布尔操作等.

为什么是叉子?

原始图书馆是 不错 从特征集和数学的角度来说,但Typescript支持是平庸的,一些非常有用的原始人还没有. 这个图书馆增加了非常需要的 Quadratic, (中文(简体) ), Bezier 财务报告和审定财务报表 Path (顺序 Arc, (中文(简体) ), Segment, (中文(简体) ), Quadratic 财务报告和审定财务报表 Bezier这让与SVG和Canvas合作的微风.

原作也以JS引擎难以优化的方式写出,而为捆绑者则无法树摇. 这个分叉会用一个新的主干线在某个时候打破API来分解一些特性(尤其是相接和相距算法)并优化捆绑大小.

安装

pnpm install --save 2d-geometry

使用量

import {
    Point,
    Vector,      // Oriented vector starting at (0, 0)
    Line,        // Infinite line
    Ray,         // Semi-infinite line (starts at a point, doesn't end)
    Segment,     // Finite line (starts and ends at a point)
    Arc,         // Circular arc only, no ellipses
    Circle,
    Box,         // A bounding box, not a Rect!
    Bezier,      // Cubic bezier
    Quadratic,   // Quadratic bezier
    Path,        // Sequence of Arc, Segment, Quadratic and Bezier
    Polygon,
    Rect,        // Child class of Polygon
    RoundedRect, // Child class of Polygon
    Matrix,      // 2d affine transformation matrix
} from '2d-geometry';

每个形状都是抽象的童年 Shape 类,包含道具像 .box 财务报告和审定财务报表 .center,以及方法类 .translate() 或者说 .rotate()。 。 。 .

有些课有快捷键来避免打电话 new,例如:

import { point, circle, segment } from '2d-geometry';

const s1 = segment(10, 10, 200, 200);
const s2 = segment(10, 160, 200, 30);
const c = circle(point(200, 110), 50);

对象默认不可改变,并创建其内容的新副本:

import { Point } from '2d-geometry';

const a = Point.EMPTY // contains a frozen `new Point(0, 0)`
const b = a.translate(50, 100)

但是,对于避免分配的高绩效情况,有些方法具有可变的等同性。 他们将被标记为 Mut 后缀 :

import { Matrix } from '2d-geometry';

const a = new Matrix()
const b = Matrix.fromTransform(0, 0, 0, 2) // x, y, rotation, scale
a.multiplyMut(b) // a is mutated directly

核心库是抽象的,但一些SVG utils被单独导出(以避免捆绑大小成本). 你可以这样使用它们:

import { Circle } from '2d-geometry'
import { parsePath, stringify } from '2d-geometry/svg'

const svgString = stringify(new Circle(100, 100, 50), { fill: 'red' })
const path = parsePath('M0,0 L100,0 L100,100 L0,100 Z') // returns a `Path` instance

本项目遵循 《陶宣言》 并导出圆形常数为 TAU,相当于 2 * Math.PI数字 :

import { TAU } from '2d-geometry'

高性能使用个案

如果你正在使用这个库渲染,你可能需要匹配对象的类型. 你可以用这个 shape.tag 歧视者,即整数法.

import { ShapeTag, Segment, Circle } from '2d-geometry'

const shape = graphicNode.shape

// NO
if (shape instanceof Segment) {
  drawSegment(shape as Segment)
} else if (shape instanceof Circle) {
  drawCircle(shape as Circle)
}
// ...

// YES
switch (shape.tag) {
  case ShapeTag.Segment: {
    drawSegment(shape as Segment); break
  }
  case ShapeTag.Circle: {
    drawCircle(shape as Circle); break
  }
  // ...
}

你也可以使用这个 shape._data 字段用于您自己的目的,用于实例缓存提供了数据.

图书馆的内容

多边形

多边形 内 2d 几何 库实际上是多边形. 多边形是面相的集合 - 边缘的闭合线链,可以是线段或弧。 最外在的面孔 外边的面孔 叫做"岛" 里面的一张脸叫做"洞" 洞里可能还有内岛, 包容性水平是无限的.

岛屿和洞的取向是计算问题 洞穴的方向应该与岛屿相反. 这意味着,为了取得适当结果,多边形的面孔应该是: 可定向:它们不应该有自交. 相貌也不应该相互重叠。 方法 isValid() 检查多边形是否符合这些规则.

多边形对象的构造者接受各种输入 :

  • 外形分流(平地分流出. 分会或平会. 表示闭锁链的弧
  • 作为代表闭锁链的json对象的形状阵列
  • 分数组 (Flatten.). 代表多边形顶点的点
  • 代表多边形顶点的数组对 [x,y]
  • 圆形或框形实例

多边形提供了各种有用的方法:

  • area - 计算多边形的区域
  • addFace - 在多边形上添加新面孔
  • deleteFace - 从多边形中去除面相
  • addVertex - 将多边形的边缘adn拆分,创造出新的顶点
  • cut - 将多行多边形切入子多边形
  • findEdgeByPoint - 在多边形中找到边缘
  • contains - 测试多边形是否包含形状(点、段或弧)
  • transform - 利用等离子变换矩阵转换多边形
  • reverse - 脸部回向
  • splitToIslands - 分裂成有洞的岛屿

多线

多线表示类型子段或弧的未关闭边缘链

绘图集

计划 Set是一个能通过长方形查询进行空间切分的形状容器.

转换

所有班级都有办法 translate, (中文(简体) ), rotate 财务报告和审定财务报表 scale 被锁起来的.
示例

// Rotate segment by 45 deg around its center
let {point,segment,matrix} = Flatten;
let s = segment(point(20,30), point(60,70));
let center = s.box.center;
let angle = 45.*Math.PI/180.;
let rotated_segment = s.rotate(angle, center)

交叉点

所有班都有办法 intersect(otherShape) 返回交叉点数组, 如果两个形状相交,或空阵列。 这不是预定义的顺序 的相交点.

别乱来,还有两种方法 BooleanOperations.intersect() 执行多边形和逻辑上游的布尔相交点 Relations.intersect() 检查两个形状是否交叉.

形状之间的距离

所有基本类和多边形都有方法 distanceTo(othershape) 计算到其他形状的距离。 与相距函数一起返回最短段 介于两个形状之间 - 两个最相近点之间的分块, 第一点位于其中 打开 this 形状,第二个 - 在另一个形状上,见示例:

let s = segment(point(10,30), point(150, 40));
let c = circle(point(75,75),10);
let [dist,shortest_segment] = s.distanceTo(c);

交叉模型(DE-9IM)

维基百科扩展九相通模型 (单位:千美元)DE-9IM 请检查URL=值 (帮助))是一个地形模型和一个标准 用于描述二维平面上两个几何的空间关系.

首先,对于我们定义的每个形状:

  • 内部
  • 边界
  • 一个外出

对于多边形,内部,边界和外表都很明显,其他类型也有一些排除:

  • 点没有内部
  • 线条没有边界

DE-9IM模型基于3×3相交矩阵与形式:

         [ I(a) ^ I(b)   B(a) ^ I(b)   E(a) ^ I(b)
de9im =    I(a) ^ B(b)   B(a) ^ B(b)   E(a) ^ B(b)
           I(a) ^ E(b)   B(a) ^ E(b)   E(a) ^ E(b)  ]

地点 a财务报告和审定财务报表 b 有两个形状(宝石),

I(), B(), E() 表示内部、边界和外部操作员以及

^ 表示相交点的操作. 相交结果的维度取决于形状的维度,例如,

  • 线内与多边形内相交点是一个 线段数组
  • 线内与边界多边形之间的相交点是 一系列点(在触碰时可包括分块)
  • 两个多边形内部的相交点( 如果存在) 将是 a 多边形.

DE-9IM矩阵描述平面上两个形状之间可能存在的任何关系.

DE-9IM 矩阵可通过方法获取 relate 名称空间 Relations。 。 。 .

DE-9IM矩阵中的每个元素都是代表相应相交点的物体的数组. 空数组表示没有相交的大小写 . 如果相接点不适用(即与没有边界线的边界相接), 通讯单元格未定义 .

不计算出两个外观之间的交叉,因为通常它毫无意义.

let {relate} = Relations;
// 
// define two shapes: polygon1, polygon2
//
let de9im = relate(polygon1, polygon2);
//
// explore 8 of 9 fields of the de9im matrix:
// de9im.I2I  de9im.B2I  de9im.E2I
// de9im.I2B  de9im.B2B  de9im.E2B
// de9im.I2E  de9im.B2E     N/A

另一个常见的表示DE-9IM矩阵的方法是字符串,其中

  • T 表示不纯正的相交点
  • F 表示数组为空的相交点
  • . 指无关或不适用

字符串可以使用 de9im.toString() 方法.

关系上游

通过命名空间暴露的两个形状之间的空间关系 Relations。 。 。 . 空间上游返回 true 如果关系匹配 false 否则.

let {intersect, disjoint, equal, touch, inside, contain, covered, cover} = Relations;
// define shape a and shape b
let p = intersect(a, b);
console.log(p)             // true / false
  • intersect - 形状 a和b至少有一个共同点
  • disjoint - 对 intersect
  • equal - 形状a和b在地形学上是相等的
  • touch - 形状a和b至少有一个共同点,但其内部不相交
  • inside - 形状内侧的谎言 b
  • contain - 形状b位于形状b的内部
  • covered - 谎言或内地或外形边界的每个点b
  • covered - b的每个地点、内地或外形边界a

布尔操作

通过命名空间提供多边形上的布尔操作 布尔操作。 。 。 . 布尔操作中的多边形应该有效: 两种操作都应该具有相同的面相取向意义, 相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相.

用户负责提供有效的多边形,布尔操作方法不检查有效性.

let {unify, subtract, intersect, innerClip, outerClip} = BooleanOperations;
  • unify - 统一两个多边形并返回结果的多边形
  • subtract - 从第一个中减去第二个多边形,返回生成的多边形
  • intersect - 两个多边形相交并返回结果的多边形
  • innerClip - 相交两个多边形,并将相交的边界还原为2个阵列. 第一个射线包含第一个多边形的边缘,第二个-第二个的边缘
  • outerClip - 第一个多边形与第二个多边形内部的剪接边界

基于 Weiler-Atherton 剪接算法的执行, 条款说明 使用多边形区域排序来隐藏表面去除

序列化

全体 2d 几何 形状对象可使用 JSON.stringify() 方法. JSON.stringify 使用 .toJSON() 在课堂上执行. JSON.parse 从字符串中恢复对象,然后构造器可以使用此对象来创建平面对象.

let l = line(point(4, 0), point(0, 4));
// Serialize
let str = JSON.stringify(l);  
// Parse and reconstruct
let l_json = JSON.parse(str);
let l_parsed = line(l_json);

版本与发布记录

2d-geometry 共发布 7 个版本,首次发布于 2024/03/30;过去 12 个月发布了 0 个版本。

版本发布日期距今
3.0.0latest2024/06/092 年前
3.0.0-rc.22024/04/112 年前
3.0.0-rc.12024/04/102 年前
2.1.02024/04/022 年前
2.0.12024/04/012 年前
2.0.02024/03/302 年前

关于 2d-geometry 的常见问题

2d-geometry 是什么?

按打字符排列的表演者和工程学2D几何

如何安装 2d-geometry?

在项目目录运行 npm install 2d-geometry,或使用 pnpm add / yarn add / bun add。

2d-geometry 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

2d-geometry 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

2d-geometry 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=4.2.4。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

2d-geometry 可以商用吗?

2d-geometry 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

2d-geometry 的下载量有多少?

根据 npm 官方下载统计,2d-geometry 在 2026/10/04 – 2026/11/02 这 30 天内被下载 2,264 次,日均约 75 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

2d-geometry 还在维护吗?

最新版本 3.0.0 发布于 2024/06/09(2 年前);至今共发布 7 个版本,其中过去 12 个月发布了 0 个;首次发布于 2024/03/30。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。