Closed KenKenhehe closed 2 years ago
No, the current implementation doesn't provide a "PlanePrimitive" data structure, but the plane equation can be easily obtained by least-squares fitting of the points of a plane.
You can use the PrincipalAxes
in easy3d/core/principal_axes.h
to do the least-squares fitting.
Something like:
PrincipalAxes<3, float> pca;
pca.begin();
for each point p belonging to a plane: {
pca.add(p);
}
pca.end();
// the eigen vector corresponding to the smallest eigen value gives you the normal of the plane.
plane_normal = pca.axis(2);
// the centroid of the points is a point on the plane
plane_point = pca.center();
// then the plane can be constructed by
Plane3 plane(vec3(0, 0, 0), normal);
// and now you can get the plane parameters, please refer to `easy3d/core/plane.h`
I believe your question has been answered and thus I am closing this issue. Feel free to re-open it if this is not the case.
The Normal of the plane is different when I apply a positional translation to all of this point(for example when apply P(x, y, z) =>P(x = 1000, y+ 1000, z) for all the points in plane), is there a way for me to get the same normal no matter what the translation is?
For example:
PrincipalAxes<3, float> pca;
PrincipalAxes<3, float> pca2;
pca.begin();
for (auto v : plane_point_could->vertices()) {
pca.add(plane_point_could->position(v));
}
pca.end();
vec3 plane_normal = pca.axis(2);
vec3 plane_point = pca.center();
//modify the translation of all point
pca2.begin();
for (auto v : plane_point_could->vertices()) {
vec3 pos = plane_point_could->position(v);
pos.x += 1000;
pos.y += 1000;
pca2.add(pos);
}
pca2.end();
vec3 plane_normal2 = pca2.axis(2);
vec3 plane_point2 = pca2.center();
//plane_normal and plane_normal2 should be equal but is not???
How did you know the normals are different? Can you provide your computed normals? And if possible, please also attached your points in a file (preferably XYZ format).
I found out by simply printing out the normal in console:
vec3 plane_normal = pca.center();
std::cout << plane_normal << std::endl;
output normal for this model when it sits in (0,0,0) in blender(the yellow mesh is the plane I have extracted):
but when model is moved with y + 3000 and x + 3000: We can see the plane is no longer aligned with the point cloud data and the normal is:
Can you attach your point cloud file here?
The point could is converted by a .obj file taken just the x,y,z from each vertex github doesn't seem to support uploading obj file
Try making a simple plane in blender, and convert to point cloud by taking the xyz, and you should see similar behaviour when the location is x+3000, y+3000 and when it's (0,0,0)
The simplest would be the "XYZ" file, so each line simply 3 floating-point numbers representing the x, y, and z coordinates, e..g,,
2.3 3.322 32.98
123.2 67.77 72.24
...
Yes, but again the xyz file isn't the initial input, the .obj is, the point cloud is internally converted by this .obj file so I can not provide any xyz file
So how can I help? I want to help, but I need your problem data. So please save it in any format and send it to me (xyz is just the simplest format to look at).
Can you try PrincipalAxes<3, double> pca;
, i.e., use double
instead of float
.
I can imagine that when using float
, if your object coordinates are very close to the origin, adding 1000 to each coordinate and then summing up those for hundreds/thousands/millions of points could accumulate huge errors.
Sorry I won't be able to provide the actual obj due to company policy, I will have a try to see if it's really the double vs float issue, thanks
In file Tutorial_603_PlaneExtraction/viewer.cpp line 70
The PrimitivesRansac::detect() method only returns the number of primitive extracted, is there a way to access or retrive a "plane" data structure such that I can get the equation of the plane or get the x1y1, x2y2,x3y3 of a plane??
Appreciate the help