I want to morph sphere, using the following equation:
R=1+k*(cos(4*elev)+sin(4*az))
,
Spherical coordinates elev
and az
are transferred as gl_Vertex
. The problem is to calculate normals for such morphing. I may calculate them, just shifting az
and elev
a bit, the obtain 2 more "virtual" vertices and use standard approach with cross-product, but it looks rather ugly and expensive approach.
Is their are any way to calculate normals also parametrically for such kind of morphing?
Thanks to @meowgoesthedog, but I still have problems. My implementation of this formula (code below) did not work:
Am i correct and it should be:
cos(theta)*(k*(cos(4*theta)+sin(4*phi))+1)
or cos(theta*(k*(cos(4*theta)+sin(4*phi))+1))
?
Are normals calculated in cartesian coordinate system?
My code in Matlab:
close all
clear all
N=100;
phi_range=linspace(-pi,pi,N+2);
theta_range=linspace(-pi/2,pi/2,N);
phi_range([1,end])=[];
k=6;
% generate morphed sphere
PHI=repmat(phi_range,N,1);
THETA=repmat(theta_range',1,N);
R=1+k*cos(4*THETA)+k*sin(4*PHI);
% convert to cartesian coordinates
[X,Y,Z]=sph2cart(PHI,THETA,R);
%% meowgoesthedog formula
S=k.*(cos(4.*THETA)+sin(4.*PHI))+1;
V1_x = cos(PHI).*(cos(THETA).*S-4.*k.*sin(THETA).*sin(4.*THETA));
V1_y = sin(PHI).*(cos(THETA).*S-4.*k.*sin(THETA).*sin(4.*THETA));
V1_z = -sin(THETA).*S-4.*k.*sin(4.*THETA).*cos(THETA);
V2_x = sin(THETA).*(4.*k.*cos(PHI).*cos(4.*PHI)-sin(PHI).*S);
V2_y = sin(THETA).*(4.*k.*sin(PHI).*cos(4.*PHI)+cos(PHI).*S);
V2_z = 4.*k.*cos(THETA).*cos(4.*THETA);
V1=cat(3,V1_x,V1_y,V1_z);
V2=cat(3,V2_x,V2_y,V2_z);
Normals=cross(V1,V2);
% normalize
Normals=Normals./sqrt(sum(Normals.^2,3));
%% plot and compare results:
hold all
surfnorm(X,Y,Z,'EdgeAlpha',0.5)
quiver3(X,Y,Z,Normals(:,:,1),Normals(:,:,2),Normals(:,:,3),'m')
On figures below red - correct normals, magenta which I calculate.
We can compute an analytical expression for the normal using differential geometry. Let's first state the form of the Cartesian parametric coordinate:
Locally at any point on the surface, there is a 2D coordinate system spanned by the unit vectors in the directions of increasing θ
and φ
.
These vectors are given by:
The normal is simply given by the cross-product of these two vectors (un-normalized):
After some very tedious algebra we obtain:
(The formula becomes too long to legibly display past this point, and probably not as efficient to evaluate either.)
EDIT
It appears that I have used the conventional definition of θ
(angle from the +Z axis) instead of Matlab's elev
. Redefining the equations this would give:
Where ψ = ½π - θ
is the elevation.