maya 检查uv面的重叠
2019-12-25 本文已影响0人
CGPipeline
maya 检查uv面的重叠
最近准备写一个maya的场景检查工具,觉得这个检查uv面的重叠挺有意思的,所以写个小分享。
<center>判断两条边是否相互跨越
这个检查UV面的重叠问题其实就是一道向量问题或者线性方程问题,解法有两种:
- 第一种就是通过向量叉积判断两条边是否有焦点
- 第二种就是求两条线段的直线方程进行求焦点进而判断是否相交
因为第二种情况求斜率的时候会有精度损失,所以我们就使用第一种方法,这样我们就可以避免除法造成的精度损失。
使用向量的叉积判断两条边是否跨越
a的坐标是x1,y1
b的坐标是x2,y2
a×b = |a||b| sin <a,b>
a×b = \left[\begin{matrix}
x1 & y1 \\
x2 & y2 \\
\end{matrix}
\right] = x1y2 - x2y1
<a,b>表示向量a与向量b之间的夹角
根据上面的公式由正弦可知:
-
当叉积x1y2 - x2y1等于零的时候两个向量的夹角为0或者180
-
当叉积x1y2 - x2y1小于零的时候两个向量的夹角大于180
-
当叉积x1y2 - x2y1大于零的时候两个向量的夹角小于180
在我们需要判断两个向量是否相互跨越的时候,我们需要判断向量a的两个端点在向量b的两侧,同时向量b的两个端点也在向量a的两侧。
判断\overrightarrow {AB}与\overrightarrow {CD}是否相互跨越,就要判断AB两点是否在\overrightarrow {CD}两侧
这个时候我们就可以使用叉积进行判断了
\overrightarrow {CA} X \overrightarrow {CD}与
\overrightarrow {CB} X \overrightarrow {CD}异号的话就说明两点在向量\overrightarrow {CD}的两侧
转换成坐标的公式就是
(x1 * y2 - x2 * y1) * (x1 * y3 - x3 * y1) < 0.0
def judge_edge(edges_point, edges_point_ju):
"""
judge edge intersect
:param list edges_point: edges point uv value
:param list edges_point_ju: edges point uv value
:return: bool
"""
x1 = edges_point[0][0] - edges_point[1][0]
y1 = edges_point[0][1] - edges_point[1][1]
x2 = edges_point_ju[0][0] - edges_point[1][0]
y2 = edges_point_ju[0][1] - edges_point[1][1]
x3 = edges_point_ju[1][0] - edges_point[1][0]
y3 = edges_point_ju[1][1] - edges_point[1][1]
x4 = edges_point_ju[0][0] - edges_point_ju[1][0]
y4 = edges_point_ju[0][1] - edges_point_ju[1][1]
x5 = edges_point[0][0] - edges_point_ju[1][0]
y5 = edges_point[0][1] - edges_point_ju[1][1]
x6 = edges_point[1][0] - edges_point_ju[1][0]
y6 = edges_point[1][1] - edges_point_ju[1][1]
if (x1 * y2 - x2 * y1) * (x1 * y3 - x3 * y1) < 0.0 and (x4 * y5 - x5 * y4) * (x4 * y6 - x6 * y4) < 0.0:
return True
else:
return False
判断不可能相交的面
在进行判断两条边是否相互跨越之前,可以先进行判断这两个面是否肯定不会相交,在二维坐标系内,如果一个多边形的X 或者 Y轴的最小值比另一个多边形的X 或者 Y轴的最大值要大的话,那他们根本不可能相交
def judge_face_position(edges_point, edges_point_ju):
"""
Determine if two faces may intersect
:param tuple edges_point: edges point uv value
:param tuple edges_point_ju: edges point uv value
:return:
"""
if edges_point[0] >= edges_point_ju[1] or \
edges_point_ju[0] >= edges_point[1] or \
edges_point[2] >= edges_point_ju[3] or \
edges_point_ju[2] >= edges_point[3]:
return True
elif (edges_point[0] == edges_point_ju[0] and edges_point[1] == edges_point_ju[1]) and \
(edges_point[2] == edges_point_ju[2] and edges_point[3] == edges_point_ju[3]):
return True
else:
return False
判断不可能相交的边
在进行判断两条边是否相互跨越之前,可以先进行判断这两个边是否肯定不会相交,在二维坐标系内,如果一个边的X 或者 Y轴的最小值比另一个边的X 或者 Y轴的最大值要大的话,那他们根本不可能相交
# 欢迎关注微信供公众号CGPipeline获取更多干货
def judge_edge_position(edges_point, edges_point_ju):
"""
Determine if two edges may intersect
:param edges_point:
:param edges_point_ju:
:return:
"""
# judge u
if min(edges_point[0][0], edges_point[1][0]) > max(edges_point_ju[0][0], edges_point_ju[1][0]) or \
min(edges_point_ju[0][0], edges_point_ju[1][0]) > max(edges_point[0][0], edges_point[1][0]):
return True
# judge v
elif min(edges_point[0][1], edges_point[1][1]) > max(edges_point_ju[0][1], edges_point_ju[1][1]) or\
min(edges_point_ju[0][1], edges_point_ju[1][1]) > max(edges_point[0][1], edges_point[1][1]):
return True
else:
return False