a question about vtkImplicitFunction::EvaluateGradient

The description on the documentation is "Evaluate function gradient at position x-y-z and pass back vector.But I don’t understand what it does. I created a new class,inherited from vtkImplicitFunction,i overrid EvaluateGradient

void MyFuntion::EvaluateGradient(double x[3], double g[3])
{

}

did nothing,This doesn’t seem to affect my use of it,Can someone tell me why?

Are you creating a custom class inheriting from vtkImplicitFunction?

I want to generate a shape using a custom function,The function seems to be implemented, but I did not implement the “EvaluateGradient” function,So I don’t know how it will affect my future use.

I have implemented numerous implicit functions for use with vtkClipPolyData, where I have simply returned a null vector. Specifically vtkClipPolyData does not make use of the gradient function. Personally, I have only used the EvaluateGradient for testing my implicit functions by visualizing a vector field.

Hello,

My two cents: x[3] is your input coordinates (x,y,z)? and you put the result in g[3]. Though, I think you should declare the g output parameter as a pointer.

void MyFuntion::EvaluateGradient(double* x, double* g)
{
     /// h is some small separation value (e.g. grid cell size)
     g[0] = my_function(x[0] + h, x[1], x[2]) - my_function(x[0] - h, x[1], x[2])) / (2 * h);
     g[1] = my_function(x[0], x[1] + h, x[2]) - my_function(x[0], x[1] - h, x[2])) / (2 * h);
     g[2] = my_function(x[0], x[1], x[2] + h) - my_function(x[0], x[1], x[2] - h)) / (2 * h);
}

Does this make sense?

regards,

Paulo

Edit, making my_function() taking x,y,z coordinates.

I think g is already a pointer,I roughly understand how to return a gradient,But I still don’t understand what the gradient does?

I believe the primary purpose is for isocontouring: generating normals on the resulting isosurface. Another use is determining in/out in some situations.

A great way to answer questions like this is to search the VTK source code and/or examples for EvaluateGradient and see how it’s used.

In my example above is how I compute the orthogonal components (x,y,z) of the gradient vector. h may even have components itself: hx, hy and hz (e.g. anisotropic grid cells). In this case, it becomes:

void MyFuntion::EvaluateGradient(double* x, double* g)
{
     /// hx, hy, hz are small separation values (e.g. grid cell sizes)
     g[0] = my_function(x[0] + hx, x[1], x[2]) - my_function(x[0] - hx, x[1], x[2])) / (2 * hx);
     g[1] = my_function(x[0], x[1] + hy, x[2]) - my_function(x[0], x[1] - hy, x[2])) / (2 * hy);
     g[2] = my_function(x[0], x[1], x[2] + hz) - my_function(x[0], x[1], x[2] - hz)) / (2 * hz);
}

Yes, parameters declared like that “decay” to pointers inside the function. But it is a good practice to declare them explicitly as pointers to avoid misleading anyone else reading your code. Declaring them as pointers makes it clear that the array elements will be changed inside the function. IMO, the form void foo( double x[] ) being equivalent to void foo( double* x ) is a language design flaw.

cheers,

Paulo

this is a good suggestion

That’s a good idea, I really should read the source code