# Convex hull of set of points lying on a 3D plane

**URL:** https://discourse.vtk.org/t/convex-hull-of-set-of-points-lying-on-a-3d-plane/11277
**Category:** Support
**Created:** [April 24, 2023, 5:09am UTC](https://discourse.vtk.org/t/convex-hull-of-set-of-points-lying-on-a-3d-plane/11277 "2023-04-24T05:09:10Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![kruvva](https://discourse.vtk.org/letter_avatar_proxy/v4/letter/k/a4c791/32.png) [@kruvva](https://discourse.vtk.org/u/kruvva)
#### Post date: [April 24, 2023, 5:09am UTC](https://discourse.vtk.org/t/convex-hull-of-set-of-points-lying-on-a-3d-plane/11277/1 "2023-04-24T05:09:10Z")

</div>

Hi, How do I find the boundary of point cloud lying on a 3D plane. This plane is not parallel to XY or YZ or ZX planes. I am looking for the polygon on the plane that surrounds the point cloud. vtkConvexHull2D is supressing the z-coordinates.

---

<div class="post-metadata">

### Author: ![dcthomp](https://discourse.vtk.org/user_avatar/discourse.vtk.org/dcthomp/32/60_2.png) [@dcthomp](https://discourse.vtk.org/u/dcthomp)
#### Post date: [April 24, 2023, 6:27pm UTC](https://discourse.vtk.org/t/convex-hull-of-set-of-points-lying-on-a-3d-plane/11277/2 "2023-04-24T18:27:14Z")

</div>

We don’t have a filter that easily projects points to a plane, but that is what’s required before you can use vtkConvexHull2D.

The closest thing I can think of would be to use `vtkPCAStatistics` to compute the first two eigenvectors of your point cloud and use these as the _x_ and _y_ axes of the projected cloud.

---

<div class="post-metadata">

### Author: ![will.schroeder](https://discourse.vtk.org/user_avatar/discourse.vtk.org/will.schroeder/32/233_2.png) [@will.schroeder](https://discourse.vtk.org/u/will.schroeder)
#### Post date: [April 24, 2023, 7:00pm UTC](https://discourse.vtk.org/t/convex-hull-of-set-of-points-lying-on-a-3d-plane/11277/3 "2023-04-24T19:00:02Z")

</div>

Did you try: Filters/Points/vtkProjectPointsToPlane?

---

<div class="post-metadata">

### Author: ![dcthomp](https://discourse.vtk.org/user_avatar/discourse.vtk.org/dcthomp/32/60_2.png) [@dcthomp](https://discourse.vtk.org/u/dcthomp)
#### Post date: [April 24, 2023, 7:29pm UTC](https://discourse.vtk.org/t/convex-hull-of-set-of-points-lying-on-a-3d-plane/11277/4 "2023-04-24T19:29:31Z")

</div>

Derp. I have not seen that one before.

---

<div class="post-metadata">

### Author: ![kruvva](https://discourse.vtk.org/letter_avatar_proxy/v4/letter/k/a4c791/32.png) [@kruvva](https://discourse.vtk.org/u/kruvva)
#### Post date: [April 25, 2023, 11:42pm UTC](https://discourse.vtk.org/t/convex-hull-of-set-of-points-lying-on-a-3d-plane/11277/5 "2023-04-25T23:42:39Z")

</div>

Thanks Will. That worked.  
After I compute the ConvexHull2D, I project it back to the plane.

I see problem with ConvexHull2D in some cases when the point cloud is on vatical plane which is parallel to YZ or ZX planes.

---

<div class="post-metadata">

### Author: ![will.schroeder](https://discourse.vtk.org/user_avatar/discourse.vtk.org/will.schroeder/32/233_2.png) [@will.schroeder](https://discourse.vtk.org/u/will.schroeder)
#### Post date: [April 26, 2023, 6:30pm UTC](https://discourse.vtk.org/t/convex-hull-of-set-of-points-lying-on-a-3d-plane/11277/6 "2023-04-26T18:30:01Z")

</div>

I’m not sure what the issue is, is it the vtkProjectPointsToPlane filter? Can you share a snippet of code?

---

<div class="post-metadata">

### Author: ![kruvva](https://discourse.vtk.org/letter_avatar_proxy/v4/letter/k/a4c791/32.png) [@kruvva](https://discourse.vtk.org/u/kruvva)
#### Post date: [April 27, 2023, 12:22am UTC](https://discourse.vtk.org/t/convex-hull-of-set-of-points-lying-on-a-3d-plane/11277/7 "2023-04-27T00:22:52Z")

</div>

Will, Here is the code. Basically I have points on a plane and I need t find the boundary polygon.

def ProjectPointsToPlane(polyData, origin = (0,0,0), normal = (0,0,1)):

```
p2plaFilter = vtk.vtkProjectPointsToPlane()
p2plaFilter.SetInputData(polyData)
p2plaFilter.SetProjectionTypeToSpecifiedPlane()
p2plaFilter.SetOrigin(origin)
p2plaFilter.SetNormal(normal)
p2plaFilter.Update()
return p2plaFilter.GetOutput()

```

def GetConvexHull2D(pointCloudPolyData):

```
#PolyData holds the point cloud in a plane
points = pointCloudPolyData.GetPoints()
numPoints = points.GetNumberOfPoints()

#Plane normal and origin
pt0 = points.GetPoint(0)
pt1 = points.GetPoint(int(numPoints/2))
pt2 = points.GetPoint(numPoints-1)

planeNormal = [0,0,1]
planeOrigin = (pt1[0], pt1[1], pt1[2])
vtk.vtkTriangle.ComputeNormal(pt0, pt1, pt2, planeNormal)

#Project the points to XY plane
projectedPolyData = ProjectPointsToPlane(pointCloudPolyData, (0,0,0), (0, 0, 1))

hull = vtk.vtkConvexHull2D()
hull.SetHullShape(1) #0: BoundingRectangle or 1: ConvexHull.
hull.SetInputData(projectedPolyData)
hull.Update()

#Project back the hull to original plane
hullPolyData = ProjectPointsToPlane(hull.GetOutput(), planeOrigin, (0, 0, 1))
return hullPolyData

```

def CreateHullFromJOBFile(renderer, jobFileName):

```
mapper = ReadJOBFiles([jobFileName])
if type(mapper) is str: 
    print(mapper)
    return

mapper.SetInputData(GetConvexHull2D(mapper.GetInput()))

actor = vtk.vtkActor()
actor.SetMapper(mapper)
actor.GetProperty().SetColor([1,0,0])
actor.GetProperty().SetRepresentationToWireframe()

renderer.AddActor(actor)

```
