C++ 三维闭合体积内的点

C++ 三维闭合体积内的点,c++,3d,raycasting,point-in-polygon,C++,3d,Raycasting,Point In Polygon,我有一个由6个曲面定义的三维闭合体积,每个曲面有4个顶点 所以,我想检查给定的点是在体积内还是在体积外。我想到的一个解决办法是: 从给定点随机绘制一条线,并检查其与包围体积的曲面相交的位置。由于我使用向量代数来计算直线和曲面的交点,交点可以位于三维无限曲面上的任何位置 现在我检查这个交点是否恰好位于无限平面上并包围体积的面上 So what I can do is for a single face (and I will extend it to all the faces) is, I ch

我有一个由6个曲面定义的三维闭合体积,每个曲面有4个顶点

所以,我想检查给定的点是在体积内还是在体积外。我想到的一个解决办法是:

从给定点随机绘制一条线,并检查其与包围体积的曲面相交的位置。由于我使用向量代数来计算直线和曲面的交点,交点可以位于三维无限曲面上的任何位置

现在我检查这个交点是否恰好位于无限平面上并包围体积的面上

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?
为此,我再次希望从交点到体积的各个面绘制一条随机光线,并检查该点是否位于面上

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. 

可以为每个曲面创建布尔条件,以确定给定点是在曲面内部还是外部。这可能需要添加有关每个曲面法线的信息,即曲面的哪一侧是“向外”的。如果此条件适用于六个曲面中的每个曲面,则该点位于体积内

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?

另一种类似的方法是创建一个线性不等式系统,使用每个曲面创建一个不等式,创建一个表示体积的封闭空间。这也归结为满足点是在每个曲面的“内部”还是“外部”,并检查点是否在所有曲面内部。

您可以为每个曲面创建一个布尔条件,以确定给定点是在曲面内部还是外部。这可能需要添加有关每个曲面法线的信息,即曲面的哪一侧是“向外”的。如果此条件适用于六个曲面中的每个曲面,则该点位于体积内

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?

另一种类似的方法是创建一个线性不等式系统,使用每个曲面创建一个不等式,创建一个表示体积的封闭空间。这也归结为满足点是在每个曲面的“内部”还是“外部”,并检查点是否在所有曲面的内部。

看看这个问题:

现在,您只需要检查您的点是否位于每个体积曲面的右侧。大概是这样的:

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;
};

看看这个问题:

现在,您只需要检查您的点是否位于每个体积曲面的右侧。大概是这样的:

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;
};

因此,我认为我能做到这一点的一个方法是:

将光线投射扩展到三维曲面,但这涉及到从所考虑的点开始的光线穿过体积的次数。这涉及到查找线和体积面的交点

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?

因此,我认为我能做到这一点的一个方法是:

将光线投射扩展到三维曲面,但这涉及到从所考虑的点开始的光线穿过体积的次数。这涉及到查找线和体积面的交点

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?

考虑到你的问题,我们首先要考虑内部或外部的含义。对于四个曲面实体,每个曲面将空间精确地划分为两个面,一般来说,四个曲面将空间划分为9个区域,其中只有一个区域是有界的,划定了一个四面体,但如果我们仔细选择曲面,我们甚至可以到达没有边界的区域,例如使其中两个区域平行。所以,一般来说,你必须决定平面的哪一边是内侧还是外侧,这也没关系,因为外侧和不内侧是一样的

如果有更多的面,问题会变得越来越复杂,因为您可以有多个也定义实体的有界区域,因此您需要更多的信息,而不仅仅是对其进行定界的平面。如果区域生成非凸区域,则问题更为复杂,因为点可能位于区域的某个部分,该部分与某些平面的一侧匹配,而其他平面的一侧匹配,并且继续位于实体内部。请看这样一个分隔的多边形

以及制作有界区域的可能性

您需要做的第一件事是充分定义实体,用边分隔面,并在一定程度上确定分隔一个面的边和顶点,以及面如何连接以形成实体

一旦出现这种情况,就会有一组面和向量以连续的方式指向每个面的外部,因此不会以一个面法线指向上,而下一个面法线指向下结束。下一步你需要做的是把你的实体分割成一个凸的实体。可以证明,对于由平面构成的三维实体,可以将其细分为一组有限的凸面实体

我将尝试在2D中说明相同的问题,但在3D中基本相同:

首先,我们有初始多边形,假设它是凸的 s是一个重要的财产,我将在后面提到:

让我们想象它是一个3D小行星,你是一个在它表面行走的人。如果你开始走路,你将穿过所有用黄色标出的线条。这些是法线,为此,您需要从每个面知道哪些面是可访问的,并像我所做的那样构造到这些曲面的法线贴图。当你在小行星上行走时,你会标记法线以知道小行星内部的位置,并对其进行划界。现在,我们有一张小行星地图,上面有所有的法线。让我们在我们下面画一个半空间,曲面的一边在几何上在我们下面,这可以用一个平面来表示。一个平面的属性是它的所有点都与一个向量正交,所以X*V=0,其中*表示点积。如果我们把多边形的中心和法向量作为图中的黄色向量,我们会得到X-P*N=0,其中X是平面上一点的位置,P是我们的位置,面中心,N是一个垂直于平面的向量,指向小行星的外侧

这个方程的性质是,如果我们用空间中的任意位置来代替X,那么平面下的所有点X的值都是X-p*N<0,而所有的天空值都大于0

如果我对四条法线做同样的处理,我会得到: ... 处理 只有当四个平面给出X-X_面*N_面<0时,问题点X才会被埋入小行星,其中X_面是面中心,N_面是指向小行星外部的法线面。只有在这四个条件适用的情况下,该点才会位于小行星内部

但是如果小行星不是凸的,会发生什么呢

如果您绘制法线,这将无助于。。。由于小行星内部存在一些点,并且未通过某些测试,记住,该点必须位于所有表面下方,但并非如下图所示:

问题是多边形或多面体不是凸的,我们不能在那里应用算法。所以首先我们要解决使它凸的问题

如果你开始沿着小行星的所有表面移动,当你穿过一条边时,保持法线不变,你会到达另一个增加或减少坡度的平面,因此如果它增加坡度,你会在多边形中将该边顶点标记为异常,我们用红色标记了它们,如果它减少,我们将它们标记为正常,我们已将它们标记为绿色:

当所有边缘都正常时,没有问题,因为我们的小行星将是凸面的,但当其中任何一个边缘异常时,我们必须在该平面上继续在所有平面上挖掘小行星,直到我们到达另一个表面,我们已经延长了该平面以划分我们的多边形:

因为我们有有限数量的边,并且只有一些边被标记为异常,所以这个过程是有保证完成的。记住,你可以让另一侧尝试找到多面体多边形的面侧,它的顶点向上和向下,就像我们前面解释的那样

所以你已经把你的多面体划分成一个有限的凸多面体集合,可以应用于第一个算法


考虑到你的问题,我们首先要考虑内部或外部的含义。对于四个曲面实体,每个曲面将空间精确地划分为两个面,一般来说,四个曲面将空间划分为9个区域,其中只有一个区域是有界的,划定了一个四面体,但如果我们仔细选择曲面,我们甚至可以到达没有边界的区域,例如使其中两个区域平行。所以,一般来说,你必须决定平面的哪一边是内侧还是外侧,这也没关系,因为外侧和不内侧是一样的

如果有更多的面,问题会变得越来越复杂,因为您可以有多个也定义实体的有界区域,因此您需要更多的信息,而不仅仅是对其进行定界的平面。如果区域生成非凸区域,则问题更为复杂,因为点可能位于区域的某个部分,该部分与某些平面的一侧匹配,而其他平面的一侧匹配,并且继续位于实体内部。请看这样一个分隔的多边形

以及制作有界区域的可能性

您需要做的第一件事是充分定义实体,用边分隔面,并在一定程度上确定分隔一个面的边和顶点,以及面如何连接以形成实体

一旦出现这种情况,就会有一组面和向量以连续的方式指向每个面的外部,因此不会以一个面法线指向上,而下一个面法线指向下结束。下一步你需要做的是把你的实体分割成一个凸的实体。可以证明,对于由平面构成的三维实体,可以将其细分为一组有限的凸面实体

我会尽力帮助你 在2D中解决相同的问题,但在3D中基本相同:

首先,我们有初始poligon,假设它是凸的,这是一个重要的性质,我将在后面提到:

让我们想象它是一个3D小行星,你是一个在它表面行走的人。如果你开始走路,你将穿过所有用黄色标出的线条。这些是法线,为此,您需要从每个面知道哪些面是可访问的,并像我所做的那样构造到这些曲面的法线贴图。当你在小行星上行走时,你会标记法线以知道小行星内部的位置,并对其进行划界。现在,我们有一张小行星地图,上面有所有的法线。让我们在我们下面画一个半空间,曲面的一边在几何上在我们下面,这可以用一个平面来表示。一个平面的属性是它的所有点都与一个向量正交,所以X*V=0,其中*表示点积。如果我们把多边形的中心和法向量作为图中的黄色向量,我们会得到X-P*N=0,其中X是平面上一点的位置,P是我们的位置,面中心,N是一个垂直于平面的向量,指向小行星的外侧

这个方程的性质是,如果我们用空间中的任意位置来代替X,那么平面下的所有点X的值都是X-p*N<0,而所有的天空值都大于0

如果我对四条法线做同样的处理,我会得到: ... 处理 只有当四个平面给出X-X_面*N_面<0时,问题点X才会被埋入小行星,其中X_面是面中心,N_面是指向小行星外部的法线面。只有在这四个条件适用的情况下,该点才会位于小行星内部

但是如果小行星不是凸的,会发生什么呢

如果您绘制法线,这将无助于。。。由于小行星内部存在一些点,并且未通过某些测试,记住,该点必须位于所有表面下方,但并非如下图所示:

问题是多边形或多面体不是凸的,我们不能在那里应用算法。所以首先我们要解决使它凸的问题

如果你开始沿着小行星的所有表面移动,当你穿过一条边时,保持法线不变,你会到达另一个增加或减少坡度的平面,因此如果它增加坡度,你会在多边形中将该边顶点标记为异常,我们用红色标记了它们,如果它减少,我们将它们标记为正常,我们已将它们标记为绿色:

当所有边缘都正常时,没有问题,因为我们的小行星将是凸面的,但当其中任何一个边缘异常时,我们必须在该平面上继续在所有平面上挖掘小行星,直到我们到达另一个表面,我们已经延长了该平面以划分我们的多边形:

因为我们有有限数量的边,并且只有一些边被标记为异常,所以这个过程是有保证完成的。记住,你可以让另一侧尝试找到多面体多边形的面侧,它的顶点向上和向下,就像我们前面解释的那样

所以你已经把你的多面体划分成一个有限的凸多面体集合,可以应用于第一个算法


我同意这个解决方案,但我所寻找的是一个通用算法,它不涉及很多线性代数,可以像光线投射在2d中一样实现。@AnkitMishra光线投射如何不涉及线性代数?是的,但它以一种非常简单的方式,它计算点P0、P1和P1的斜率,P2,并得出它是顺时针还是逆时针。所以,这就是为什么我要做的,比较斜率,看看直线上两点的方向是否不同,w.r.t,形成曲面的直线,然后直线与线段相交。但我不确定如何在3d中做到这一点space@AnkitMishra,光线投射总是在假设多面体是凸的基础上进行的,因此解决方案并不像您认为的那样一般。看看我的答案,了解一下没有凸性的一般多面体的复杂性对不起,这是对二维多边形的解释,原因很明显,我同意这个解决方案,但我所寻找的是一种通用算法,它不涉及很多线性代数,可以像光线投射在2d中一样实现。@AnkitMishra光线投射怎么不涉及线性代数?是的,但它以一种非常简单的方式实现,它计算点P0、P1和P1的斜率,P2,并得出它是顺时针还是逆时针。所以,这就是为什么我要做的,比较斜率,看看直线上两点的方向是否不同,w.r.t,形成曲面的直线,然后直线与线段相交。但我不确定如何在3d中做到这一点space@AnkitMishra,光线投射总是假设多面体是凸的,所以t
hat解决方案并不像您想象的那么普遍。请看我的答案,了解没有凸性的一般多面体的复杂性对不起,这是对二维多边形的明显解释。我同意这种方法,但它会给我点和无限平面之间的距离,因为我计算了交点,我知道它是零。但是我想检查点是否位于有限曲面上,这是由我知道的四组点构成的。我该怎么做?符号距离是无限平面和点之间的距离。每个平面上的边总是其他平面的交叉点。你只需要考虑每个表面是无限的。如果该点位于边的外侧,则表示其他一些无限曲面的另一侧。考虑2d的情况:你可以检查一个点是否在x=a,by=c,d的正方形内,也就是说:aSo,这是我的理解,如果我找到3d线和平面的交点,然后通过这样做检查它是否位于形成面的四个顶点内。设Px,y,z为直线和平面的交点,如果它位于由曲面端点形成的长方体中,即xlow,xhigh,ylow,yhigh,zlow,zhigh。这能证明这一点是正确的吗。我想它应该,只是想听听意见。我不明白。我的建议是,首先将每个曲面表示为法线和点,然后按照我的答案进行操作。没有一些线性代数,比如标量积投影,你真的不能做这样的事情。@AnkitMishra,不确定。听起来很有说服力——必须画出它,并考虑它会错过什么,如果有的话。尝试这两种方法,并与一些简单的情况进行比较,如果你需要使其快速,请进行纵断面。我同意这种方法,但它会给出点与无限平面之间的距离,因为我计算了交点,我知道它是零。但是我想检查点是否位于有限曲面上,这是由我知道的四组点构成的。我该怎么做?符号距离是无限平面和点之间的距离。每个平面上的边总是其他平面的交叉点。你只需要考虑每个表面是无限的。如果该点位于边的外侧,则表示其他一些无限曲面的另一侧。考虑2d的情况:你可以检查一个点是否在x=a,by=c,d的正方形内,也就是说:aSo,这是我的理解,如果我找到3d线和平面的交点,然后通过这样做检查它是否位于形成面的四个顶点内。设Px,y,z为直线和平面的交点,如果它位于由曲面端点形成的长方体中,即xlow,xhigh,ylow,yhigh,zlow,zhigh。这能证明这一点是正确的吗。我想它应该,只是想听听意见。我不明白。我的建议是,首先将每个曲面表示为法线和点,然后按照我的答案进行操作。没有一些线性代数,比如标量积投影,你真的不能做这样的事情。@AnkitMishra,不确定。听起来很有说服力——必须画出它,并考虑它会错过什么,如果有的话。尝试这两种方法,并与一些简单的情况进行比较,如果您需要使其快速。