how to move a sphere until it intersect a surface?

3 views (last 30 days)
Hi mates!
My idea is creat a sphere with center fixed in x and y but free in z. So it had movemet in z, up and down. Then, i have a surface and i want to move the sphere until it intersect the surface and get the intersection point. Someone can help? thanks!
  10 Comments
John D'Errico
John D'Errico on 11 Mar 2019
Edited: John D'Errico on 11 Mar 2019
Yes. It does matter what the surface is. Is this a functional form, like z(x,y)? Is it a surface that you created, possibly using meshgrid? Is is just a scattered list of points with no defined connectivity? I'd solve the problem differently depending on what I have to deal wih.
Luís Asevedo
Luís Asevedo on 12 Mar 2019
Hi @Jan and @john,
I have this surface:
[X,Y] = meshgrid(0:0.2:4,-0:0.2:4);
Z = X.*exp(-0.1*X.^2 - 0.2*Y.^2 + 1.5);
figure
surface(X,Y,Z)
view(3)
now i want to do the intersection of a sphere ( radius =0.2) with the lower face of surface when x=2 and y=2 and then get the sphere center point.
thanks for your help

Sign in to comment.

Accepted Answer

John D'Errico
John D'Errico on 13 Mar 2019
Edited: John D'Errico on 13 Mar 2019
You have a surface defined as
Z = x.*exp(-0.1*x.^2 - 0.2*y.^2 + 1.5);
fsurf(Z)
xlabel X
ylabel Y
zlabel Z
And a sphere, with radius 0.2, centered at (x,y,z) = (2,2,z). So the sphere can translate up or down, but only in z.
You wish to find the value of x for the center of that sphere, such that the distance from the center of the sphere and the surface is 0.2. So that sphere will appear to touch the surface at some point near the peak of the yellow mound.
view(2)
xline(2,'r');
yline(2,'r');
A sphere that touches the surface will touch at one point. And if the sphere just touches a surface, then it must be tangent at that point. Therefore, I want to compute the normal vector to the surface at any point, if the sphere is tangent. Then I could compute a point that lies at a distance of 0.2 units along the normal vector.
What is the normal vector at any point on the surface? So, at any (x,y)? A point on the surface itself lies at the triple (x,y,z).
syms x y z
xyz = [x,y,x*exp(- x^2/10 - y^2/5 + 3/2)]
xyz =
[ x, y, x*exp(- x^2/10 - y^2/5 + 3/2)]
S = z - x.*exp(-0.1*x.^2 - 0.2*y.^2 + 1.5);
Differentiating S, we now get a gradient. That gradient vector will point towards the center of a sphere that is tangent to the surface at the given point. So, again, we want to move at a distance of 0.2 units along that vector.
For example, consider the point (x,y) = (2.1, 1.75). Just looking at the surface plot, I might guess that (x,y) pairs is close to where the sphere might tough the surface.
gvec = subs(G,{x,y},[2.1 1.75]);
gvec = double(gvec/norm(gvec))
gvec =
-0.0734031632331007 0.914429236886933 0.398034101998506
double(subs(xyz,[x,y],[2.1 1.75])) + gvec*0.2
ans =
2.08531936735338 1.93288584737739 3.36155546426728
So the center of a radius 0.2 sphere that touches the surface at (x,y) = 2.1,1.75), lies at the point shown, which is quite near (x,y) = (2,2). In fact, that suggests a simple scheme that should be convergent. First, a function m-file that fsolve will use.
function [dxy,zfinal] = xyiter(xy,G,xyz,target,radius
syms x y
gvec = subs(G,[x,y],x0y0);
gvec = double(gvec/norm(gvec));
C = double(subs(xyz,[x,y],[2.1 1.75])) + gvec*radius;
xy = C(1:2);
zfinal = C(3);
dxy = target - xy;
end
Next call fsolve like this:
xy0 = [2.1 1.75];
target = [2 2];
radius = 0.2;
[xyfinal,fval] = fsolve(@(xy) xyiter(xy,G,xyz,target,radius),xy0)
Equation solved.
fsolve completed because the vector of function values is near zero
as measured by the default value of the function tolerance, and
the problem appears regular as measured by the gradient.
<stopping criteria details>
xyfinal =
2.02247706698766 1.81825442183378
fval =
-1.60967950080249e-09 1.29511423807571e-09
One final call to xyiter to get z.
[~,zfinal] = xyiter(xyfinal,G,xyz,target,radius)
zfinal =
3.18868207699213
So easy, peasy. The sphere touches the surface at the (x,y) coordinates xyfinal. The height of the center of the sphere that touches that location is in zfinal. The point on the surface where the sphere touches down is
xyztouch = double(subs(xyz,[x,y],xyfinal))
xyztouch =
2.02247706698766 1.81825442183378 3.10828725862812
which lies at a distance of 0.2 units from [2,2,zfinal].
norm(xyztouch - [2 2 zfinal])
ans =
0.200000001357811
The small error is in the fsolve convergence tolerance.
I imagine there are other ways to write the solution, but the one I chose made sense to me, and is, I think, instructive. (Sorry it took a little time to write this. I was playing bridge. I do have my priorities.)
  3 Comments
Luís Asevedo
Luís Asevedo on 13 Mar 2019
Edited: Luís Asevedo on 13 Mar 2019
In this case you arbitrate a value for (x,y)=2.1,1.75. Is there any way where is not necessary gives values to x and y ?
Thanks a lor for your help!!
John D'Errico
John D'Errico on 13 Mar 2019
Um, probably not, at least for an absolutely completely general surface. There are surely a variety of solutions I might pose here, and probably some I've not thought of. The reason I chose the approach that I did was that it is easier to find a tangent plane to the surface, then recognize the sphere touches the surface along the local tangent plane.
Given that approach, one needs to search for the point where the sphere and surface touch. This is an optimization search, if I formulate it in numerical form. I could possibly have formulated this as a problem for solve to attack, but many general differentiable surfaces probably would not admit an analytical solution.
So why does this need starting values? Imagine we had a surface that had literally millions of tiny (smooth) bumps. As well, now pose a problem with a very large radius sphere, which as the radius gets sufficiently large, the sphere approaches a plane.
In this scenario, you would need to either solve the optimization problem by providing good starting values, or by a VERY extensive global search technique.
Another approach would be to approximate the entire problem, then use knnsearch. So just generate a huge number of points on the surface, then many points along the line that represent the center of the sphere. Use knnsearch to solve for the nearest point between the different sets. Choose that point where the nearest distance is as close to 0.2 as possible. This is only approximate of course, but it will require no starting value.

Sign in to comment.

More Answers (0)

Categories

Find more on Computational Geometry in Help Center and File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!