我有一个由6个曲面定义的3d闭合体积,每个曲面有4个顶点。
所以,我想检查给定点是在卷内还是在卷外。我想到的解决方案是:
从给定点绘制一条随机线,并检查它与包围体积的曲面相交的位置。由于我使用矢量代数来计算线和曲面的交点,因此交点可以位于3d无限表面上的任何位置。
现在我检查这个交叉点是否恰好位于无限平面上的那个面上,并包围了该体积。
为此,我再次想要从我的交叉点到卷的相应面绘制一条随机光线,并检查点是否位于面上。
But I don't know how to check this feature of locating if it is on the surface
or not. Can someone please suggest how can I do it.
P.S. One way of doing this was extending ray casting to 3d but that involves
comparison of slopes to check the orientation. So how can I check orientation
of 3 points in 3d space. I have 4 vertices which make up that face, I know the
point under consideration. How can I check if this point lies clockwise or
counter clockwise to the surface.
答案 0 :(得分:3)
您可以为每个曲面创建一个布尔条件,以确定给定点是在曲面内部还是外部。这可能需要您添加有关每个曲面法线的信息(即曲面的哪一侧向外')。如果六个表面中的每个表面都符合此条件,则该点位于体积内。
另一种类似的思考方式是使用每个曲面创建一个线性不等式系统来创建一个不等式,以创建一个代表您的体积的封闭空间。这也归结为满足是否内在'内部'或者'外面'每个表面,并检查该点是否在所有表面内。
答案 1 :(得分:3)
要考虑您的问题,我们必须首先考虑内部或外部的含义。四个表面是实心的,每个表面将空间分成两个正面,一般来说,四个表面将空间划分为9个区域,其中只有一个区域是有界的,划分出一个四面体(但如果我们仔细选择表面,我们可以达到甚至没有有界区域 - 例如使它们中的两个平行)。因此,一般来说,你必须决定飞机的哪一侧标记内部或外部(嗯,它也不重要,因为外部与不在内部相同)。
使用更多面,问题变得复杂(并且进一步复杂化),因为您可以有几个有界区域也定义实体,因此您需要更多信息,只有分隔它的平面。如果区域导致非凸区域,问题甚至会更复杂,因为您的点可能位于您的区域的某些部分,与某些平面的匹配,而错误的一侧 为其他人,并继续在你的坚实。只需看到像这样的分隔多边形
以及制作有界区域的可能性
你需要的第一件事就是充分定义你的实体,用边缘划分面,并稍微建立边界和顶点,划分一个面,面如何连接自己形成你的实体。
一旦遇到这种情况,你就会有一组面孔,以及指向每个面部外部的矢量(以连续的方式,所以你不要以面部法线结束)朝上,下一个指向下方)。接下来你需要做的是将实体分成凸实体。可以证明,对于由平面构成的三维实体,它可以细分为一组有限的凸实体。
我将尝试在2D中说明相同的问题,但在3D中基本相同:
首先,我们有最初的poligon,让我们假设它是凸的(这是我为此目的的一个重要属性,我将在后面提到):
让我们想象它是一颗3D小行星,而你却是一个走在它表面的人。如果你开始行走,你将穿过黄色的所有线条。这些是法线,你需要从每个面知道哪些面可以到达,并像我一样构造这些面的法线贴图。当你在小行星上行走时,你可以标记法线以了解小行星内部的位置,然后划分它。现在,我们有一个包含所有法线的小行星地图。让我们绘制我们下方的半空间(我们下方的表面的一侧)在几何中,这可以用平面表示(平面具有其所有点都与向量正交的属性,因此{{ 1}}其中X*V=0
表示点积。如果我们将poligon的中心和法线向量作为图形中的黄色向量,我们将获得*
,其中{{1} }}是平面中点的位置,(X - P)*N = 0
是我们的位置(面的中心),X
是垂直于平面的向量,指向上方(到小行星的外部) )
嗯,这个等式具有如下特性:如果我们用P
替换空间中的任何位置,则平面下方的所有点N
都具有值X
和所有天空值拥有它X
。
如果我对四个法线做同样的事情,我会这样做:
...
交易
只有当四个平面给(X - P)*N < 0
现在,> 0
是面部的中心,并且X
是(X - X_face)*(N_face) < 0
时,问题X_face
才会被埋入小行星正常指向我们小行星的外面。如果适用这四个条件,该点将位于小行星 内。
但如果小行星不凸起会发生什么?
如果绘制法线,这将无济于事......因为小行星内部有点并且未通过某些测试(请记住,该点必须低于所有曲面,但不是(如下图所示):
问题是多边形(或多面体)不是凸面的,我们不能在那里应用算法。首先,我们必须解决使其凸起的问题。
如果在越过边缘时开始跟踪小行星的所有表面(保留法线),您将到达另一个增加或减少斜率的平面,因此如果它增加斜率,您将标记edge(我们的多边形中的顶点)是异常的(我们用红色标记它们),如果它减少了,我们将它们标记为正常(我们将它们标记为绿色):
当所有边缘都正常时,没有问题,因为我们的小行星将是凸起的,但当它们中的任何一个是异常时,我们必须继续在那个平面上(在所有平面上的小行星中挖掘)直到我们到达另一个表面(我们已经将飞机延长以分割我们的poligon):
由于我们有一定数量的边缘,并且只有部分边缘被标记为异常,因此有必要完成此过程(请记住,您可以让另一边试图找到一张脸你的多面体(多边形)的(侧面)有顶点向上和顶点向下(在我们之前解释过的意义上))所以你已经将多面体划分为一组有限的凸多面体,可以应用第一种算法。
答案 2 :(得分:1)
看一下这个问题:signed distance between plane and point
现在,您只需要检查您的点是否在每个体积曲面的右侧(正确的符号)。像这样:
bool isInside(const std::vector<Planes>& planes, const Point& point){
for(const auto& plane : planes){
const auto dist =
dotProduct(plane.normal, vectorSubtract(point, plane.point));
if(dist>0) return false;
}
return true;
};
答案 3 :(得分:0)
所以,我认为我能做到的一种方式是:
将光线投射延伸到3d曲面,但这涉及到来自所考虑点的光线穿过体积的次数。这涉及找到线的交点和体积的面。
So what I can do is for a single face (and I will extend it to all the faces)
is, I check for the point of intersection of 3d line and plane by doing simple
algebra and then check if the point lies inside the cuboid formed by
extremities of the vertices forming the face. i.e check if P(x.y,z) which is
the point of intersection of line and plane lies inside the region defined by
extremities of the surface.
i.e.
x > xlow and x < xhigh and y > ylow and y < yhigh and z > zlow and z < zhigh.
These two conditions i.e. ray intersects the 3d plane and the intersection
lies in this region proves that the intersection of ray and plane lies on the
surface which encloses the volume.
I can count the number of such intersections if it is odd, the point
lies inside the volume if it is even the point lies outside the volume.
Does anyone see a problem with this algorithm?