おぼろげながら浮かんできたんです 46という数字が

一発ネタです．以下のgifを作りたくなっただけです．

|![a.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308259/0c94dd95-cab3-e77d-55c2-af26cfa60f97.gif)|![b.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308259/2173805b-2c87-700e-7a97-33641a743076.gif)|

# 補足
タイトルにもある「おぼろげながら浮かんできたんです 46という数字が」は，小泉進次郎氏の有名?な発言です．[YouTube](https://www.youtube.com/watch?v=0IKVb2fIxxc)

https://dic.nicovideo.jp/a/%E3%81%8A%E3%81%BC%E3%82%8D%E3%81%92%E3%81%AA%E3%81%8C%E3%82%89%E6%B5%AE%E3%81%8B%E3%82%93%E3%81%A7%E3%81%8D%E3%81%9F%E3%82%93%E3%81%A7%E3%81%99%2046%E3%81%A8%E3%81%84%E3%81%86%E6%95%B0%E5%AD%97%E3%81%8C

gifは，以下のMATLABプログラムを参考に作成しています．

https://jp.mathworks.com/matlabcentral/communitycontests/contests/6/entries/13962

[MATLAB Shorts Mini Hack](https://jp.mathworks.com/matlabcentral/contests/2024-matlab-mini-hack.html)というコンテストが2024年10月7日から開催されます．

このコンテスト参加にあたり[昨年のコンテスト](https://jp.mathworks.com/matlabcentral/contests/2023-matlab-mini-hack.html)参加プログラムを確認していたところ，
$\pi$が浮かび上がるgifを見つけてしまいました．
そして，どうしても一発ネタを作成する衝動が抑えきれませんでした．

# 解説
元のプログラムは遅い&難解な部分があったので，大幅に書き直しました．
以下のプログラムを動かすと，`animation.gif`が出力されます．

```matlab:contestAnimator.m
function contestAnimator()
    animFilename = 'animation.gif'; % Output file name
    firstFrame = true;
    framesPerSecond = 24;
    delayTime = 1/framesPerSecond;
    % Create the gif
    for frame = 1:48
        drawframe(frame)
        fig = gcf(); 
        fig.Units = 'pixels';
        fig.Position(3:4) = [300,300];
        im = getframe(fig);
        [A,map] = rgb2ind(im.cdata,256);
        if firstFrame
            firstFrame = false;
            imwrite(A,map,animFilename, LoopCount=Inf, DelayTime=delayTime);
        else
            imwrite(A,map,animFilename, WriteMode="append", DelayTime=delayTime);
        end
    end
end

function drawframe(f)
    persistent x y c txt
    nFrames = 48; vertex = 8;
    
    if f == 1
        a = nFrames * vertex;
        [x,y] = pol2cart(2*pi*(1:a)/a, 1);
        x = reshape(x, [], vertex);
        y = reshape(y, [], vertex);
        c = pdist([x(1,:)' y(1,:)']);

        set(gcf, 'Color', 'k');
        axes(Position = [-0.14 -0.14 1.28 1.28]);
        colormap(jet(vertex));
        clim([0.8 2.5])
        txt = text();
        hold on
        axis off
    end
    
    G = graph(ones(vertex), 'omitselfloops');
    plot(G, 'XData', x(f,:), 'YData', y(f,:), 'Marker', 'none', ...
        'NodeLabel', {}, EdgeCData = c, EdgeAlpha = 0.3);

    txt.delete
    txt = text(0, 0, '46', HorizontalAlignment = 'Center', ...
        FontUnits = 'normalized', FontSize = 0.2, Color = 'k');
end
```

`contestAnimator`関数は，[MATLAB Flipbook Mini Hack](https://jp.mathworks.com/matlabcentral/contests/2023-matlab-mini-hack.html)で運営側が用意した関数です．
過去，この関数の解説記事を書いたので，ここでは説明を割愛します．

https://qiita.com/tomtkg/items/b4a40570f846988fafdc

`drawframe`関数は，初回の呼び出しとその後の呼び出しで動作が変わります．
初回呼び出し時は，画像の設定と円周上の点のxy座標，色分けに利用する距離cの計算処理が入ります．

まず，nFramesで必要なフレーム数（=画像数），vertexで円周上の頂点の数を決めます．
次に，`pol2cart`関数を利用し，円周上の点のxy座標を求めます．
`reshape`関数を利用し，1フレームで追加描画する点を分かり易いかたちで整理します．
`pdist`関数を利用し，点群間の距離を求めます．これは，後で色分けで利用します．

画像の形や色に関する設定は，1フレーム目でまとめて行います．
`colormap`と`clim`を変更すると，作成するgifの印象を大きく変更できます．

そして，以下の処理を毎フレーム実行します．
* 指定された点群の完全グラフを画像に追加する
* 46の文字を削除し，一番手前に再描画する

`graph`を利用すると線をまとめて描画でき，動作も軽量になるのでおすすめです．

# 終わりに
[MATLAB Shorts Mini Hack](https://jp.mathworks.com/matlabcentral/contests/2024-matlab-mini-hack.html)では，時間が4秒（=96フレーム）に変更になるだけでなく，
音声も付けられるようです．またネタを探して記事にしたいと思います．