【问题标题】:Curved arrows in matlabmatlab中的曲线箭头
【发布时间】:2014-11-11 18:07:55
【问题描述】:

出于文档目的,我想展示可用于描述球体上位置的各种球坐标系(即位置可以描述为 xyz 坐标或翻转方位角、方位角-超高或仰角超过方位角等)

我在 .net 上没有找到清晰的插图,特别是对于非常规的约定,我想使用 matlab 创建简单的插图,如下图(翻转方位角系统),imao 是简单易懂:

无论如何,我想知道如何创建弯曲箭头来显示角度方向(上图中的 phi/theta 箭头)。使用 quiver3 绘制直线向量是可以的。我尝试阅读有关stream3 的信息,但没有得到关于使用的重点。我想要一些简单的东西,比如:

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

我希望有一些简单的方法可以做到这一点,否则我将使用线段来解决。

【问题讨论】:

  • 您真的想在 Matlab 中执行此操作吗?您可以在 Illustrator 或 inkscape 中在 5 分钟内绘制此图,而无需将头靠在桌子上数小时尝试编写此代码;)抱歉没有提供帮助,但还有更好的选择。
  • 在 matlab 中编码这很容易,除了弯曲的箭头(你是对的,我可以在导出到图像后手动添加)
  • 直线甚至arrows 都很容易。但是曲线呢?可能是的,但值得努力吗?您只需绘制所有没有箭头的线条,保存为矢量图形,然后再添加头部。
  • SVG 导出是一种方式。检查 >>> mathworks.com/matlabcentral/fileexchange/…
  • @thewaywewalk ok ok ...我现在将使用手动添加的弯曲箭头,稍后我会在业余时间看到编程的箭头,只是为了好玩。

标签: matlab


【解决方案1】:

只是为了好玩:

算法缓慢地围绕Normal 轴将Center->StartPoint 向量向Center->EndPoint 向量旋转,并使用中间点绘制弯曲箭头。实现当然可以进一步改进:

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

【讨论】:

  • +1 可以做到 ;) 一条评论,如果我猜对了,你用quiver3 画出曲线的箭头。但只是一个非常短的向量。这样头真的很小吗?我在您的屏幕截图中实际上看不到它。您可能对this question 感兴趣,如何使用annotation 获得稳定的大箭头。 (我之前已经在 cmets 发过)
  • @thewaywewalk 是的,我画头部的方式不太合适。稍后我将看到一个更经典的 PropertyName\PropertyValue 对的概要,以进行可能的自定义。感谢您的链接;)
猜你喜欢
  • 2016-01-22
  • 2011-09-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-16
  • 1970-01-01
  • 2017-01-25
  • 2016-04-15
相关资源
最近更新 更多