关于验证非重合点序列是否构成多边形的方法及逻辑合理性的技术问询
我在编程任务中遇到了以下问题:给定一组非重合点的序列或列表,我想知道它们是否构成一个多边形。
到目前为止我的想法是:如果满足以下情况,它们就不能构成多边形:
- 边重合;
- 某条边与其他n-1条边相交。
但具体该怎么做呢?
给定直线r和s,分别由等式$A + \lambda (P_{01} - P_{00})$和$B + \mu (P_{11} - P_{10})$表示,两条直线相交当且仅当等式$P_{00} + \lambda \underbrace{(P_{01} - P_{00})}{u} = P{10} + \mu \underbrace{(P_{11} - P_{10})}{v}$成立。这意味着存在元组$(\lambda, \mu) \in \mathbb{R}^2+$使得$\underbrace{\begin{bmatrix} u & -v \end{bmatrix}}W \begin{bmatrix} \lambda \ \mu \end{bmatrix} = P{10} - P_{00} $。由于点$P_{00}$和$P_{10}$是按顺序给出的,两个参数$\lambda$和$\mu$必须为正。
还有一种情况是矩阵W的行列式为0,这意味着边是平行的。因此这种情况下的真值函数是$[(\lambda, \mu) \in \mathbb{R}^2_+] \wedge [det(W) \neq 0]$
你能看出我的逻辑有什么漏洞吗?谢谢!
嘿,我来帮你梳理下这个思路里的问题和可以完善的地方:
首先要肯定你大方向是对的——判断多边形的核心确实要排除边重合和非法的边相交,不过你的推导里有几个关键漏洞和遗漏的前提:
1. 相交边的范围判断错误
你提到“某条边与其他n-1条边相交”,但多边形的边本来就是首尾相连的,相邻的两条边在顶点处的相交是完全合法的,不能算非法情况。正确的条件应该是:任意一条边不能和除了前后相邻两条边之外的其他边发生相交(包括顶点处的跨边交点,那属于自交多边形,也不符合要求)。
2. 线段相交的参数范围错误
你把参数$(\lambda, \mu)$的范围限定在$\mathbb{R}^2_+$(正实数),但我们要判断的是线段相交,不是无限延伸的直线相交!只有当$\lambda \in (0, 1)$且$\mu \in (0, 1)$时,交点才落在两条线段的内部,这才是需要排除的非法相交。
- 如果$\lambda$或$\mu$等于0或1,说明交点是线段的端点:这时候要区分是不是相邻边的端点(相邻的话合法),如果是非相邻边的端点重合,那也属于自交,同样要排除。
3. 平行边的判断不完整
你提到行列式$det(W)=0$时边平行,但平行的边还有可能完全重合(这就是你说的“边重合”情况),这时候即使行列式为0,也需要额外判断两条线段是否重叠,而不是只看$det(W)≠0$的情况。
4. 遗漏了基础前提条件
构成多边形还有两个必要的基础条件你没提到:
- 点的数量至少为3个(2个点只能构成线段,不是多边形);
- 所有点不能共线(3个共线的点只能构成直线段,无法形成闭合的多边形)。
5. 等式的小笔误
你写的等式右边常数项是$P_{01} - P_{00}$,应该是$P_{10} - P_{00}$才对,不然和前面的直线方程对应不上,这个是小细节,但编程时会导致计算错误。
总结一下修正后的完整判断步骤:
- 第一步:检查点的数量≥3,且所有点不共线;
- 第二步:遍历每一条边(序列中连续两点+最后一点和第一点组成的闭合边),检查是否和其他非相邻边存在问题:
- 若两条边平行:判断是否重合,重合则直接判定不是多边形;
- 若两条边不平行:解出$\lambda$和$\mu$,如果$\lambda \in (0,1)$且$\mu \in (0,1)$,说明线段内部相交,判定不是多边形;如果$\lambda$或$\mu$为0/1,且交点是非相邻边的端点,也判定不是多边形;
- 第三步:检查是否存在重合的边(比如序列中出现连续重复的边,或者反向的重合边)。
这样就能更准确地判断点序列是否构成合法的简单多边形啦!
备注:内容来源于stack exchange,提问作者User 42

