Matlab颤抖箭头长度

时间:2018-04-05 23:51:23

标签: matlab matlab-figure

我正在处理以下代码:

function myquiver

clc
R=2.3;
C=1.2;
V=@(t) 3*sqw(t,1,10);
F=@(t,VC) (V(t)-VC)/(R*C);
[T,VC]=meshgrid(linspace(0,25,10),linspace(0,0.5,10));
S=(3*sqw(T,1,10)-VC)/(R*C);
L=sqrt(1+S.^2);
quiver(T,VC,1./L,S./L,'r','ShowArrowhead','off','AutoScale','off')
axis([0,25,0,0.5])
shg

function y=sqw(t,T,d)
r=mod(t,T);
y=(r<d*T/100);

这会产生以下图像:

enter image description here

现在,我想做的是根据轴使每个箭袋箭头长度相同。我不想改变轴([0,25,0.05])。这正是我想要的。但是,我如何缩放每个箭袋箭头,使它们在这个特定图像中的长度相同?

我希望看到一个我可以使用的想法,如果我用say轴([0,10,-30,50])做另一个情节。

我希望看到完整的代码示例和图像。

感谢。

1 个答案:

答案 0 :(得分:3)

让我们考虑两个坐标系。首先是数据所在的世界坐标系。例如1./LS./L是世界坐标表示。第二,我们定义的绘图坐标系使得一个距离单位是绘图窗口的宽度和高度。即绘图坐标中单位长度的水平向量将精确地跨越整个绘图宽度,类似地,绘图坐标中单位长度的垂直向量将精确地跨越整个绘图高度。

您似乎要问的是如何缩放每个矢量,使它们在绘图坐标中都是一些固定长度。不难看出,对于世界坐标(x_world, y_world)中定义的某个矢量,以下函数将世界坐标转换为绘图坐标。

x_plot = x_world / x_span
y_plot = y_world / y_span

x_spany_span是世界坐标中情节的宽度和高度(在您的情况下分别为250.5)。

我们想知道要应用于x_worldy_world的比例因子,以便(x_plot, y_plot)具有一定的固定长度。请注意,我们必须在x和y中应用相同的缩放系数才能保留原始方向。在数学上,这可以用等式

来描述
d = sqrt((s*x_world / x_span)^2 + (s*y_plot / y_span)^2)

其中d是绘图坐标中所需的长度,s是我们需要确定的比例因子。

求解s得到的等式

s = d/sqrt((x_world / x_span)^2 + (y_plot / y_span)^2)

给了我们一个解决方案。

function myquiver
    xmin = 0; xmax = 25;
    ymin = 0; ymax = 0.5;

    R=2.3;
    C=1.2;
    V=@(t) 3*sqw(t,1,10);
    F=@(t,VC) (V(t)-VC)/(R*C);
    [T,VC]=meshgrid(linspace(xmin,xmax,10),linspace(ymin,ymax,10));
    S=(3*sqw(T,1,10)-VC)/(R*C);
    L=sqrt(1+S.^2);

    x_span = xmax - xmin;
    y_span = ymax - ymin;
    % Compute the scale factor so that vectors are 10% of plot window
    d = 0.1;
    X_world = 1./L;
    Y_world = S./L;
    s = d ./ sqrt((X_world / x_span).^2 + (Y_world / y_span).^2);
    quiver(T,VC,s.*X_world,s.*Y_world,'r','ShowArrowhead','off','AutoScale','off')
    axis([xmin,xmax,ymin,ymax])

    % force the axis to be square
    axis('square');

function y=sqw(t,T,d)
    r=mod(t,T);
    y=(r<d*T/100);

enter image description here

这里要注意的一点是我们使用了axis('square')。这对于确保绘图坐标屏幕/像素坐标之间的相等缩放关系是必要的。由于这可能不合适(也许我们不想要方形图!),然后我们可以通过将x_span除以轴的纵横比(以像素为单位)来解决此问题。不幸的是,在创建绘图之前我们无法获得纵横比。为了实现通用解决方案,我们基本上有两个选择。

  1. 编写一个函数处理程序,以便在每次调整图形大小时自动重新绘制。这是更多的工作,但一般化。
  2. 使用图形直到它达到所需的大小,然后查询大小,然后使用此信息重新绘制所需的图形大小。
  3. 我选择了第二选择。首先,我绘制没有 axis('square'),然后使用窗口播放,直到它与您发布的原始图形大小相同。接下来,我查询了图形和纵横比的位置如下

    >> get(gcf, 'Position')
    ans = 666   223   672   505
    >> set(gca, 'Units', 'Pixels');
    >> get(gca, 'Position')
    ans = 88.3600   56.5500  520.8000  411.5750
    

    这告诉我们,对于此图形位置,轴的纵横比(以像素为单位)为520.8 / 411.575。使用这些知识,我们修改函数以绘制此非方轴的相等长度向量,如下所示。

    function myquiver
        xmin = 0; xmax = 25;
        ymin = 0; ymax = 0.5;
    
        R=2.3;
        C=1.2;
        V=@(t) 3*sqw(t,1,10);
        F=@(t,VC) (V(t)-VC)/(R*C);
        [T,VC]=meshgrid(linspace(xmin,xmax,10),linspace(ymin,ymax,10));
        S=(3*sqw(T,1,10)-VC)/(R*C);
        L=sqrt(1+S.^2);
    
        aspect = 520.8 / 411.575;
        x_span = (xmax - xmin) / aspect;
        y_span = ymax - ymin;
        % Compute the scale factor so that vectors are 10% of y-direction of plot window
        d = 0.1;
        X_world = 1./L;
        Y_world = S./L;
        s = d ./ sqrt((X_world / x_span).^2 + (Y_world / y_span).^2);
        quiver(T,VC,s.*X_world,s.*Y_world,'r','ShowArrowhead','off','AutoScale','off')
        axis([xmin,xmax,ymin,ymax])
    
        % Make the figure have the desired position/size
        set(gcf, 'Position', [666   223   672   505]);
    
    function y=sqw(t,T,d)
        r=mod(t,T);
        y=(r<d*T/100);
    

    enter image description here

相关问题