凸多边形的判定方法
在计算几何、有限元计算中,四边形的凹凸性判断十分重要,凹的四边形网格会影响到有限元计算精度。那如何判定凹多边形和凸多边形呢?
可以根据顶点的角度的正负性进行判断凹凸性,即是判断每个顶点所对应的内角是否都为同号或者异号,如果四个内角均同号,则是凸的,如果异号,则是凹多边形。
假设当前四边形连续的顶点分别是P1、P2、P3、P4,按顺序排列,对于连续的三个点P1、P2、P3,计算两条相邻直线的向量a、b。对向量a、b进行点积,计算出当前顶点所在的角度,依次循环计算出四个顶点的角度。对向量进行叉乘,若向量叉乘为负时,则对角度取反。
代码的实现
def calculate_signed_inner_angles(A, B, C, D, ifOutputInnerAngels=False): np.seterr(divide='ignore', invalid='ignore') # 将四个点转换为numpy数组,以便进行向量操作 Points = np.array([A, B, C, D]) # 计算相邻两边的向量 AB = Points[1] - Points[0] BC = Points[2] - Points[1] CD = Points[3] - Points[2] DA = Points[0] - Points[3] # 判断向量的方向并计算带符号的内部角(使用叉积绝对值判断) A = np.dot(AB, BC) / (np.linalg.norm(AB) * np.linalg.norm(BC)) angle_AB = np.degrees(np.arccos(np.clip(A, -1, 1))) if np.cross(AB, BC) < 0 and abs(np.cross(AB, BC)) > 1e-4: # 检查叉积绝对值是否大于阈值 angle_AB = -angle_AB B = np.dot(BC, CD) / (np.linalg.norm(BC) * np.linalg.norm(CD)) angle_BC = np.degrees(np.arccos(np.clip(B, -1, 1))) if np.cross(BC, CD) < 0 and abs(np.cross(BC, CD)) > 1e-4: angle_BC = -angle_BC C = np.dot(CD, DA) / (np.linalg.norm(CD) * np.linalg.norm(DA)) angle_CD = np.degrees(np.arccos(np.clip(C, -1, 1))) if np.cross(CD, DA) < 0 and abs(np.cross(CD, DA)) > 1e-4: angle_CD = -angle_CD D = np.dot(DA, AB) / (np.linalg.norm(DA) * np.linalg.norm(AB)) angle_DA = np.degrees(np.arccos(np.clip(D, -1, 1))) if np.cross(DA, AB) < 0 and abs(np.cross(DA, AB)) > 1e-4: angle_DA = -angle_DA angleALL = np.array([angle_AB, angle_BC, angle_CD, angle_DA]) signAngle = np.sign(angleALL) a = np.unique(signAngle) if len(a) == 2: if ifOutputInnerAngels: return False, angleALL else: return False else: if ifOutputInnerAngels: return True, angleALL else: return True