7

I have set P of point (3D) which are vertices of convex hull (every one). I looking for method for checking if given point p0 is NOT outside of this convex hull.

I'll have to repeat the checking it several times (for different p0). So if is possible to reuse part of computation it would be great.

On stackoverflow pages i found this: Find if a point is inside a convex hull for a set of points without computing the hull itself There are 2 aproche: First based on convex hull property - set of linear equations. Secound based on observation: "The point lies outside of the convex hull of the other points if and only if the direction of all the vectors from it to those other points are on less than one half of a circle/sphere/hypersphere around it."

Unfortunately I don't know how exactly can do it. First give me insoluble system of equations - 3 equation with n unknown (n>3). How can I sovle it? Did I do some mistake? In second approach I don't know how check this assumption.

Community
  • 1
  • 1
Marcel Słabosz
  • 139
  • 1
  • 2
  • 7
  • 1
    I am unsure if this will lead you in the right direction, but would like to mention it anyway: What if you morph this question into: How to compute the barycentric weights/coordinates of a point p0? If I remember correctly, for a point inside the convex hull, the barycentric weights will be in [0,1]... – André Nov 24 '11 at 19:36
  • 1
    I think my answer in [Find point is in polygon or not](http://stackoverflow.com/questions/4243042/c-sharp-point-in-polygon/4243079#4243079) can cover your problem, code is in C#. In fact it's not so hard to convert it to 3d, and is extremely fast. – Saeed Amiri Nov 24 '11 at 20:37
  • @Andre. It's exactly first approach which I mentioned in my question. If i will know how compute the weight vector it I can simple check if all pass conditions to be in [0, 1] interval. But how if I have set P (more then 3 elements) and only one point with 3 dimension. – Marcel Słabosz Nov 24 '11 at 23:02
  • @Saeed Amiri. THX. For me it's look like one step in Graham Algorithm for 2D, but i cant imagine how to move it to 3D. If you could give me some leads. PS. Sorry if I done some language mistakes, but english isn't my native language. Therefore please write answers in possibility simplest way . :) – Marcel Słabosz Nov 24 '11 at 23:02

3 Answers3

3

CGAL can easily do this test. Not only you could build the convex hull with CGAL, but you can quickly and easily determine whether a specific point is inside, on the surface or outside of the polyhedron.

A code snippet is shown below:

#include <CGAL/Simple_cartesian.h>
#include <CGAL/AABB_tree.h>
#include <CGAL/AABB_traits.h>
#include <CGAL/Polyhedron_3.h>
#include <CGAL/boost/graph/graph_traits_Polyhedron_3.h>
#include <CGAL/AABB_face_graph_triangle_primitive.h>
#include <CGAL/algorithm.h>
#include <CGAL/Side_of_triangle_mesh.h>

typedef CGAL::Simple_cartesian<double> K;
typedef K::Point_3 Point;
typedef CGAL::Polyhedron_3<K> Polyhedron;
typedef CGAL::AABB_face_graph_triangle_primitive<Polyhedron> Primitive;
typedef CGAL::AABB_traits<K, Primitive> Traits;
typedef CGAL::AABB_tree<Traits> Tree;
typedef CGAL::Side_of_triangle_mesh<Polyhedron, K> Point_inside;

bool pointInside(Polyhedron &polyhedron, Point &query) {
    // Construct AABB tree with a KdTree
    Tree tree(faces(polyhedron).first, faces(polyhedron).second, polyhedron);
    tree.accelerate_distance_queries();
    // Initialize the point-in-polyhedron tester
    Point_inside inside_tester(tree);

    // Determine the side and return true if inside!
    return inside_tester(query) == CGAL::ON_BOUNDED_SIDE;
}
Maghoumi
  • 3,295
  • 3
  • 33
  • 49
1

Assuming P is large and there are many p0, you should compute a 3D triangulation in which to do point location. This is a CGAL demo.

Per
  • 2,594
  • 12
  • 18
  • Yes. You suggest compute triangulation of convex hull and next try locate in which triangle (simplex) is contained **p0**. But if the convex hull tirangulation simplex is only plane triangele (not tetrahedron)? (I'm not sure.) Do this have a volume and not just the surface? There is no way to do not compute convex hull? THX for answer. – Marcel Słabosz Nov 24 '11 at 20:00
  • @MarcelSłabosz You want a division into 3D simplices. – Per Nov 24 '11 at 21:15
  • I'm defeated by GCAL. I can't install this library. First I download GCAL zip, and extract it. It's not sufficient to run. Next I download and extract boost, install Cmake and try use, but get some extra errors. Cmake give me this: CMake Error: Unable to find the executable at any of: E:/Library/CGAL-3.9/CMakeFiles/CMakeTmp/cmTryCompileExec.exe E:/Library/CGAL-3.9/CMakeFiles/CMakeTmp/Debug/cmTryCompileExec.exe E:/Library/CGAL-3.9/CMakeFiles/CMakeTmp/Development/cmTryCompileExec.exe Additionaly i get some problem with find boost_thread. – Marcel Słabosz Dec 08 '11 at 12:54
1

You can write down the points in the hull as columns in a matrix and then have a vector which tells you what combination of points to take:

(X1 X2)  (a)      (X1a + X2b)
(Y1 Y2)  (b)   =  (Y1a + Y2b)
(Z1 Z2)           (Z1a + Z2b)

To generate your target point you want to find a vector that solves this, subject to the constraints that the elements of the vector are between 0 and 1, and that the elements of the vector add up to 1. You can solve this sort of problem - if there is a solution - via linear programming, which might involve using the http://en.wikipedia.org/wiki/Simplex_algorithm.

There are a variety of tricks to get this into the strict form. Adding another row to the matrix will allow you to say a + b = 1. To force b <= 1 you could have b + q = 1 and q >= 0, although as pointed out by Ted Hopp below, in this case b <= 1 because a + b = 1, and both a and b are >= 0.

mcdowella
  • 19,301
  • 2
  • 19
  • 25
  • 1
    The constraint "between 0 and 1" can be relaxed to "non-negative". The additional constraint that they sum to 1 makes the upper limit redundant. – Ted Hopp Nov 25 '11 at 04:40