pntsGeometry3D

Coordinates of points for given geometries in three dimensional space. At the moment only points are arranged on a sphere or have to be defined manually.

Contents

Syntax

[Pnts,Nb,dS] = pntsGeometry3D(seti,type,varargin)
[Pnts,Nb,dS] = pntsGeometry3D(seti,'manually',Pnts);
[Pnts,Nb,dS] = pntsGeometry3D(seti,'manually',Pnts,dispDepth);
[Pnts,Nb,dS] = pntsGeometry3D(seti,'sphereLatLon',Nb,rad);
[Pnts,Nb,dS] = pntsGeometry3D(seti,'sphereLatLon',Nb,rad,dispDepth);
[Pnts,Nb,dS] = pntsGeometry3D(seti,'sphereFibo',Nb,rad);
[Pnts,Nb,dS] = pntsGeometry3D(seti,'sphereFibo',Nb,rad,dispDepth);

Description

[Pnts,Nb,dS] = pntsGeometry3D(seti,type,varargin) computes the coordinates in Pnts and serves their number Nb and an approximation of the infinitesimal element of closed contour in dS. The geometry type is defined in type and the details in varargin depending on the type. seti is only used to check that seti.dim = 3.

[Pnts,Nb,dS] = pntsGeometry(seti,'manually',Pnts) counts the number |Nb of input points Pnts and sets dS to 1. Input and output Pnts is the same.

[Pnts,Nb,dS] = pntsGeometry3D(seti,'sphereLatLon',Nb,rad) generates coordinates Pnts on a sphere. The number of Nb points are arranged on a sphere with radius rad with latitude-longitude lattice. Distance dS is computed. Note that this in general does not result in a equidistant distribution and a fewer number of points is arranged than originally given as input. Therefore, we recommend to use the method 'sphereFibo'.

[Pnts,Nb,dS] = pntsGeometry3D(seti,'sphereFibo',Nb,rad) generates coordinates Pnts on a sphere. The number of Nb points are arranged on a sphere with radius rad with Fibonacci lattice, see [1, Sec. 3.1]. Distance dS is computed. This results in a nearly equidistant distribution. In case of an even number Nb, only Nb-1 points are arranged; if the input number Nb is an odd number nothing will be subtracted. Therefore, we recommend to use the method 'sphereFibo'.

[Pnts,Nb,dS] = setData(seti,'manually',Pnts,dispDepth), [Pnts,Nb,dS] = pntsGeometry3D(seti,'sphereLatLon',Nb,rad,dispDepth), and [Pnts,Nb,dS] = pntsGeometry3D(seti,'sphereFibo',Nb,rad,dispDepth) do the same as without the argument dispDepth, but allow to control the depth of displayed messages by dispDepth.

Examples

Example 1: manually

seti.dim = 3;
Pnts = [2 0 0 2;
        0 2 0 1;
        0 0 2 2];
[Pnts,Nb,dS] = pntsGeometry3D(seti,'manually',Pnts);
figure(101); scatter3(Pnts(1,:),Pnts(2,:),Pnts(3,:),'filled');

Example 2: sphere with latitude-longitude lattice

Arrange 50 points on a sphere with radius 5. Because latitude-longitude lattice actually only 32 points are arranged.

seti.dim = 3;
Nb = 50;
rad = 5;
[Pnts,Nb,dS] = pntsGeometry3D(seti,'sphereLatLon',Nb,rad);
figure(102); [sx,sy,sz] = sphere; r = rad; sx = sx*r; sy = sy*r; sz = sz*r; surf(sx,sy,sz);
hold on; scatter3(Pnts(1,:),Pnts(2,:),Pnts(3,:),'filled'); axis square; hold off;

Example 3: sphere with Fibonacci lattice

Arrange 50 points on a sphere with radius 5. Because 50 is an even number, the method with Fibonacci lattice acutally arranges only 49 points.

seti.dim = 3;
Nb = 50;
rad = 5;
[Pnts,Nb,dS] = pntsGeometry3D(seti,'sphereFibo',Nb,rad);
figure(103); [sx,sy,sz] = sphere; r = rad; sx = sx*r; sy = sy*r; sz = sz*r; surf(sx,sy,sz);
hold on; scatter3(Pnts(1,:),Pnts(2,:),Pnts(3,:),'filled'); axis square; hold off;

Input Arguments

varargin in case of type = 'manually'

varargin in case of type = 'sphereLatLon' and 'sphereFibo'

Optional Input Argument

This argument must be the last if it is used.

Output Arguments

More About

References

See Also

Code: pntsGeometry3D

function [Pnts,Nb,dS] = pntsGeometry3D(seti,type,varargin)
if seti.dim ~= 3
    error('pntsGeometry3D needs 3D.')
end

if nargin == 4 && strcmp(type,'manually')
    dispDepth = varargin{2};
else
    dispDepth = 0;
end
if strcmp(type,'manually')
    %   pntsGeometry3D(seti,'manually',Pnts)
    Pnts = varargin{1};
    Nb = size(Pnts,2);
    if nargin == 4
        dispDepth = varargin{2};
    else
        dispDepth = 0;
    end

elseif strcmp(type,'sphereLatLon')
    %   pntsGeometry(seti,'sphereLatLon',Nb,rad)
    Nb = varargin{1};
    rad = varargin{2};
    Pnts = sphereLatLon(Nb,rad);
    if nargin == 5
        dispDepth = varargin{3};
    else
        dispDepth = 0;
    end

elseif strcmp(type,'sphereFibo')
    %   pntsGeometry(seti,'sphereFibo',Nb,rad)
    Nb = varargin{1};
    rad = varargin{2};
    Pnts = sphereFibo(Nb,rad);
    if nargin == 5
        dispDepth = varargin{3};
    else
        dispDepth = 0;
    end
end

% *Compute Nb and dS*

NbOut = size(Pnts,2); % in some cases (especially sphereLatLon, but also
% in case of an even number sphereFibo) NbOut is not Nb.

if Nb ~= NbOut && dispDepth >= 1
    fprintf('   Input was Nb = %d, but set "Nb" to %d (e.g. because surface mesh of S^2 has %d points).\n',Nb, NbOut,NbOut);
end
Nb = NbOut;

if strcmp(type,'manually')
    dS = 1;
elseif strcmp(type,'sphereLatLon') || strcmp(type,'sphereFibo')
    % normalized surface measure
    dS = dS3D(Nb, rad);
else
    error('pntsGeometry3D.m: no value type to compute dS.');
end
end

Code: Subfunctions

function Pnts = sphereLatLon(Nb,rad)

Arrange points on a sphere with latitude-longitude lattice

Set incident points for a ball in 3D.

Input Arguments: * Nb : number of points (input) * rad : radius of the sphere

Output Arguments: * Pnts : Coordinates of the points. * NbOut : number of points (really generated).

% incident fields
NbTemp = floor(sqrt(Nb+2));
[pntsX, pntsY, pntsZ] = sphere(NbTemp-1);

% extract multiple points
pntsX = pntsX(:).'; pntsY = pntsY(:).'; pntsZ = pntsZ(:).';
Pnts = [pntsX(1); pntsY(1); pntsZ(1)];
for jj = 2:length(pntsX)
    [~,aux] = size(Pnts);
    dummy = 1;
    for kk = 1:aux
        if norm(Pnts(:,kk)-[pntsX(jj); pntsY(jj); pntsZ(jj)]) < 1e-10
            dummy = 0;
        end
    end
    if dummy == 1
        Pnts(:,aux+1) = [pntsX(jj); pntsY(jj); pntsZ(jj)];
    end
end

[~,NbOut] = size(Pnts); % no output of NbOut, but if below needs it.

Pnts = rad*Pnts;

if NbOut == 1
    % workaround: code above does not work for Nb == 1.
    if dispDepth >= 1
        disp('pntsGeometry3D.m : As Nb == 1 => Set Pnts = [1; 0; 0]');
    end
    Pnts = [1; 0; 0];
    % NbOut = 1; % no output here
    % dS = 1; % no output here
end
end

sphereFibo

function Pnts = sphereFibo(Nb,rad)
% Arrange points on a sphere with Fibonacci lattice
%
% * If Nb is odd, then really Nb points are generated.
% * If Nb is even, Nb-1 points are generated.

N = floor((Nb-1)/2);

Geographical coordinates in degrees

The following follows the pseudo code in Sec. 3.1 in: Álvaro González. Measurement of areas on a sphere using fibonacci and latitude?longitude lattices. Mathematical Geosciences, 42(1):49, 2009.

NN = 2*N+1; % resulting number of points...
lat = zeros(1,NN); % latitude (North/South)
lon = zeros(1,NN); % longitude (West/East)
phi = (1+sqrt(5))/2; % phi: golden ratio
for i = -N:N
    j = i+N+1; % shifted i because MATLAB can not deal with negative index (or 0)
    lat(j) = asin(2*i/(2*N+1))*180/pi; % asin is arcsin
    % asin is arcsin, but of course needs [-1,1] input for a real output.
    lon(j) = mod(i,phi)*360/phi;
    if lon(j) < -180
        lon(j) = 360 + lon(j);
    elseif lon(j) > 180
        lon(j) = lon(j) - 360;
    end
end

Coordinates in cartesian system

Transforms geographical coordinates (they are spherical coordinates) into cartesian. Note that lat and lon are in degrees and not in rad.

Transform them to rad

latrad = deg2rad(lat);
lonrad = deg2rad(lon);
%
% Transform them into cartesian system
r = 1;
[x,y,z] = sph2cart(lonrad,latrad,r);
% n = size(x,2); % number of points: no output here

Pnts = zeros(1,NN);
Pnts(1,:) = x; Pnts(2,:) = y; Pnts(3,:) = z;

Pnts = rad*Pnts;
end