# 判断多边形是否属于复杂多边形

## 判断

$$点_A,点_F$$组成的$$线段a$$与$$点_C,点_D$$组成的$$线段b$$相交。$$线段a$$的两个端点$$A$$、$$F$$必然在$$线段b$$的两侧，反之亦然。

### 计算

$$a \times b = \begin{bmatrix} x_a & x_b \\ y_a & y_b \end{bmatrix} = x_a y_b - x_b y_a$$

## 代码

interface Point {
x: number;
y: number;
}
type Edge = [Point, Point];

/**
* 叉乘
*/
const crossProduct = (v1: number[], v2: number[]) => {
const [v1x, v1y] = v1;
const [v2x, v2y] = v2;
return v1x * v2y - v2x * v1y;
};

/**
* 是否可以相交
* @param baseEedge
* @param targetEdge
*/
const isIntersection = (baseEedge: Edge, targetEdge: Edge) => {
const [basePointA, basePointB] = baseEedge;
const [targetPointC, targetPointD] = targetEdge;

const vBase = [basePointA.x - basePointB.x, basePointA.y - basePointB.y];
const vBaseC = [basePointA.x - targetPointC.x, basePointA.y - targetPointC.y];
const vBaseD = [basePointA.x - targetPointD.x, basePointA.y - targetPointD.y];
return crossProduct(vBase, vBaseC) * crossProduct(vBase, vBaseD) <= 0;
};

/**
* 提取数组元素
*/
const extractArray = (array: Edge[], startIndex: number, length: number) => {
const arr = [];
for (let i = 0; i < length; i++) {
arr.push(array[(startIndex + i) % array.length]);
}
return arr;
};

/**
* 是否是复杂多边形
* @param points 多边形的顶点
*/
const isComplexPolygon = (points: Point[]) => {
const length = points.length;
if (length < 4) return false;
const edges = points.reduce<Edge[]>((edges, startPoint, i, array) => {
const endPoint = array[(i + 1) % length];
edges.push([startPoint, endPoint]); // [起始点, 结束点]
return edges;
}, []);

// 逐边判断 相邻的边无需判断
for (const [i, baseEdge] of Object.entries(edges)) {
const nonadjacentEdge = extractArray(edges, Number(i) + 2, edges.length - 3);
(edge) => isIntersection(baseEdge, edge) && isIntersection(edge, baseEdge)
);
if (flag) return true;
}
return false;
};


651 声望
14 粉丝
0 条评论