Search code examples
pythonmath3dmayamaya-api

Generate random points on any 3 dimensional surface


I was wondering, how would you, mathematically speaking, generate x points at random positions on a 3D surface, knowing the number of triangle polygons composing the surface (their dimensions, positions, normals, etc.)? In how many steps would you proceed?

I'm trying to create a "scatterer" in Maya (with Python and API), but I don't even know where to start in terms of concept. Should I generate the points first, and then check if they belong to the surface? Should I create the points directly on the surface (and how, in this case)?

Edit: I want to achieve this without using 2D projection or UVs, as far as possible.


Solution

  • You should compute the area of each triangle, and use those as weights to determine the destination of each random point. It is probably easiest to do this as a batch operation:

    def sample_areas(triangles, samples):
      # compute and sum triangle areas
      totalA = 0.0
      areas = []
      for t in triangles:
        a = t.area()
        areas.append(a)
        totalA += a
    
      # compute and sort random numbers from [0,1)
      rands = sorted([random.random() for x in range(samples)])
    
      # sample based on area
      area_limit = 0.0
      rand_index = 0
      rand_value = rands[rand_index]
      for i in range(len(areas)):
        area_limit += areas[i]
        while rand_value * totalA < area_limit:
          # sample randomly over current triangle
         triangles[i].add_random_sample()
    
          # advance to next sorted random number
          rand_index += 1;
          if rand_index >= samples:
            return
          rand_value = rands[rand_index]
    

    Note that ridged or wrinkled regions may appear to have higher point density, simply because they have more surface area in a smaller space.