我需要在3D空间中绘制n个平面。四边形是由两个点创建的平面,通过一个算法,我得到了4个顶点来绘制四边形。我遇到的问题是,顶点的顺序显然会影响结果。下面是我的意思:
但是当平面是水平的而不是垂直的:
我可以想象出两种可能的解决方案。使用三角形并将它们组合起来,或者对顶点进行适当的排序。我不知道如何实现第二种想法。我试过使用三角形,但遇到了同样的问题。
# self.planos = [('A', (500, 500, 10), (-500, 500, 10), (-500, -500, 10), (500, -500, 10))] for horizontal
# self.planos = [('A', (-500, 10, 500), (500, 10, 500), (-500, 10, -500), (500, 10, -500))] for vertical
glEnable(GL_BLEND)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
glDepthMask(GL_FALSE)
glBegin(GL_QUADS)
glColor(0.5, 0.5, 0.1, 0.5)
for i in range(len(self.planos)):
glVertex(self.planos[i][1][0], self.planos[i][1][2], self.planos[i][1][1])
glVertex(self.planos[i][2][0], self.planos[i][2][2], self.planos[i][2][1])
glVertex(self.planos[i][3][0], self.planos[i][3][2], self.planos[i][3][1])
glVertex(self.planos[i][4][0], self.planos[i][4][2], self.planos[i][4][1])
glEnd()
glDepthMask(GL_TRUE)
glDisable(GL_BLEND)
求四个顶点绘制平面的交集代码:
In init method:
# Vertices of the cube
self.v = (Point3D(500, 500, 500), Point3D(-500, 500, 500), Point3D(-500, -500, 500),
Point3D(500, -500, 500), Point3D(500, 500, -500), Point3D(-500, 500, -500),
Point3D(-500, -500, -500), Point3D(500, -500, -500))
# Edges of the cube
self.a = (Segment3D(self.v[0], self.v[1]), Segment3D(self.v[1], self.v[2]),
Segment3D(self.v[2], self.v[3]), Segment3D(self.v[3], self.v[0]),
Segment3D(self.v[0], self.v[4]), Segment3D(self.v[1], self.v[5]),
Segment3D(self.v[2], self.v[6]), Segment3D(self.v[3], self.v[7]),
Segment3D(self.v[4], self.v[5]), Segment3D(self.v[5], self.v[6]),
Segment3D(self.v[6], self.v[7]), Segment3D(self.v[7], self.v[4]))
# Algorithm for getting 4 points
def plano_limites(self, point1, point2, point3):
plano = Plane(Point3D(point1), Point3D(point2), Point3D(point3))
good = []
for i in range(12):
a = intersection(plano, self.a[i]) # Sympy intersection
if a:
good.append(a[0])
return good
2条答案
按热度按时间r55awzrz1#
首先,要知道相交可能会产生多于或少于四个顶点,但由于区域总是凸的,所以你可以简单地用三角形扇形来画它。
要对顶点进行排序,需要平面的法线
n
和所有顶点v_i
的质心c
:然后,我们需要一个z轴为法线的坐标系。为此,我们可以简单地定义一个任意的其他方向矢量
d
和定义x = normalize(cross(d, normal)), y = cross(normal, x)
。对于d
与normal
重合的情况,我们需要一个替代的d
。然后,我们可以计算该坐标系中任意顶点的代表角:
按这个Angular 排序,你就完成了。
xmq68pz92#
由于尼科的回答,我能够学会如何为自己做这件事,但我认为这将是有用的做一个完整的写了,因为它仍然需要我进一步学习,以了解这里发生了什么。
我们需要找到一个x轴和y轴,其中z轴与法线对齐,我们通过取任意矢量
other
的叉积来完成这一点。如果other
矢量与法线重合,我们需要使用另一个矢量。如果两个矢量的点积等于1,则它们重合。在右手坐标系中使用
(0, 1, 0)
的other
矢量(或者(0, 0, -1)
重合的情况下),我们将产生更容易理解的x轴和y轴矢量。这对算法来说并不重要,但我发现这是我自己最初理解中缺少的最关键的部分。当平面的法线为
(0, 0, 1)
时,通过使用(0, 1, 0)
的另一个矢量,x轴将为(1, 0, 0)
,y轴将为(0, 1, 0)
。当平面的法线为
(0, 1, 0)
时,通过使用(0, 0, -1)
的另一个矢量,x轴将为(1, 0, 0)
,y轴将为(-1, 0, 0)
。这可以很容易地通过使用你的右手和转动你的手指,这是正常的指向正z轴(对你自己)建模。