I tried do use 1000 samples on the 2-sphere surrounding the centre vertex. The mesh is manifold, but it looks like the results from Marching Cubes.
def quat_normal_from_function(f, d=0.000001):
"""Given a sufficiently smooth 3d function, f, returns a function approximating of the gradient of f.
d controls the scale, smaller values are a more accurate approximation."""
def norm(x, y, z):
num_samples = 1000
sample_points = []
for i in range(0, num_samples):
sample_point = V3(0, 0, 0)
u = random.randint(0, 1000)/1000.0
v = random.randint(0, 1000)/1000.0
pi = 4.0*math.atan(1.0);
theta = 2.0*pi*u
phi = math.acos(2.0*v - 1.0)
# generate pseudorandom location on 2-sphere of radius d
sample_point.x = d*math.cos(theta)*math.sin(phi)
sample_point.y = d*math.sin(theta)*math.sin(phi)
sample_point.z = d*math.cos(phi)
sample_points.append(sample_point)
normal = V3(0, 0, 0)
for sample_counter in range(0, len(sample_points)):
if f(sample_points[sample_counter].x, sample_points[sample_counter].y, sample_points[sample_counter].z) < 0:
normal.x += -sample_points[sample_counter].x
normal.y += -sample_points[sample_counter].y
normal.z += -sample_points[sample_counter].z
if 0 == normal.x*normal.x + normal.y*normal.y + normal.z*normal.z:
normal.x = 1;
return normal.normalize()
return norm