pca_ellipsoid.py 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
  1. """Draw the ellipsoid that contains 50% of a cloud of Points,
  2. then check how many points are inside the surface"""
  3. #
  4. # NB: check out pca_ellipse() method for 2D problems
  5. #
  6. from vedo import settings, Points, pca_ellipsoid, Arrow, Assembly, show
  7. import numpy as np
  8. settings.use_depth_peeling = True
  9. pts = Points(np.random.randn(10_000, 3)*[3,2,1])
  10. pts.rotate_z(45).rotate_x(20).shift([30,40,50])
  11. elli = pca_ellipsoid(pts, pvalue=0.50) # 50% of points inside
  12. ids = elli.inside_points(pts, return_ids=True)
  13. pts.print() # a new "IsInside" array now exists in pts.pointdata
  14. pin = pts.coordinates[ids]
  15. print("inside points #", len(pin))
  16. # Create an inverted mask instead of calling inside_points(invert=True)
  17. mask = np.ones(pts.npoints, dtype=bool)
  18. mask[ids] = False
  19. pout = pts.coordinates[mask]
  20. print("outside points #", len(pout))
  21. # Extra info can be retrieved with:
  22. print("axis 1 size:", elli.va)
  23. print("axis 2 size:", elli.vb)
  24. print("axis 3 size:", elli.vc)
  25. print("axis 1 direction:", elli.axis1)
  26. print("axis 2 direction:", elli.axis2)
  27. print("axis 3 direction:", elli.axis3)
  28. print("asphericity:", elli.asphericity(), '+-', elli.asphericity_error())
  29. a1 = Arrow(elli.center, elli.center + elli.axis1)
  30. a2 = Arrow(elli.center, elli.center + elli.axis2)
  31. a3 = Arrow(elli.center, elli.center + elli.axis3)
  32. triad = Assembly(a1, a2, a3) # let's group them
  33. show(
  34. elli, triad,
  35. Points(pin).c("green4"),
  36. Points(pout).c("red5").alpha(0.2),
  37. __doc__,
  38. axes=1,
  39. ).close()