2

For documentation purpose I'd like to show the various spherical coordinates systems that can be used to describe a position on a sphere (i.e. position can be described as xyz-coordinates or roll-over-azimuths, azimuth-over-elevation or elevation-over-azimuth, etc).

I did not find clear illustrations on the .net, especially for non-regular conventions, and I'd like to use matlab to create simple illustrations like the following one (roll-over-azimuth system) which, imao, is straightforward to understand :

enter image description here

Anyhow I was wondering how I can create the curved arrows to show the angular direction (phi/theta arrows in above illustration). Drawing straight vectors using quiver3 is ok. I tried reading about stream3 but did not get the point about usage. I'd like to have something simple like:

function [h] = CreateCurvedArrow(startXYZ, endXYZ)
%[
     % Draw curved-line in the plane defined by 
     % vectors 'Origin->StartXYZ' and 'Origin->EndXYZ'
     % going from 'StartXYZ' to 'EndXYZ'
%] 

I hope there's some easy way to do it else I'll work-around using line segments.

CitizenInsane
  • 4,755
  • 1
  • 25
  • 56
  • 3
    Do you REALLY want to do this in Matlab? You can draw this in 5 minutes in Illustrator or inkscape, instead of poking your head against the table for hours trying to code this ;) Sorry for not being helpful, but there are far better options. – Robert Seifert Sep 17 '14 at 15:52
  • 1
    Coding this is easy in matlab, except for the curved arrows (which you're right I can later add manually after exporting to image) – CitizenInsane Sep 17 '14 at 16:00
  • 1
    The straight lines and even the [arrows](http://stackoverflow.com/questions/25729784/how-to-draw-an-arrow-in-matlab) are easy. But the curved line? possible yes, but worth the effort? You just draw all lines without arrowheads, save as vector graphic and add the heads later on. – Robert Seifert Sep 17 '14 at 16:03
  • SVG export is the way. Check >>> http://www.mathworks.com/matlabcentral/fileexchange/7401-scalable-vector-graphics--svg--export-of-figures – user3666197 Sep 17 '14 at 16:05
  • @thewaywewalk ok ok ... I'll go with manually added curved arrows for now and I'll see for programmed-one later on spare time, just for the fun of it. – CitizenInsane Sep 17 '14 at 16:19

1 Answers1

5

Simply for the fun of doing it:

Curved Arrows

The algorithm slowy rotates Center->StartPoint vector toward Center->EndPoint vector around their Normal axis and uses intermediate points to draw the curved arrow. Implementation can be further improved of course:

function [] = TestCurvedArrow()
%[
    hold on
    CreateCurvedArrow3(0.3*[1 0 0], 0.3*[0 1 0]);
    CreateCurvedArrow3(0.2*[0 1 0], 0.2*[0 0 1]);
    CreateStraightArrow([0 0 0], [1 0 0], 'r');
    CreateStraightArrow([0 0 0], [0 1 0], 'g');
    CreateStraightArrow([0 0 0], [0 0 1], 'b');
    hold off
    daspect([1 1 1]);
%]
end

%% --- Creates a curved arrow
% from: Starting position - (x,y,z) upplet
% to: Final position - (x,y,z) upplet
% center: Center of arc - (x,y,z) upplet => by default the origin
% count: The number of segment to draw the arrow => by default 15
function [h] = CreateCurvedArrow3(from, to, center, count)
%[        
    % Inputs
    if (nargin < 4), count = 15; end
    if (nargin < 3), center = [0 0 0]; end
    center = center(:); from = from(:); to = to(:);

    % Start, stop and normal vectors    
    start = from - center; rstart = norm(start);
    stop = to - center; rstop = norm(stop);
    angle = atan2(norm(cross(start,stop)), dot(start,stop));
    normal = cross(start, stop); normal = normal / norm(normal);

    % Compute intermediate points by rotating 'start' vector
    % toward 'end' vector around 'normal' axis
    % See: http://inside.mines.edu/fs_home/gmurray/ArbitraryAxisRotation/
    phiAngles = linspace(0, angle, count);
    r = linspace(rstart, rstop, count) / rstart;
    intermediates = zeros(3, count);
    a = center(1); b = center(2); c = center(3);
    u = normal(1); v = normal(2); w = normal(3); 
    x = from(1); y = from(2); z = from(3);
    for ki = 1:count,
        phi = phiAngles(ki);
        cosp = cos(phi); sinp = sin(phi);
        T = [(u^2+(v^2+w^2)*cosp)  (u*v*(1-cosp)-w*sinp)  (u*w*(1-cosp)+v*sinp) ((a*(v^2+w^2)-u*(b*v+c*w))*(1-cosp)+(b*w-c*v)*sinp); ...
             (u*v*(1-cosp)+w*sinp) (v^2+(u^2+w^2)*cosp)   (v*w*(1-cosp)-u*sinp) ((b*(u^2+w^2)-v*(a*u+c*w))*(1-cosp)+(c*u-a*w)*sinp); ...   
             (u*w*(1-cosp)-v*sinp) (v*w*(1-cosp)+u*sinp)  (w^2+(u^2+v^2)*cosp)  ((c*(u^2+v^2)-w*(a*u+b*v))*(1-cosp)+(a*v-b*u)*sinp); ...
                      0                    0                      0                                1                               ];
        intermediate = T * [x;y;z;r(ki)];
        intermediates(:,ki) = intermediate(1:3);
    end

    % Draw the curved line
    % Can be improved of course with hggroup etc...
    X = intermediates(1,:);
    Y = intermediates(2,:);
    Z = intermediates(3,:);    
    tf = ishold;
    if (~tf), hold on; end
    h = line(X,Y,Z);       
    quiver3(X(end-1), Y(end-1), Z(end-1), X(end)-X(end-1), Y(end)-Y(end-1), Z(end)-Z(end-1),1);    
    if (~tf), hold off; end
%]
end

%% --- Creates normal arrow
% from: Starting position - (x,y,z) upplet
% to: Final position - (x,y,z) upplet
% lineSpec: Line specifications 
function [h] = CreateStraightArrow(from, to, lineSpec)
%[
    h = quiver3(from(1), from(2), from(3), to(1)-from(1), to(2)-from(2), to(3)-from(3), lineSpec);
%]
end
CitizenInsane
  • 4,755
  • 1
  • 25
  • 56
  • 1
    +1 It can be done ;) One comment, if I get it right you draw the arrowheads of the curved line with `quiver3`. but just for a very very short vector. This way the head is really small? I acutally can't see it in your screenshot. You may be interested in [this question](http://stackoverflow.com/questions/25729784/how-to-draw-an-arrow-in-matlab) how to get stable and big arrow heads with `annotation`. (I already posted it before in the comments) – Robert Seifert Sep 19 '14 at 09:47
  • @thewaywewalk Yes, the way I'm drawing the head is not that appropriate. I'll see later for a more classic PropertyName\PropertyValue pairs synopsis for possible customization. Thanks for the link ;) – CitizenInsane Sep 20 '14 at 00:15