如何在MATLAB中更新/动画一个复杂的图形?

时间:2019-07-12 17:54:15

标签: matlab animation plot matlab-figure

我需要为一个复杂的动画设置动画,该动画由一系列矩形组成,形成一条手臂。 这是该手臂未设置动画时的外观示例:

Static plot

为使该图动起来,我编写了以下代码:

using System;
using System.Collections.Generic;
using System.Linq;

public class Program
{
    public class FtpFileInfo
    {
        public string FileName;
        public DateTime FileDate;
        public long FileSize;
        public object FileType;
    }

    public static void Main()
    {
        var xmlFileNames = fillClasses();
        var newXmlFileNames = new List<FtpFileInfo>();
        var res = xmlFileNames.Select(s => new
        {
            Country = s.FileName.Split('_')[1], 
            Version = s.FileName.Split('_')[2],
            ftpFileInfo = s
        }).GroupBy(x => x.Country).Select(c=> new {
            country = c.Key,
            ftpFileInfo = c.OrderByDescending(t=> t.Version).First().ftpFileInfo
        }).ToList();

        foreach(var item in res.OrderBy(c=> c.country))
        {
            var ftpFileInfo = new FtpFileInfo();
            ftpFileInfo.FileName = item.ftpFileInfo.FileName;
            ftpFileInfo.FileDate = item.ftpFileInfo.FileDate;
            ftpFileInfo.FileSize = item.ftpFileInfo.FileSize;
            ftpFileInfo.FileType = item.ftpFileInfo.FileType;

            newXmlFileNames.Add(ftpFileInfo);
        }

        foreach(var newXmlFileName in newXmlFileNames)
        {
            Console.WriteLine(string.Format("FileName: {0} FileDate:  {1}  FileSize: {2}", newXmlFileName.FileName, newXmlFileName.FileDate, newXmlFileName.FileSize));
        }


    }

    public static List<FtpFileInfo> fillClasses()
    {
        var ftpFileInfoList = new List<FtpFileInfo>();
        var fileNames = new List<string>()
        {"XXX_AE_V1_20160812132126.xml", "XXX_AE_V2_20160912142126.xml", "XXX_AE_V3_20161012152126.xml", "XXX_AU_V1_20190213142439.xml", "XXX_AU_V2_20190313142439.xml", "XXX_AU_V3_20190413142439.xml", "XXX_AU_V4_20190513142439.xml", "XXX_BR_V1_20170828214049.xml", "XXX_BR_V2_20170928214049.xml", "XXX_BR_V3_20171028214049.xml", "XXX_BR_V4_20171038214049.xml", "XXX_BR_V6_20171048214049.xml"};
        foreach (var fileName in fileNames)
        {
            ftpFileInfoList.Add(new FtpFileInfo()
            {FileName = fileName, FileDate = DateTime.Now, FileSize = 11111, FileType = null});
        }

        return ftpFileInfoList;
    }
}

但是我动画的帧根本看不清。结果如下图:

Moving plot

我做错了什么?是否可以通过清除框架来绘制具有多个部分的复杂图形并对其进行动画处理?

我调查了使用function renderFrame(fig, data) hold(ax, 'on'); % Need to hold so that new elements of the arm add themselves showMembers(fig, data); % Create patches and rotate them to the right angle to create members showJoints(fig, data); % Draw circles at the joints betwwen the members. Use the width of rectangle members drawnow; hold(ax, 'off'); % Next rendering will replace this one; No need to hold end function rotateMember(fig, data, iMember, rotAngle) for iAngle = 1:rotAngle updateMemberAngle(data, i, 1); % Change thew data so the i-th member rotates by 1 renderFrame(fig); % Show frame after the data was changed end end function main() fig = figure; ax = gca; axis(ax, 'equal'); setAxis(data); % Set axis limits and create axis arrows with totalLength of the arm renderFrame(ax, data); rotateMember(fig, data, 3, 90); % Rotate 3rd member by 90 degrees end main() newplot的情况,但是MATLAB's documentation on the subject一如既往地不完整。我还尝试了创建图形对象,然后在每次迭代时设置数据,但是由于“图形对象被删除”,因此每次删除图形时它都会拒绝一个异常。

2 个答案:

答案 0 :(得分:0)

在我看来,就好像您采用的方法那样,绘制下一帧时您并没有擦除绘图。也许在绘制下一帧之前调用cla()会使它工作吗?但是,如果重画顺序错误,可能会产生闪烁现象。

我建议看一下animation techniques in Matlab,以了解三种制作动画的不同方式。

答案 1 :(得分:0)

找到了一种清除轴子代的方法,除了两个轴颤动(箭头)。

以下是可以正常运行的代码:

function renderFrame(renderAxes, data)

    % CHECK IF THERE ARE MORE GRAPHIC OBJECTS THAN ONLY THE QUIVERS
    if ~(length(renderAxes.Children) == 2)

        % DELETE EVERYTHING EXCEPT THE AXIS QUIVERS THAT WERE RENDERED AT THE BEGINNING
        % MATLAB ADDS NEW GRAPHIC OBJECTS TO THE BEGINNING OF AX.CHILDREN
        delete(renderAxes.Children(1:length(renderAxes.Children)-2))
    end

    showMembers(renderAxes, data); % Create patches and rotate them to the right angle to create members
    showJoints(renderAxes, data); % Draw circles at the joints betwwen the members. Use the width of rectangle members  
    drawnow;
end

function rotateMember(ax, data, iMember, rotAngle)
    for iAngle = 1:rotAngle
        updateMemberAngle(data, i, 1); % Change thew data so the i-th member rotates by 1
        renderFrame(ax, data); % Show frame after the data was changed
    end
end

function main()
    fig = figure;
    ax = gca;
    axis(ax, 'equal');

    % HOLD AXES AT THE BEGINNING OF THE SCRIPT
    hold(ax, 'on');

    setAxis(data); % Set axis limits and create axis arrows with totalLength of the arm
    renderFrame(ax, data);
    rotateMember(ax, data, 3, 90); % Rotate 3rd member by 90 degrees
end

main()