 # finding if point is in 3d poly in python

• Last Update :
• Techknowledgy :

I checked out the QHull version (from above) and the linear programming solution (e.g. see this question). So far, using QHull seems to be the best bet, although I might be missing some optimizations with the `scipy.spatial` LP.

```import numpy
import numpy.random
from numpy
import zeros, ones, arange, asarray, concatenate
from scipy.optimize
import linprog

from scipy.spatial
import ConvexHull

def pnt_in_cvex_hull_1(hull, pnt):
''
'
Checks
if `pnt`
is inside the convex hull.
`hull`--a QHull ConvexHull object
`pnt`--point array of shape(3, )
''
'
new_hull = ConvexHull(concatenate((hull.points, [pnt])))
if numpy.array_equal(new_hull.vertices, hull.vertices):
return True
return False

def pnt_in_cvex_hull_2(hull_points, pnt):
''
'
Given a set of points that defines a convex hull, uses simplex LP to determine
whether point lies within hull.
`hull_points`--(N, 3) array of points defining the hull `pnt`--point array of shape(3, )
''
'
N = hull_points.shape
c = ones(N)
A_eq = concatenate((hull_points, ones((N, 1))), 1).T # rows are x, y, z, 1
b_eq = concatenate((pnt, (1, )))
result = linprog(c, A_eq = A_eq, b_eq = b_eq)
if result.success and c.dot(result.x) == 1.:
return True
return False

points = numpy.random.rand(8, 3)
hull = ConvexHull(points, incremental = True)
hull_points = hull.points[hull.vertices,: ]
new_points = 1. * numpy.random.rand(1000, 3)```

where

```% % time
in_hull_1 = asarray([pnt_in_cvex_hull_1(hull, pnt) for pnt in new_points], dtype = bool)```

produces:

```CPU times: user 268 ms, sys: 4 ms, total: 272 ms
Wall time: 268 ms```

produces

```CPU times: user 3.83 s, sys: 16 ms, total: 3.85 s
Wall time: 3.85 s```

Well, the most efficient solution, also comes from `scipy.spatial`, but makes use of `Delaunay` tesselation:

```from scipy.spatial
import Delaunay

Delaunay(poly).find_simplex(point) >= 0 # True
if point lies within poly```

First for one point:

```import numpy
from scipy.spatial
import ConvexHull, Delaunay

def in_poly_hull_single(poly, point):
hull = ConvexHull(poly)
new_hull = ConvexHull(np.concatenate((poly, [point])))
return np.array_equal(new_hull.vertices, hull.vertices)

poly = np.random.rand(65, 3)
point = np.random.rand(3)

%
timeit in_poly_hull_single(poly, point) %
timeit Delaunay(poly).find_simplex(point) >= 0```

Result:

```2.63 ms± 280 µs per loop(mean± std.dev.of 7 runs, 100 loops each)
1.49 ms± 153 µs per loop(mean± std.dev.of 7 runs, 100 loops each)```

What I am doing is using scipy.spatial.ConvexHull like shongololo suggested, but with a slight twist. I am making a 3D convex hull of the point cloud, and then adding the point I am checking into a "new" point cloud and making a new 3D convex hull. If they are identical then I am assuming that it must be inside the convex hull. I would still appreciate if someone has a more robust way of doing this, as I see this as a bit hackish. The code would look something like as follows:

```from scipy.spatial
import ConvexHull

def pnt_in_pointcloud(points, new_pt):
hull = ConvexHull(points)
new_pts = points + new_pt
new_hull = ConvexHull(new_pts)
if hull == new_hull:
return True
else:
return False```

Suggestion : 2

In summary, Delaunay is not only much anycodings_3d faster, but also very concise in the anycodings_3d code.,Thanks to all that have commented. For anycodings_3d anyone looking for an answer for this, I anycodings_3d have found one that works for some cases anycodings_3d (but not complicated cases). ,This works, because -1 is returned by anycodings_3d .find_simplex(point) if the point is not anycodings_3d in any of the simplices (i.e. outside of anycodings_3d the triangulation). (Note: it works in N anycodings_3d dimensions, not only 2/3D.),I am trying to find out whether a point is anycodings_polygons in a 3D poly. I had used another script I anycodings_polygons found online to take care of a lot of the 2D anycodings_polygons problems using ray casting. I was wondering anycodings_polygons how this could be changed to work for 3D anycodings_polygons polygons. I'm not going to be looking at anycodings_polygons really strange polygons with a lot of anycodings_polygons concavity or holes or anything. Here is the anycodings_polygons 2D implementation in python:

I am trying to find out whether a point is anycodings_polygons in a 3D poly. I had used another script I anycodings_polygons found online to take care of a lot of the 2D anycodings_polygons problems using ray casting. I was wondering anycodings_polygons how this could be changed to work for 3D anycodings_polygons polygons. I'm not going to be looking at anycodings_polygons really strange polygons with a lot of anycodings_polygons concavity or holes or anything. Here is the anycodings_polygons 2D implementation in python:

```def point_inside_polygon(x, y, poly):

n = len(poly)
inside = False

p1x, p1y = poly
for i in range(n + 1):
p2x, p2y = poly[i % n]
if y > min(p1y, p2y):
if y <= max(p1y, p2y):
if x <= max(p1x, p2x):
if p1y != p2y:
xinters = (y - p1y) * (p2x - p1x) / (p2y - p1y) + p1x
if p1x == p2x or x <= xinters:
inside = not inside
p1x, p1y = p2x, p2y

return inside```

I checked out the QHull version (from anycodings_3d above) and the linear programming anycodings_3d solution (e.g. see this question). So anycodings_3d far, using QHull seems to be the best anycodings_3d bet, although I might be missing some anycodings_3d optimizations with the scipy.spatial LP.

```import numpy
import numpy.random
from numpy
import zeros, ones, arange, asarray, concatenate
from scipy.optimize
import linprog

from scipy.spatial
import ConvexHull

def pnt_in_cvex_hull_1(hull, pnt):
''
'
Checks
if `pnt`
is inside the convex hull.
`hull`--a QHull ConvexHull object
`pnt`--point array of shape(3, )
''
'
new_hull = ConvexHull(concatenate((hull.points, [pnt])))
if numpy.array_equal(new_hull.vertices, hull.vertices):
return True
return False

def pnt_in_cvex_hull_2(hull_points, pnt):
''
'
Given a set of points that defines a convex hull, uses simplex LP to determine
whether point lies within hull.
`hull_points`--(N, 3) array of points defining the hull `pnt`--point array of shape(3, )
''
'
N = hull_points.shape
c = ones(N)
A_eq = concatenate((hull_points, ones((N, 1))), 1).T # rows are x, y, z, 1
b_eq = concatenate((pnt, (1, )))
result = linprog(c, A_eq = A_eq, b_eq = b_eq)
if result.success and c.dot(result.x) == 1.:
return True
return False

points = numpy.random.rand(8, 3)
hull = ConvexHull(points, incremental = True)
hull_points = hull.points[hull.vertices,: ]
new_points = 1. * numpy.random.rand(1000, 3)```

where

```% % time
in_hull_1 = asarray([pnt_in_cvex_hull_1(hull, pnt) for pnt in new_points], dtype = bool)```

produces:

```CPU times: user 268 ms, sys: 4 ms, total: 272 ms
Wall time: 268 ms```

produces

```CPU times: user 3.83 s, sys: 16 ms, total: 3.85 s
Wall time: 3.85 s```

Well, the most efficient solution, also anycodings_3d comes from scipy.spatial, but makes use anycodings_3d of Delaunay tesselation:

```from scipy.spatial
import Delaunay

Delaunay(poly).find_simplex(point) >= 0 # True
if point lies within poly```

First for one point:

```import numpy
from scipy.spatial
import ConvexHull, Delaunay

def in_poly_hull_single(poly, point):
hull = ConvexHull(poly)
new_hull = ConvexHull(np.concatenate((poly, [point])))
return np.array_equal(new_hull.vertices, hull.vertices)

poly = np.random.rand(65, 3)
point = np.random.rand(3)

%
timeit in_poly_hull_single(poly, point) %
timeit Delaunay(poly).find_simplex(point) >= 0```

Result:

```2.63 ms Ã‚ Â± 280 Ã‚ Âµs per loop(mean Ã‚ Â± std.dev.of 7 runs, 100 loops each)
1.49 ms Ã‚ Â± 153 Ã‚ Âµs per loop(mean Ã‚ Â± std.dev.of 7 runs, 100 loops each)```

What I am doing is using anycodings_3d scipy.spatial.ConvexHull like shongololo anycodings_3d suggested, but with a slight twist. I anycodings_3d am making a 3D convex hull of the point anycodings_3d cloud, and then adding the point I am anycodings_3d checking into a "new" point cloud and anycodings_3d making a new 3D convex hull. If they anycodings_3d are identical then I am assuming that it anycodings_3d must be inside the convex hull. I would anycodings_3d still appreciate if someone has a more anycodings_3d robust way of doing this, as I see this anycodings_3d as a bit hackish. The code would look anycodings_3d something like as follows:

```from scipy.spatial
import ConvexHull

def pnt_in_pointcloud(points, new_pt):
hull = ConvexHull(points)
new_pts = points + new_pt
new_hull = ConvexHull(new_pts)
if hull == new_hull:
return True
else:
return False```

Suggestion : 3

20th January, 2016: Initial version

1._
```gp = [p1, p2, p3, p4, p5, p6, p7, p8];
gpInst = GeoPolygon(gp);
procInst = GeoPolygonProc(gpInst);```
2._
```if (x > procInst.x0 and x < procInst.x1 and y > procInst.y0 and y < procInst.y1 and z > procInst.z0 and z < procInst.z1):
if (procInst.PointInside3DPolygon(x, y, z)):```
3._
```class GeoPoint(object):
def __init__(self, x, y, z):
self.x = x
self.y = y
self.z = z
return GeoPoint(self.x + p.x, self.y + p.y, self.z + p.z)```
5._
```from GeoVector
import *

class GeoPlane(object):

def __init__(self, a, b, c, d):
self.a = a
self.b = b
self.c = c
self.d = d

@staticmethod
def Create(p0, p1, p2): # p0, p1, p2: GeoPoint

v = GeoVector(p0, p1)
u = GeoVector(p0, p2)

# normal vector
n = u * v;

a = n.x
b = n.y
c = n.z
d = -(a * p0.x + b * p0.y + c * p0.z)

return GeoPlane(a, b, c, d)

def __neg__(self):
return GeoPlane(-self.a, -self.b, -self.c, -self.d)

def __mul__(self, pt): # pt: GeoPoint
return (self.a * pt.x + self.b * pt.y + self.c * pt.z + self.d)```
6._
```class GeoFace(object):

# ptList: vertice GeoPoint Array
# idxList: vertice index Integer Array
def __init__(self, ptList, idxList):

#alloc instance array memory
self.__v = [] # vertice point array
self.__idx = [] # vertice index array

self.__n = len(ptList) # number of vertices

for i in range(0, self.__n):
self.__v.append(ptList[i])
self.__idx.append(idxList[i])

@property
def v(self):
return self.__v

@property
def idx(self):
return self.__idx

@property
def n(self):
return self.__n```

Suggestion : 4

Last Updated : 26 Jul, 2022

```No
Yes
Yes
Yes
No
No```

Suggestion : 5

How to check if point is inside a polygon?,It is also possible to do PIP other way around, i.e. to check if polygon contains a point:,Let’s check if those points are within the polygon,using a function called .within() that checks if a point is within a polygon

```from shapely.geometry
import Point, Polygon

# Create Point objects
p1 = Point(24.952242, 60.1696017)
p2 = Point(24.976567, 60.1612500)

# Create a Polygon
coords = [(24.950899, 60.169158), (24.953492, 60.169158), (24.953510, 60.170104), (24.950958, 60.169990)]
poly = Polygon(coords)```
```# Let 's check what we have
In: print(p1)
POINT(24.952242 60.1696017)

In: print(p2)
POINT(24.976567 60.16125)

In: print(poly)
POLYGON((24.950899 60.169158, 24.953492 60.169158, 24.95351 60.170104, 24.950958 60.16999, 24.950899 60.169158))```
```# Check
if p1 is within the polygon using the within
function
In: p1.within(poly)
Out: True

# Check
if p2 is within the polygon
In: p2.within(poly)
Out: False```
```# Our point
In: print(p1)
POINT(24.952242 60.1696017)

# The centroid
In: print(poly.centroid)
POINT(24.95224242849236 60.16960179038188)```
```# Does polygon contain p1 ?
In : poly.contains(p1)
Out: True

# Does polygon contain p2 ?
In : poly.contains(p2)
Out: False```
```from shapely.geometry
import LineString, MultiLineString

# Create two lines
line_a = LineString([(0, 0), (1, 1)])
line_b = LineString([(1, 1), (0, 2)])```