如何在点云中获取立方体的对角线?
How to get diagonal line of a cube in a point cloud?
我有一个立方体的点云。我用 random() 创建了它,所以所有 x、y、z 点都在 0 和 1 之间。我是这样创建立方体的。
import numpy as np
import open3d
import random
listPoints = []
for i in range(10000):
x = random.random()
y = random.random()
z = random.random()
listPoints.append([x,y,z])
arrayPoints = np.asarray(listPoints)
point_cloud = open3d.PointCloud()
point_cloud.points = open3d.Vector3dVector(arrayPoints)
open3d.draw_geometries([point_cloud])
现在我想得到对角线上的点。我现在如何让点垂直于一个点。我需要根据度数乘以一些值,但我不知道该怎么做。我用来垂直于立方体中间的代码:(Y 是 0.5,所以我保持静态并检查所有具有 0.5 Y 值的点)
listPoints2 = []
minimumY = 0.5 - 0.02
maximumY = 0.5 + 0.02
for i in range(10000):
if(listPoints[i][1] < maximumY and listPoints[i][1] > minimumY):
listPoints2.append([listPoints[i][0],listPoints[i][1],listPoints[i][2]])
arrayPoints2 = np.asarray(listPoints2)
point_cloud2 = open3d.PointCloud()
point_cloud2.points = open3d.Vector3dVector(arrayPoints2)
open3d.draw_geometries([point_cloud2])
我的最终输出有垂直点。我希望它像对角线一样倾斜。
我应该用什么乘以我的值以获得对角线?
你需要的是计算一个点到轴的垂直距离见:
由此您只需测试所有点是否足够接近立方体的 4 条对角线。在 C++ 中(抱歉不是 Python 编码员)它看起来像这样:
//---------------------------------------------------------------------------
const int n=10000; // points
const int n3=n+n+n; // points*dimensions
double pnt[n3]; // points x,y,z ...
DWORD col[n]; // colors rgba, ...
//---------------------------------------------------------------------------
double distance_point_axis(double *p,double *p0,double *dp)
{
int i;
double l,d,q[3];
for (i=0;i<3;i++) q[i]=p[i]-p0[i]; // q = p-p0
for (l=0.0,i=0;i<3;i++) l+=dp[i]*dp[i]; // l = |dp|^2
for (d=0.0,i=0;i<3;i++) d+=q[i]*dp[i]; // d = dot(q,dp)
if (l<1e-10) d=0.0; else d/=l; // d = dot(q,dp)/|dp|^2
for (i=0;i<3;i++) q[i]-=dp[i]*d; // q=q-dp*dot(q,dp)/|dp|^2
for (l=0.0,i=0;i<3;i++) l+=q[i]*q[i]; l=sqrt(l); // l = |q|
return l;
}
//---------------------------------------------------------------------------
void pnt_init()
{
Randomize();
int i,i3,j;
double r=0.1; // radius of diagonals cylinders
double diag[4*6]=
{
// p0 dp
0.0,0.0,0.0, +1.0,+1.0,+1.0, // diagonal 1
0.0,1.0,0.0, +1.0,-1.0,+1.0, // diagonal 2
1.0,0.0,0.0, -1.0,+1.0,+1.0, // diagonal 3
1.0,1.0,0.0, -1.0,-1.0,+1.0, // diagonal 4
};
// compute some uniformly random points <0,1>
for (i3=0;i3<n3;i3++) pnt[i3]=Random();
// compute color
for (i=0,i3=0;i<n;i++,i3+=3)
{
// graysh
col[i]=0x00303030;
// diagonals
j=0;
if (distance_point_axis(pnt+i3,diag+j+0,diag+j+3)<r) col[i]|=0x00FF0000; j+=6;
if (distance_point_axis(pnt+i3,diag+j+0,diag+j+3)<r) col[i]|=0x0000FF00; j+=6;
if (distance_point_axis(pnt+i3,diag+j+0,diag+j+3)<r) col[i]|=0x000000FF; j+=6;
if (distance_point_axis(pnt+i3,diag+j+0,diag+j+3)<r) col[i]|=0x00FF00FF; j+=6;
}
}
//---------------------------------------------------------------------------
void gl_draw()
{
int i,i3;
static double ang=0.0; ang+=2.5; if (ang>360.0) ang-=360.0;
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
glDisable(GL_TEXTURE_2D);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(-0.5,-0.5,-5.0);
glRotatef(ang,0.5,0.5,0.5);
// render points froma list
glBegin(GL_POINTS);
for (i=0,i3=0;i<n;i++,i3+=3)
{
glColor4ubv((BYTE*)(col+i));
glVertex3dv(pnt+i3);
}
glEnd();
// glFlush();
glFinish();
SwapBuffers(hdc);
}
//---------------------------------------------------------------------------
所以我声明了 4 个轴 diag[4*6]
(起点和方向向量)并且只设置每个点的颜色接近预定义的 RGB 颜色...
此处预览:
和GIF动图:
如果你想要更简单的东西,那么立方体的主对角线是
x = y = z
所以简单测试一下
fabs(x-y)+fabs(x-z)+fabs(y-z) <= 1e-2
对于每个点...其他对角线只是镜像所以只需将镜像 coordinate
替换为 1-coordinate
我有一个立方体的点云。我用 random() 创建了它,所以所有 x、y、z 点都在 0 和 1 之间。我是这样创建立方体的。
import numpy as np
import open3d
import random
listPoints = []
for i in range(10000):
x = random.random()
y = random.random()
z = random.random()
listPoints.append([x,y,z])
arrayPoints = np.asarray(listPoints)
point_cloud = open3d.PointCloud()
point_cloud.points = open3d.Vector3dVector(arrayPoints)
open3d.draw_geometries([point_cloud])
现在我想得到对角线上的点。我现在如何让点垂直于一个点。我需要根据度数乘以一些值,但我不知道该怎么做。我用来垂直于立方体中间的代码:(Y 是 0.5,所以我保持静态并检查所有具有 0.5 Y 值的点)
listPoints2 = []
minimumY = 0.5 - 0.02
maximumY = 0.5 + 0.02
for i in range(10000):
if(listPoints[i][1] < maximumY and listPoints[i][1] > minimumY):
listPoints2.append([listPoints[i][0],listPoints[i][1],listPoints[i][2]])
arrayPoints2 = np.asarray(listPoints2)
point_cloud2 = open3d.PointCloud()
point_cloud2.points = open3d.Vector3dVector(arrayPoints2)
open3d.draw_geometries([point_cloud2])
我的最终输出有垂直点。我希望它像对角线一样倾斜。
我应该用什么乘以我的值以获得对角线?
你需要的是计算一个点到轴的垂直距离见:
由此您只需测试所有点是否足够接近立方体的 4 条对角线。在 C++ 中(抱歉不是 Python 编码员)它看起来像这样:
//---------------------------------------------------------------------------
const int n=10000; // points
const int n3=n+n+n; // points*dimensions
double pnt[n3]; // points x,y,z ...
DWORD col[n]; // colors rgba, ...
//---------------------------------------------------------------------------
double distance_point_axis(double *p,double *p0,double *dp)
{
int i;
double l,d,q[3];
for (i=0;i<3;i++) q[i]=p[i]-p0[i]; // q = p-p0
for (l=0.0,i=0;i<3;i++) l+=dp[i]*dp[i]; // l = |dp|^2
for (d=0.0,i=0;i<3;i++) d+=q[i]*dp[i]; // d = dot(q,dp)
if (l<1e-10) d=0.0; else d/=l; // d = dot(q,dp)/|dp|^2
for (i=0;i<3;i++) q[i]-=dp[i]*d; // q=q-dp*dot(q,dp)/|dp|^2
for (l=0.0,i=0;i<3;i++) l+=q[i]*q[i]; l=sqrt(l); // l = |q|
return l;
}
//---------------------------------------------------------------------------
void pnt_init()
{
Randomize();
int i,i3,j;
double r=0.1; // radius of diagonals cylinders
double diag[4*6]=
{
// p0 dp
0.0,0.0,0.0, +1.0,+1.0,+1.0, // diagonal 1
0.0,1.0,0.0, +1.0,-1.0,+1.0, // diagonal 2
1.0,0.0,0.0, -1.0,+1.0,+1.0, // diagonal 3
1.0,1.0,0.0, -1.0,-1.0,+1.0, // diagonal 4
};
// compute some uniformly random points <0,1>
for (i3=0;i3<n3;i3++) pnt[i3]=Random();
// compute color
for (i=0,i3=0;i<n;i++,i3+=3)
{
// graysh
col[i]=0x00303030;
// diagonals
j=0;
if (distance_point_axis(pnt+i3,diag+j+0,diag+j+3)<r) col[i]|=0x00FF0000; j+=6;
if (distance_point_axis(pnt+i3,diag+j+0,diag+j+3)<r) col[i]|=0x0000FF00; j+=6;
if (distance_point_axis(pnt+i3,diag+j+0,diag+j+3)<r) col[i]|=0x000000FF; j+=6;
if (distance_point_axis(pnt+i3,diag+j+0,diag+j+3)<r) col[i]|=0x00FF00FF; j+=6;
}
}
//---------------------------------------------------------------------------
void gl_draw()
{
int i,i3;
static double ang=0.0; ang+=2.5; if (ang>360.0) ang-=360.0;
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
glDisable(GL_TEXTURE_2D);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(-0.5,-0.5,-5.0);
glRotatef(ang,0.5,0.5,0.5);
// render points froma list
glBegin(GL_POINTS);
for (i=0,i3=0;i<n;i++,i3+=3)
{
glColor4ubv((BYTE*)(col+i));
glVertex3dv(pnt+i3);
}
glEnd();
// glFlush();
glFinish();
SwapBuffers(hdc);
}
//---------------------------------------------------------------------------
所以我声明了 4 个轴 diag[4*6]
(起点和方向向量)并且只设置每个点的颜色接近预定义的 RGB 颜色...
此处预览:
和GIF动图:
如果你想要更简单的东西,那么立方体的主对角线是
x = y = z
所以简单测试一下
fabs(x-y)+fabs(x-z)+fabs(y-z) <= 1e-2
对于每个点...其他对角线只是镜像所以只需将镜像 coordinate
替换为 1-coordinate