Code Monkey home page Code Monkey logo

convhull_3d's People

Contributors

alexharker avatar bkaradzic avatar leomccormack avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

convhull_3d's Issues

Co-linear points cause erratic behavior

I have a case where sometimes my incoming points (~1000 points) are on a regularly spaced grid. When this happens the plane_3d function in the main loop of convhull_3d_build (in sub-loop with the comment: "Add faces connecting horizon to the new point") can return wildly varying values for cfi and dfi.

This appears to propagate (probably because I have so many colinear points) and eventually causes the program to fail. This failure is intermittent since, strangely, I can do:

std::vector< ch_vertex > vertices;
int *faceIndices= NULL;
int nFaces;
...
convhull_3d_build( &vertices[0], vertices.size(), &faceIndices, &nFaces); //Succeeds
convhull_3d_build( &vertices[0], vertices.size(), &faceIndices, &nFaces); //Fails
convhull_3d_build( &vertices[0], vertices.size(), &faceIndices, &nFaces); //Succeeds
...

So it's possible that something stranger is going on. This fail, succeed, fail, pattern continues even if I free faceIndices between each run.

EDIT:

Additionally, I can shake up the pattern by running

std::vector< ch_vertex > easy_vertices;
std::vector< ch_vertex > vertices;
int *faceIndices= NULL;
int nFaces;
...
convhull_3d_build(&easy_vertices[0], easy_vertices.size(), &faceIndices, &nFaces); //Succeeds
convhull_3d_build( &vertices[0], vertices.size(), &faceIndices, &nFaces); //Fails
convhull_3d_build( &vertices[0], vertices.size(), &faceIndices, &nFaces); //Succeeds
convhull_3d_build( &vertices[0], vertices.size(), &faceIndices, &nFaces); //Fails
...

where easy_vertices is some collection of points without any co-linear points.

Robust predicates

Thanks for your work on this algorithm and for making it available.

Have you considered modifying the implementation to use robust geometric predicates?

The hope would be that it would allow you to avoid the random perturbation of points by CH_NOISE_VAL.

The comments indicate that the perturbation is needed to avoid problems with coincident points. If I guarantee that I do not pass any coincident points to convhull, should it be guaranteed to work? (I.e. is it sensitive to other kinds of degeneracies -- co-linear points, or co-planar points?)

Bug when using single precsion

I ran into issue where calling function convhull_3d_build multiple times with the same input causes different results. The bug exist only when used with CONVHULL_3D_USE_SINGLE_PRECISION.

Repro:

#include <stdlib.h>

#define CONVHULL_3D_ENABLE
#define CONVHULL_3D_USE_SINGLE_PRECISION /* optional */
#include "../convhull_3d.h"

int main(int argc, const char * argv[])
{
	ch_vec3 vert[] =
	{
		{  4.243597,  2.029179, -0.815667 },
		{  4.417669,  0.039982, -0.928770 },
		{ -2.428492,  1.198822,  3.519505 },
		{ -2.254420, -0.790374,  3.406402 },
		{  3.153918,  2.029179, -2.492747 },
		{  3.327990,  0.039982, -2.605850 },
		{ -3.518171,  1.198822,  1.842424 },
		{ -3.344099, -0.790374,  1.729321 },
	};

	for (int ii = 0; ii < 10; ++ii)
	{
		printf("%d\n", ii);
		int* indices = NULL;
		int numFaces;
		convhull_3d_build(vert, 8, &indices, &numFaces);
		free(indices);
	}

	return 0;
}

Program hits this assert:

assert(detA>0.0);

> gcc bug.c -lm -o bug; and ./bug
0
1
2
bug: ../convhull_3d.h:923: convhull_3d_build: Assertion `detA>0.0' failed.

.obj files are out of date

It looks like 6f61a29 changes the output of the test code due to the difference in the random numbers. the committed files haven't been updated in some time (there's something creating a minor accuracy difference in one file before that, but this seems very minor)

I expected that the difference might just be in terms of ordering, but in convhull_airboat.obj the first change looks quite large (in that the first two values stay the same, but the Z value changes radically:

-v 7.711631 -1.639892 -2.027359
+v 7.711631 -1.639892 2.043359

I couldn't find the old value of z ==-2.027359 or anything particularly close to it elsewhere in the new file (there are also many other changes, so tracing all of them is not viable). Intuitively that doesn't seem right, but I tested rnd() and it is producing values in the range 0-1 as I'd expect, and I can't see how it could be affecting values to this degree.

I'm not sure if this needs investigating. It's simple enough to commit the results if they are valid (which would be useful as changes (or not) in the repo can then be used to verify further changes to the codebase), but I didn't want to make a PR for this without raising the issue of the changed values first.

Running infinite loop, unexpected results

At first, thanks for this simple drop in library.
Works well mostly, but some edge (not very) cases were found.
Sometimes it randomly runs into long or even infinite loop; likely in case of odd points, located precisely on resulting faces
+ using 30-50Mb of memory during this with just a handful of points.
It's simply reproducible with such geometry:
11
(merging its vertices)

Which are: (-744 3300 7552) (-808 3300 7552) (-808 3364 7552) (-744 3364 7552) (-744 3364 7551) (-808 3364 7551) (-744 3300 7551) (-808 3300 7551) (-1000 3300 7552) (-1064 3300 7552) (-1064 3364 7552) (-1000 3364 7552) (-1000 3364 7551) (-1064 3364 7551) (-1000 3300 7551) (-1064 3300 7551) (-872 3300 7552) (-936 3300 7552) (-936 3364 7552) (-872 3364 7552) (-872 3364 7551) (-936 3364 7551) (-872 3300 7551) (-936 3300 7551) (-744 3428 7552) (-808 3428 7552) (-808 3492 7552) (-744 3492 7552) (-744 3492 7551) (-808 3492 7551) (-744 3428 7551) (-808 3428 7551) (-744 3556 7552) (-808 3556 7552) (-808 3620 7552) (-744 3620 7552) (-744 3620 7551) (-808 3620 7551) (-744 3556 7551) (-808 3556 7551) (-1000 3428 7552) (-1064 3428 7552) (-1064 3492 7552) (-1000 3492 7552) (-1000 3492 7551) (-1064 3492 7551) (-1000 3428 7551) (-1064 3428 7551) (-872 3428 7552) (-936 3428 7552) (-936 3492 7552) (-872 3492 7552) (-872 3492 7551) (-936 3492 7551) (-872 3428 7551) (-936 3428 7551) (-1000 3556 7552) (-1064 3556 7552) (-1064 3620 7552) (-1000 3620 7552) (-1000 3620 7551) (-1064 3620 7551) (-1000 3556 7551) (-1064 3556 7551) (-872 3556 7552) (-936 3556 7552) (-936 3620 7552) (-872 3620 7552) (-872 3620 7551) (-936 3620 7551) (-872 3556 7551) (-936 3556 7551)

Noticeable things are:

  • axially aligned planes
  • points are on integer grid (same rotated geometry runs well)
  • it's height is just 1unit (using ~100 makes things better) (likely volume proportions matter)
  • bug hardening after moving objects to greater coordinates

Further playing around also has shown consistency issue:
this:
22

(points) (-7671.07 -3235.66 1350.5) (-7966.3 -3165.18 1528.24) (-7860.47 -3017.46 1558.03) (-7565.25 -3087.95 1380.28) (-7565.25 -3089.2 1375.66) (-7860.47 -3018.71 1553.41) (-7671.07 -3236.91 1345.87) (-7966.3 -3166.43 1523.62) (-7333.67 -3316.21 1067.36) (-7628.9 -3245.73 1245.1) (-7523.07 -3098.02 1274.89) (-7227.85 -3168.5 1097.15) (-7227.85 -3169.75 1092.52) (-7523.07 -3099.26 1270.27) (-7333.67 -3317.46 1062.74) (-7628.9 -3246.98 1240.48)

randomly turns into this:
33
while should be this:
44

Same happens with the first example (losing one or more of vertices), but infinite loop is more probable.

Use specs

  • compiling as c++ with gcc under win32 and win64
  • precision is double; using float makes named issues to happen way more often; using long double haven't improved the state
  • CBLAS is not used
    Trying to tune noise value just shown, that current value is well ballancing in between of these two issues.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.