New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ST_3DDistance: Handle invalid polygons #338
Conversation
liblwgeom/measures3d.c
Outdated
return 0.0; | ||
|
||
f = DOT(pl->pv, v1); | ||
if (fabs(f) < DBL_EPSILON) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
didn't we have FP_IS_ZERO for such things?
liblwgeom/measures3d.c
Outdated
@@ -58,7 +59,7 @@ get_3dcross_product(VECTOR3D *v1,VECTOR3D *v2, VECTOR3D *v) | |||
v->y=(v1->z*v2->x)-(v1->x*v2->z); | |||
v->z=(v1->x*v2->y)-(v1->y*v2->x); | |||
|
|||
return LW_TRUE; | |||
return ((fabs(v->x) > DBL_EPSILON) || (fabs(v->y) > DBL_EPSILON) || (fabs(v->z) > DBL_EPSILON)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
will FP_IS_ZERO be okayish here?
https://postgis.net/docs/doxygen/2.5/d2/d54/liblwgeom__internal_8h_af2b852b5a876cb6f5a7881ba9017fe4a.html
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 I didn't remember about that macro
@@ -1133,63 +1164,46 @@ the plane is stored as a point in plane (plane.pop) and a normal vector (plane.p | |||
int | |||
define_plane(POINTARRAY *pa, PLANE3D *pl) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure about the simplification of define_plane. The reason I did it this complicated was an attempt to avoid small numbers giving large errors. If the first 3 points is very close to each other a very small error (floating point error) can make the plane quite wrong which can give quite big error if the polygon is large. This is far away in my head no, since it was a long time ago. I will look more into it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we could try to add some test with really close numbers (but bigger than FP_TOLERANCE) to see if it reproduces it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I think we need to think about stability for cases like that and also "dirty" polygons, that has more or less coplanar vertex points.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BTW, since now when we can't calculate the plane it defaults to checking the external ring itself as a line, we could add an extra check in define_plane
and ignore any point whose distance to the previous ones is less than FP_TOLERANCE or something like this.
Here is the thoughts behind how the define_plane function is designed now. |
I've modified my |
Yes, I think it looks good. If I understand it right the functionality is the same as before, but you use a fixed 3 samples instead of my walabout ending with 3-5 samples. Is that correct? |
Looking into it again I see that I'm using npoints instead of (npoints - 1) so I'm repeating the first point (equal to last). I'll change that before merging. Int division always truncates. Floor would just cast it to float and back, which hopefully will be optimized away by the compiler and do nothing ;D |
define_plane
to calculate the plane with the first 3 non collinear points of the ptarray.Trac issue: https://trac.osgeo.org/postgis/ticket/4246