File:Dragon Curve unfolding chamfered zoom numbered.webm

From Meta, a Wikimedia project coordination wiki

Original file(WebM audio/video file, VP9, length 50 s, 1,024 × 1,024 pixels, 16.86 Mbps overall, file size: 99.89 MB)

This is a file from the Wikimedia Commons. The description on its description page there is copied below.

Summary

Description
English: Animation of an unfolding Dragon curve. The order is increased from 0 to 17. The curve is chamfered for better visibility of the path. After reaching order 17 it is zoomed in to show the emerging pattern.
Deutsch: Animation einer sich entfaltenden Drachenkurve. Die Ordnung steigt von 0 bis 17. Die Ecken sind zur Darstellung des Verlaufs abgeflacht. Nach erreichen der Ordnung 17 wird die Kurve herangeholt um das Muster sichtbar zu machen.
Polski: Animacja rozwijającego się smoka Heighwaya. Rząd krzywej zmienia się od 0 do 17. Dla lepszej widoczności krzywa jest sfazowana. Po osiągnięciu 17. rzędu zostaje powiększona w celu pokazania pojawiającego się wzoru.
Čeština: Animace iteračního výpočtu dračí křivky do 17 iteračních kroků. Po dosažení 17. kroku je výsledný vzor zvětšen pro názorné zobrazení výsledné křivky.
Date
Source Own work
Author Jahobr
Other versions

[edit]

WEBM development
InfoField
 
This diagram was created with MATLAB by Jahobr.
Source code
InfoField

MATLAB code

function [] = Dragon_Curve_unfolding_mp4_webm()
% Programmed in Matlab R2017a.
% Animation of an Dragon Curve unfolding.
% Before anything is drawn the algorithm makes a dry run ('xyLim')
%    to determine proper axis limits to keep the 
%    animation nicely in frame. 
% Then eight versions of the unfolding as mp4 files are created.
%    'rectangular' and 'chamfered' with and without a final zoom inwards.
%    all with and without the order number in the lower left.
% Lastly the conversion to webm is triggered automatically. The conversion
% itself is done by ffmpeg.exe (implementation for windows only) and can
% take up to 4 hours.
 
[pathstr,fname] = fileparts(which(mfilename)); % save files under the same name and at file location
fname = strrep(fname,'_mp4_webm','');

maxOrder = 17; % final order of fractal
 
figHandle = figure(345275); clf;
set(figHandle,'Color'  ,'white'); % white background
set(figHandle,'Units'  ,'pixel');
set(figHandle,'MenuBar','none',  'ToolBar','none'); % free real estate for a maximally large image
% set(figHandle,'Renderer','OpenGL')
% set(figHandle,'GraphicsSmoothing','on')


axesHandle = axes; hold(axesHandle,'on');
axis equal
axis off % invisible axes (no ticks)

% stop acceleration rot de-acceleration stop
accFrames = 20; % frames for acceleration (first frame will be 0 last at full speed, so practicall it is accFrames-2)
speed = [linspace(0,1,accFrames) ones(1,36) linspace(1,0,accFrames)]; %
speed = speed(1:end-1); % last speed is 0, this does nothing in cumsum; (compensated by +1 frames in center)
angleList = cumsum(speed)/sum(speed) * pi/2; % create position, normalize, scale
 
staticFramesAtVideoStart = 50; % static start image (for all videos)
staticFramesAtVideoEnd = 100; % static end image (half of the versions end after building the curve)
staticFramesAtFullOrders = 10; % in between every rotation section
staticFramesBetweenOutAndIn = 50; % static start image  (half of the versions zoom back in)
nFramesZoomIn = 1000; % zoom back in

nFramesZoomOut = length(angleList)*maxOrder + staticFramesAtFullOrders*(maxOrder-1); % inital Frame + (rotation + intermediate state of the curve)*order
xMinR = -0.1*ones(1,nFramesZoomOut); % initial range
xMaxR = +2.1*ones(1,nFramesZoomOut); % initial range
yMinR = -1.1*ones(1,nFramesZoomOut); % initial range
yMaxR = +1.1*ones(1,nFramesZoomOut); % initial range

h_xy = []; h_ro = []; % init
videoFileNames = {}; % init
xySize = 1024; % pixel size of video;  multiple-of-16 boundaries (MPEG splits the video into 16x16 squares called macroblocks)

for mode = {'xyLim','chamfered','rectangular'} %
    if strcmpi(mode{1},'rectangular')
        liWidth = interp1([ 0   0.09  0.5  0.75  1  ]*nFramesZoomOut... during the run
            ,             [28  28     8    1.6   1.3]... defined Linewidth
            ,             1:nFramesZoomOut); % LineWidth sampled for all frames
    elseif strcmpi(mode{1},'chamfered')
        liWidth = interp1([ 0   0.09  0.5  0.75  1  ]*nFramesZoomOut... during the run
            ,             [24  24     4    1.1   1.1]... defined Linewidth
            ,             1:nFramesZoomOut); % LineWidth sampled for all frames
    end
    
    switch mode{1}
        case {'rectangular','chamfered'}
            % create video object
            cd(pathstr); % set path to working folder
            
            videoFileNames{end+1} = [fname '_' mode{1} '_unnum'];
            vid_u = VideoWriter(videoFileNames{end},'MPEG-4'); % Prepare the new file
            vid_u.FrameRate = 50;
            vid_u.Quality = 100; % quality in [0% 100%]
            open(vid_u);
            
            videoFileNames{end+1} = [fname '_' mode{1} '_zoom_unnum'];
            vid_uz = VideoWriter(videoFileNames{end},'MPEG-4'); % Prepare the new file
            vid_uz.FrameRate = 50;
            vid_uz.Quality = 100; % quality in [0% 100%]
            open(vid_uz);
            
            videoFileNames{end+1} = [fname '_' mode{1} '_numbered'];
            vid_n = VideoWriter(videoFileNames{end},'MPEG-4'); % Prepare the new file
            vid_n.FrameRate = 50;
            vid_n.Quality = 100; % quality in [0% 100%]
            open(vid_n);
            
            videoFileNames{end+1} = [fname '_' mode{1} '_zoom_numbered'];
            vid_nz = VideoWriter(videoFileNames{end},'MPEG-4'); % Prepare the new file
            vid_nz.FrameRate = 50;
            vid_nz.Quality = 100; % quality in [0% 100%]
            open(vid_nz);
    end
    
    x_y = [0 0;0 1];  % inital line [x1 x2... ; y1 y2...];
    iFrame    = 0;    % init

    set(figHandle, 'Position',[1 1 xySize xySize]);
    if ~all(get(figHandle, 'Position')==[1 1 xySize xySize])
        error('Figure pos not set propper.')
    end
 
    for orderr = 1:maxOrder % create zoom out; generating the dragon curve
        
        
        rotPoint_x_y = x_y(:,end); % point of rotation [x_end; y_end]
        
        x_y_new = fliplr(x_y); 
        x_y_new = x_y_new - rotPoint_x_y*ones(1,size(x_y_new,2)); % shift to zero at point of rotation
        
        for currA = angleList % rotate the current state
            
            
            iFrame = iFrame+1; % next frame
            [x_y_newRot] = rotateCordiantes(x_y_new,currA); % rotate
            x_y_newRot = x_y_newRot + rotPoint_x_y*ones(1,size(x_y_newRot,2)); % shift back

            switch mode{1}
                
                case 'xyLim'
                    xMinR(iFrame:end) = min([xMinR(iFrame) x_y(1,:) x_y_newRot(1,:)]); % record extreme range
                    xMaxR(iFrame:end) = max([xMaxR(iFrame) x_y(1,:) x_y_newRot(1,:)]); % record extreme range
                    yMinR(iFrame:end) = min([yMinR(iFrame) x_y(2,:) x_y_newRot(2,:)]); % record extreme range
                    yMaxR(iFrame:end) = max([yMaxR(iFrame) x_y(2,:) x_y_newRot(2,:)]); % record extreme range
                    
                case {'rectangular','chamfered'}
                    cla(axesHandle)
                    
                    setXYlim(axesHandle, [xMinR(iFrame) xMinR(iFrame)+maxR(iFrame)], [yMinR(iFrame) yMinR(iFrame)+maxR(iFrame)]) % use pre-created zoom
                    
                    h_xy = plot(x_y(1,:), x_y(2,:), 'b.-','LineWidth',liWidth(iFrame),'MarkerSize',3.4*liWidth(iFrame)); % non rotating original line
                    h_ro = plot(x_y_newRot(1,:), x_y_newRot(2,:), 'k.-','LineWidth',liWidth(iFrame),'MarkerSize',3.4*liWidth(iFrame)); %  rotating section
                    plot(rotPoint_x_y(1),rotPoint_x_y(2),'.r','MarkerSize',liWidth(iFrame)*6); % rotation point marker
                    
                    drawnow; %
                    f1 = getframe(figHandle);
                    writeVideo(vid_u ,f1.cdata); % save video frame
                    writeVideo(vid_uz,f1.cdata); % save video frame
                    if iFrame == 1
                        for iStat = 1:staticFramesAtVideoStart % start video extra static image
                            writeVideo(vid_u ,f1.cdata); % save video frame
                            writeVideo(vid_uz,f1.cdata); % save video frame
                        end
                        veryFirstFrame = false; % deactivate
                    end
                    
                    if currA < pi*0.25
                        text_s = num2str(orderr-1); % order string
                        co = interp1([-100 pi*0.1 pi*0.15 100],[0 0 1 1],currA);
                    else
                        text_s = num2str(orderr);   % order string
                        co = interp1([-100 pi*0.35 pi*0.4 100],[1 1 0 0],currA);
                    end
                    tHand = text(0.075*xySize,0.075*xySize,text_s,... % add order text
                        'FontName','Helvetica Narrow','Color',co*[1 1 1],...
                        'FontUnits','pixels','Units','pixel',...
                        'FontSize',0.11*xySize,'FontWeight','bold',...
                        'HorizontalAlignment','left','VerticalAlignment','baseline');
                    
                    drawnow; %
                    f2 = getframe(figHandle);
                    writeVideo(vid_n ,f2.cdata); % save video frame
                    writeVideo(vid_nz,f2.cdata); % save video frame
                    if veryFirstFrame
                        for iStat = 1:staticFramesAtVideoStart % start video extra static image
                            writeVideo(vid_n ,f2.cdata); % save video frame
                            writeVideo(vid_nz,f2.cdata); % save video frame
                        end
                    end
            end
        end
        %% transition between two rotations
        if orderr < maxOrder % not after last order
            for iTrans = 1:staticFramesAtFullOrders
                iFrame = iFrame+1; % next frame
                switch mode{1}
                    case 'xyLim'
                            xMinR(iFrame:end) = min([xMinR(iFrame) x_y(1,:) x_y_newRot(1,:)]); % record extreme range
                            xMaxR(iFrame:end) = max([xMaxR(iFrame) x_y(1,:) x_y_newRot(1,:)]); % record extreme range
                            yMinR(iFrame:end) = min([yMinR(iFrame) x_y(2,:) x_y_newRot(2,:)]); % record extreme range
                            yMaxR(iFrame:end) = max([yMaxR(iFrame) x_y(2,:) x_y_newRot(2,:)]); % record extreme range
                        
                    case {'rectangular','chamfered'}
                        
                        x_y_trans = x_y;
                        x_y_rotTrans = x_y_newRot;
                        
                        transFactor = interp1([1 staticFramesAtFullOrders],[0 1],iTrans);
                        cla(axesHandle)
                        setXYlim(axesHandle, [xMinR(iFrame) xMinR(iFrame)+maxR(iFrame)], [yMinR(iFrame) yMinR(iFrame)+maxR(iFrame)])
                        
                        
                        shiftColor = [0 0 1-transFactor]; % from black to blue
                        if strcmpi(mode{1},'chamfered')
                            x_y_trans(:,end)  = interp1([1 0],x_y(:,end-1:end)' ,transFactor*0.25)';
                            x_y_rotTrans(:,1) = interp1([0 1],x_y_newRot(:,1:2)',transFactor*0.25)';
                            plot([x_y_trans(1,end) x_y_rotTrans(1,1)],[x_y_trans(2,end) x_y_rotTrans(2,1)], '-','LineWidth',liWidth(iFrame),'Color',shiftColor/2) %  champfered intersection
                        end

                        h_xy = plot(x_y_trans(1,:), x_y_trans(2,:), '.-','LineWidth',liWidth(iFrame),'MarkerSize',3.4*liWidth(iFrame),'Color',shiftColor); % non rotating original line
                        h_ro = plot(x_y_rotTrans(1,:), x_y_rotTrans(2,:), 'k.-','LineWidth',liWidth(iFrame),'MarkerSize',3.4*liWidth(iFrame)); %  rotating section shifts color
                        
                        if (1-transFactor*2) > 0 % only if MarkerSize positive
                            plot(rotPoint_x_y(1),rotPoint_x_y(2),'.r','MarkerSize',liWidth(iFrame)*6*(1-transFactor*2)); % rotation point marker fade old out
                        end
                        if (transFactor*2-1) > 0 % only if MarkerSize positive
                            plot(x_y_newRot(1,end),x_y_newRot(2,end),'.r','MarkerSize',liWidth(iFrame)*6*(transFactor*2-1)); % rotation point marker fade new in
                        end
                        
                        %%%
                        drawnow; %
                        f1 = getframe(figHandle);
                        writeVideo(vid_u ,f1.cdata); % save video frame
                        writeVideo(vid_uz,f1.cdata); % save video frame
                        if iFrame == 1
                            for iStat = 1:staticFramesAtVideoStart % start video extra static image
                                writeVideo(vid_u ,f1.cdata); % save video frame
                                writeVideo(vid_uz,f1.cdata); % save video frame
                            end
                            veryFirstFrame = false; % deactivate
                        end
                        
                        tHand = text(0.075*xySize,0.075*xySize,text_s,... % add order text
                            'FontName','Helvetica Narrow','Color',[0 0 0],...
                            'FontUnits','pixels','Units','pixel',...
                            'FontSize',0.11*xySize,'FontWeight','bold',...
                            'HorizontalAlignment','left','VerticalAlignment','baseline');
                        
                        drawnow; %
                        f2 = getframe(figHandle);
                        writeVideo(vid_n ,f2.cdata); % save video frame
                        writeVideo(vid_nz,f2.cdata); % save video frame
                        if veryFirstFrame
                            for iStat = 1:staticFramesAtVideoStart % start video extra static image
                                writeVideo(vid_n ,f2.cdata); % save video frame
                                writeVideo(vid_nz,f2.cdata); % save video frame
                            end
                        end
                end
                %%%
            end
        end
        
        %% build curve
        switch mode{1}
            case {'xyLim','rectangular'}
                x_y = [x_y  x_y_newRot(:,2:end)]; % extend curve
                x_y = round(x_y); % eliminate any rounding errors by the rotation (not really a problem)
            case {'chamfered'}
                x_y = [x_y_trans x_y_rotTrans]; % extend curve
                x_y = round(x_y.*4)./4; % eliminate any rounding errors by the rotation (not really a problem)
        end
    end
    
    switch mode{1} %
        case {'rectangular','chamfered'}
            for iStat = 1:staticFramesAtVideoEnd % end video extra static image
                writeVideo(vid_u,f1.cdata); % save extra video frame
                writeVideo(vid_n,f2.cdata); % save extra video frame
            end
            
            %% zoom inwards
            for iStat = 1:staticFramesBetweenOutAndIn % pause video using extra static image
                writeVideo(vid_uz,f1.cdata); % save extra video frame
                writeVideo(vid_nz,f2.cdata); % save extra video frame
            end
            
            %% zoom back in
            aFrames = 40; % frames for acceleration
            cFrames = 20; % frames for constant speed
            dFrames = 160; % frames for deceleration
            RangeChangeSpeed = [linspace(0,1,aFrames) ones(1,cFrames) linspace(1,0,dFrames) zeros(1,nFramesZoomIn-aFrames-cFrames-dFrames)];
            Range_Change  = cumsum(RangeChangeSpeed)/sum(RangeChangeSpeed); % create position, normalize, scale
            maxR(end); % start Range
            endRange = 30; % end Range
            rangeList = maxR(end)-Range_Change*(maxR(end)-endRange);
            
            liWidthZoom = interp1(maxR+linspace(0,0.001,nFramesZoomOut),liWidth,rangeList); % remap the old liWidth list to new ranges; +linspace(0,0.001,nFramesZoomOut) to make input strictly increasing
            
            aFrames = 40; % frames for acceleration
            cFrames = 10;20; % frames for constant speed
            dFrames = 120;100; % frames for deceleration
            finMovSpeed = 0.015;0.02; % by trial and error
            PosChangeSpeed = [linspace(0,1,aFrames) ones(1,cFrames) linspace(1,finMovSpeed,dFrames) ones(1,nFramesZoomIn-aFrames-cFrames-dFrames)*finMovSpeed];
            Pos_Change  = cumsum(PosChangeSpeed)/sum(PosChangeSpeed); % create position, normalize, scale
            
            xPos = xMinR(end)+ Pos_Change*(90 -xMinR(end)); % stretch from generic shape to start and end point
            yPos = yMinR(end)+ Pos_Change*(270-yMinR(end)); % stretch from generic shape to start and end point
            
            figure(43542); clf; hold on; grid on
            title('limits zoom in')
            plot(1:nFramesZoomIn,xPos,'r', 1:nFramesZoomIn,xPos+rangeList,'r', 1:nFramesZoomIn,yPos,'b', 1:nFramesZoomIn,yPos+rangeList,'b');
            legend({'x limits','x limits','y limits','y limits'})
            
            figure(figHandle); % back to main figure
            for iFrame = 1:nFramesZoomIn %
                set(h_xy,'LineWidth',liWidthZoom(iFrame),'MarkerSize',3.4*liWidthZoom(iFrame)); % linewidth
                set(h_ro,'LineWidth',liWidthZoom(iFrame),'MarkerSize',3.4*liWidthZoom(iFrame)); % linewidth
                
                set(tHand,'Color',[1 1 1]); % hide text
                setXYlim(axesHandle, [xPos(iFrame) xPos(iFrame)+rangeList(iFrame)], [yPos(iFrame) yPos(iFrame)+rangeList(iFrame)]) % use pre-created zoom
                drawnow
                f1 = getframe(figHandle);
                writeVideo(vid_uz,f1.cdata); % save video frame
                
                if iFrame<=10 % at the start of the zoom in -> fade out the number
                    col = interp1([0 5 10],[0 0 1],iFrame);
                    set(tHand,'Color',col*[1 1 1]); %
                else
                    set(tHand,'String',''); % just get rid of the number from now on
                end
                f2 = getframe(figHandle);
                writeVideo(vid_nz,f2.cdata); % save video frame
            end
    end

    switch mode{1}
        case 'xyLim'
            % getting a smooth zoom is the most difficult part
            % the image is defined as square, but the full height and width
            % is not always required. Extra space is assigned at the side,
            % which requires it next.
            
            constPadding = 0.015; % 1.5% padding around the actually used area
            
            paddingFactorLowLeft  = interp1([1 [0.15 0.2 0.8 0.95 1]*nFramesZoomOut], [1 1 1.04 1.04 1 1]+constPadding, 1:nFramesZoomOut);
            xMinR = xMinR.*paddingFactorLowLeft; % start and end fit nicely with constPadding but during movement some padding is required around the dragon curve
            yMinR = yMinR.*paddingFactorLowLeft; % start and end fit nicely with constPadding but during movement some padding is required around the dragon curve

            paddingFactorTopRight = interp1([1 [0.15 0.2 0.8 0.95 1]*nFramesZoomOut], [1 1 1.02 1.02 1 1]+constPadding, 1:nFramesZoomOut);
            xMaxR = xMaxR.*paddingFactorTopRight; % start and end fit nicely with constPadding but during movement some padding is required around the dragon curve
            yMaxR = yMaxR.*paddingFactorTopRight; % start and end fit nicely with constPadding but during movement some padding is required around the dragon curve
            
            xRange = xMaxR-xMinR;  yRange = yMaxR-yMinR;

            maxR = max(xRange,yRange);
            assignableX = (maxR-xRange); % assignable space in x-direction
            assignableY = (maxR-yRange); % assignable space in y-direction
            
            figure(43543); clf; hold on; grid on
            title('required limits')
            plot([1:nFramesZoomOut nFramesZoomOut:-1:1],[xMinR fliplr(xMaxR)],'r', [1:nFramesZoomOut nFramesZoomOut:-1:1],[yMinR fliplr(yMaxR)],'b');
            plot(assignableX,'m'); plot(assignableY,'k');
            legend({'x limits','y limits','assignableX','assignableY'})
 
            for iFrame = 1:nFramesZoomOut
                xRange = xMaxR-xMinR;  yRange = yMaxR-yMinR;
                maxR = max(xRange,yRange);
                assignableX = (maxR-xRange); % assignable space in x-direction
                assignableY = (maxR-yRange); % assignable space in y-direction
                
                if assignableX(iFrame)>0 % x has wiggle room
                    needAtRight = find(xMaxR >= xMaxR(iFrame)+ assignableX(iFrame),1,'first'); % when will space be required next?
                    needAtLeft  = find(xMinR <= xMinR(iFrame)- assignableX(iFrame),1,'first'); % when will space be required next?
                    
                    if and(isempty(needAtRight),isempty(needAtLeft))
                        nVal = xMinR(iFrame)-assignableX(iFrame)/2;
                        xMinR(iFrame:end) = min(xMinR(iFrame:end),nVal); % assign space
                        nVal = xMaxR(iFrame)+assignableX(iFrame)/2;
                        xMaxR(iFrame:end) = max(xMaxR(iFrame:end),nVal); % assign space
                    elseif or(isempty(needAtLeft), needAtLeft>needAtRight)
                        nVal = xMaxR(iFrame)+assignableX(iFrame);
                        xMaxR(iFrame:end) = max(xMaxR(iFrame:end),nVal); % assign space
                    elseif or(isempty(needAtRight), needAtLeft<needAtRight)
                        nVal = xMinR(iFrame)-assignableX(iFrame);
                        xMinR(iFrame:end) = min(xMinR(iFrame:end),nVal); % assign space
                    end
                end
                if assignableY(iFrame)>0 % y has wiggle room
                    needAtRight = find(yMaxR >= yMaxR(iFrame)+ assignableY(iFrame),1,'first'); % when will space be required next?
                    needAtLeft  = find(yMinR <= yMinR(iFrame)- assignableY(iFrame),1,'first'); % when will space be required next?
                    
                    if and(isempty(needAtRight),isempty(needAtLeft))
                        nVal = yMinR(iFrame)-assignableY(iFrame)/2;
                        yMinR(iFrame:end) = min(yMinR(iFrame:end),nVal); % assign space
                        nVal = yMaxR(iFrame)+assignableY(iFrame)/2;
                        yMaxR(iFrame:end) = max(yMaxR(iFrame:end),nVal); % assign space
                    elseif or(isempty(needAtRight), needAtLeft<needAtRight)
                        nVal = yMinR(iFrame)-assignableY(iFrame);
                        yMinR(iFrame:end) = min(yMinR(iFrame:end),nVal); % assign space
                    elseif or(isempty(needAtLeft), needAtLeft>needAtRight)
                        nVal = yMaxR(iFrame)+assignableY(iFrame);
                        yMaxR(iFrame:end) = max(yMaxR(iFrame:end),nVal); % assign space
                    end
                end
            end
            
            % the zomm [min max] covers now the neccessary area but is very "stuttering"
            figure(43544); clf; hold on; grid on
            title('limits with assigned space/ filtered')
            plot([1:nFramesZoomOut nFramesZoomOut:-1:1],[xMinR fliplr(xMaxR)],'r', [1:nFramesZoomOut nFramesZoomOut:-1:1],[yMinR fliplr(yMaxR)],'b');
            % create smooth zoom with moving average filter & Zero-phase distortion
            wind = 60; % window size
            xMinR = filtfilt(ones(1,wind)/wind,1,(xMinR));
            xMaxR = filtfilt(ones(1,wind)/wind,1,(xMaxR));
            yMinR = filtfilt(ones(1,wind)/wind,1,(yMinR));
            yMaxR = filtfilt(ones(1,wind)/wind,1,(yMaxR));
 
            % Filter form end to start (right to left). This creates space anticipatory rather then lagging.
            % As a result the dragon_curve does not reach out of the frame 
            wind = 48;  b=ones(1,wind)/wind;  a=1; % filter parameters
            xMinR = fliplr(filter(b,a,fliplr(xMinR),filtic(b,a,ones(1,wind)*xMinR(end),ones(1,wind)*xMinR(end))));
            xMaxR = fliplr(filter(b,a,fliplr(xMaxR),filtic(b,a,ones(1,wind)*xMaxR(end),ones(1,wind)*xMaxR(end))));
            yMinR = fliplr(filter(b,a,fliplr(yMinR),filtic(b,a,ones(1,wind)*yMinR(end),ones(1,wind)*yMinR(end))));
            yMaxR = fliplr(filter(b,a,fliplr(yMaxR),filtic(b,a,ones(1,wind)*yMaxR(end),ones(1,wind)*yMaxR(end))));
            xRange = xMaxR-xMinR;  yRange = yMaxR-yMinR;
            maxR = max(xRange,yRange);
            
            plot([1:nFramesZoomOut nFramesZoomOut:-1:1],[xMinR fliplr(xMaxR)],'r:', [1:nFramesZoomOut nFramesZoomOut:-1:1],[yMinR fliplr(yMaxR)],'b:');
            legend({'x limits','y limits','x filtered','y filtered'})
            figure(figHandle); % back to main figure
            
        otherwise %  {'rectangular','chamfered'}
            % finish animation            
            close(vid_u ); disp(['MP4 completed: ' videoFileNames{end-3} '.mp4']);
            close(vid_uz); disp(['MP4 completed: ' videoFileNames{end-2} '.mp4']);
            close(vid_n ); disp(['MP4 completed: ' videoFileNames{end-1} '.mp4']);
            close(vid_nz); disp(['MP4 completed: ' videoFileNames{end}   '.mp4']);
    end
end

for iVid = 1:numel(videoFileNames)
    disp(['Conversion of ' videoFileNames{iVid} ' from MP4 to WebM (Matlab currently does not support webm)']);
    if exist('ffmpeg.exe','file') == 2 % check if it is a valid path to an existing file
        try
            dosCommand = ['!ffmpeg -i ' videoFileNames{iVid} '.mp4 '...   % Command and source
                '-c:v libvpx-vp9 -crf 30 -b:v 0 -deadline best '... % constant (best) quality; see: https://trac.ffmpeg.org/wiki/Encode/VP9
                '-metadata title="' videoFileNames{iVid} '" '... % see: https://wiki.multimedia.cx/index.php/FFmpeg_Metadata
                '-metadata author="Jahobr" -metadata copyright="CC0 1.0 Universal Public Domain Dedication" '...
                '-metadata license="CC0 1.0 Universal Public Domain Dedication" '...
                videoFileNames{iVid} '.webm'];                            % conversion target
            eval(dosCommand); % run conversion from mp4 to webm
            delete(fullfile(pathstr,[videoFileNames{iVid} '.mp4'])); % delete mp4 version after conversion (to save disc space)
        catch ME
            disp(ME)
        end
    else
        disp(['"ffmpeg.exe" not available in path "' pathstr '" (or other problem); see https://ffmpeg.zeranoe.com/builds/']);
    end
end

 
function [xy] = rotateCordiantes(xy,anglee)
% [x1 x2 x3 ... ; y1 y2 y3 ...] coordinates to rotate
% anglee angle of rotation in [rad]
rotM = [cos(anglee) -sin(anglee); sin(anglee) cos(anglee)];
xy = rotM*xy;


function setXYlim(axesHandle,xLimits,yLimits)
% set limits; practically the axis overhangs the figure all around, to
% hide rendering errors at line-ends.
% Input:
%   axesHandle:        
%   xLimits, yLimits:  [min max]
overh = 0.05; % 5% overhang all around; 10% bigger in x and y
xlim([+xLimits(1)*(1+overh)-xLimits(2)*overh  -xLimits(1)*overh+xLimits(2)*(1+overh)])
ylim([+yLimits(1)*(1+overh)-yLimits(2)*overh  -yLimits(1)*overh+yLimits(2)*(1+overh)])
set(axesHandle,'Position',[-overh -overh  1+2*overh 1+2*overh]); % stretch axis as bigger as figure, [x y width height]
drawnow;

Licensing

I, the copyright holder of this work, hereby publish it under the following license:
Creative Commons CC-Zero This file is made available under the Creative Commons CC0 1.0 Universal Public Domain Dedication.
The person who associated a work with this deed has dedicated the work to the public domain by waiving all of their rights to the work worldwide under copyright law, including all related and neighboring rights, to the extent allowed by law. You can copy, modify, distribute and perform the work, even for commercial purposes, all without asking permission.

Assessment

Media of the day This file was selected as the media of the day for 31 May 2019. It was captioned as follows:
English: Animation of an unfolding Dragon curve. The order is increased from 0 to 17. The curve is chamfered for better visibility of the path. After reaching order 17 it is zoomed in to show the emerging pattern.
Other languages
Čeština: Animace iteračního výpočtu dračí křivky do 17 iteračních kroků. Po dosažení 17. kroku je výsledný vzor zvětšen pro názorné zobrazení výsledné křivky.
Deutsch: Erstellung einer Drachenkurve durch wiederholtes Kopieren und Rotation der Kopie um 90 Grad.
English: Animation of an unfolding Dragon curve. The order is increased from 0 to 17. The curve is chamfered for better visibility of the path. After reaching order 17 it is zoomed in to show the emerging pattern.
Polski: Animacja rozwijającego się smoka Heighwaya. Rząd krzywej zmienia się od 0 do 17. Dla lepszej widoczności krzywa jest sfazowana. Po osiągnięciu 17. rzędu zostaje powiększona w celu pokazania pojawiającego się wzoru.

Captions

Animation of an unfolding Dragon curve. The order is increased from 0 to 17.

Items portrayed in this file

depicts

30 May 2019

video/webm

File history

Click on a date/time to view the file as it appeared at that time.

Date/TimeThumbnailDimensionsUserComment
current07:25, 30 May 201950 s, 1,024 × 1,024 (99.89 MB)JahobrUser created page with UploadWizard

There are no pages that use this file.

Global file usage

The following other wikis use this file:

Metadata