大家好,我是前端丁修。
在图形学和前端开发中,处理多边形时,顶点通常以循环的方式连接,即第一个点与最后一个点相连。有时需要优化多边形的点,移除路径中不必要的点以简化多边形结构。本节将介绍如何使用 TypeScript 实现一个过滤多边形中冗余点的工具。
初始化多边形
定义多边形的点集。
检测和移除冗余点
判断哪些点是多余的,并将其移除。
优化后的多边形输出
输出经过优化后的点集。
我们将采用共线检测和距离阈值的方法来判断点是否冗余。通过检查连续三个点是否共线,可以有效识别并删除那些位于直线上的中间点,从而优化多边形的顶点数,提升计算效率。
如果三个连续的点在同一直线上,中间的点就是冗余的,可以被移除。
在某些情况下,点之间的距离过小也可以被认为是冗余的,根据设定的阈值来移除这些点。
下面是过滤多边形中冗余点的 TypeScript 实现。
typescript// 定义点的接口
interface Point {
x: number;
y: number;
}
// 多边形类
class Polygon {
points: Point[];
constructor(points: Point[]) {
this.points = points;
}
// 检查三个点是否共线
private isCollinear(p1: Point, p2: Point, p3: Point): boolean {
const area =
p1.x * (p2.y - p3.y) + p2.x * (p3.y - p1.y) + p3.x * (p1.y - p2.y);
return Math.abs(area) < 1e-6;
}
// 计算两点之间的距离
private distance(p1: Point, p2: Point): number {
return Math.sqrt((p1.x - p2.x) ** 2 + (p1.y - p2.y) ** 2);
}
// 移除近距离的点
private removeClosePoints(distanceThreshold: number): void {
if (this.points.length <= 3) return;
// 先检查首尾点
if (this.distance(this.points[0], this.points[this.points.length - 1])<= distanceThreshold) {
this.points.pop();
}
this.points = this.points.filter((point, index, arr) => {
if (index === 0) return true;
return this.distance(point, arr[index - 1]) > distanceThreshold;
});
}
// 移除共线的点
private removeCollinearPoints(): void {
if (this.points.length <= 3) return;
const filteredPoints: Point[] = [];
const n = this.points.length;
for (let i = 0; i < n; i++) {
// 保证 i 为 0 时,i - 1 不会变为负数
const prev = this.points[(i - 1 + n) % n];
const current = this.points[i];
// 取模运算,用于确保索引始终在 0 到 n-1 之间,避免数组越界
const next = this.points[(i + 1) % n];
if (
this.isCollinear(prev, current, next) &&
// 检查当前点之后是否至少还有两个点。
// 如果 i + 2 大于或等于 n,意味着已经到达数组的末尾,此时不需要进一步检查共线性,直接保留当前点。
(i + 2 >= n ||
!this.isCollinear(current, next, this.points[(i + 2) % n]))
) {
continue;
}
filteredPoints.push(current);
}
this.points = filteredPoints;
}
// 过滤冗余点
private filterRedundantPoints(distanceThreshold: number = 0.01): void {
if (this.points.length < 3) return;
this.removeClosePoints(distanceThreshold);
this.removeCollinearPoints();
}
// 输出多边形的点
getPoints(): Point[] {
return this.points;
}
}
创建一个 Polygon 实例,传入点集后调用 filterRedundantPoints 方法即可过滤冗余点。通过调整 distanceThreshold 参数,可以控制距离过滤的敏感度。
typescriptconst polygon = new Polygon([
{ x: 0, y: 0 },
{ x: 2, y: 2 },
{ x: 4, y: 4 }, // 冗余点
{ x: 6, y: 2 },
{ x: 8, y: 0 },
{ x: 8.02, y: 0 }, // 冗余点
]);
console.log("原始点集:", polygon.getPoints());
polygon.filterRedundantPoints(0.05);
console.log("优化后点集:", polygon.getPoints());

输出:
原始点集: [ { x: 0, y: 0 }, { x: 2, y: 2 }, { x: 4, y: 4 }, { x: 6, y: 2 }, { x: 8, y: 0 }, { x: 8.02, y: 0 } ] 优化后点集: [ { x: 0, y: 0 }, { x: 4, y: 4 }, { x: 8, y: 0 } ]
本文作者:丁修
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!