C#による中心起点型素数螺旋プロットの生成アルゴリズム

中心座標を原点とする二次元平面に自然数を螺旋状に展開し、素数の位置を可視化する処理を実装する際には、座標軌跡の制御ロジックと効率的な素数判定が鍵となります。以下に、標準ライブラリのみを使用して記述された実装例を示します。

素数判定の基礎となる関数は、試行除算を最適化しています。偶数および3の倍数を早期に除外し、5を起点として6刻みで剰余演算を行うことで、比較回数を削減しています。

private static bool CheckPrimality(long target)
{
    if (target < 2L) return false;
    if (target == 2L || target == 3L) return true;
    if (target % 2L == 0L || target % 3L == 0L) return false;

    for (long divisor = 5L; divisor * divisor <= target; divisor += 6L)
    {
        if (target % divisor == 0L || target % (divisor + 2L) == 0L)
            return false;
    }
    return true;
}

連続する整数の軌跡を生成する部分は、従来の半径ベースの制御から、方向ベクトル配列とステップカウンターを用いた状態遷移モデルへ再構築しました。このアプローチにより、曲率の変化点での座標更新ロジックが明確になります。

public static void GenerateSpiralVisualization(int canvasWidth, int canvasHeight, string dataFilePath)
{
    var graphicSurface = new System.Drawing.Bitmap(canvasWidth, canvasHeight);
    var defaultPen = new System.Drawing.SolidBrush(System.Drawing.Color.Gray);
    
    int originX = canvasWidth / 2;
    int originY = canvasHeight / 2;

    int[] moveDeltaX = { 0, -1, 0, 1 };
    int[] moveDeltaY = { 1, 0, -1, 0 };
    
    int activeDirection = 0;
    int segmentLength = 1;
    int traveledSteps = 0;
    int phaseCounter = 0;

    int cursorX = originX;
    int cursorY = originY;
    long sequenceValue = 0;

    var streamWriter = new System.IO.StreamWriter(dataFilePath);

    try 
    {
        while (cursorX >= 0 && cursorX < canvasWidth && cursorY >= 0 && cursorY < canvasHeight)
        {
            bool isPrimeStatus = CheckPrimality(sequenceValue);
            var renderColor = isPrimeStatus ? System.Drawing.Color.Blue : defaultPen.Color;
            
            graphicSurface.SetPixel(cursorX, cursorY, renderColor.ToArgb());
            streamWriter.WriteLine($"({cursorX},{cursorY})={sequenceValue},{(isPrimeStatus ? 1 : 0)}");

            traveledSteps++;
            if (traveledSteps == segmentLength)
            {
                activeDirection = (activeDirection + 1) % 4;
                traveledSteps = 0;
                phaseCounter++;
                if (phaseCounter % 2 == 0) segmentLength++;
            }

            cursorX += moveDeltaX[activeDirection];
            cursorY += moveDeltaY[activeDirection];
            sequenceValue++;
        }
    }
    finally 
    {
        streamWriter.Close();
        defaultPen.Dispose();
        graphicSurface.Save(dataFilePath.Replace("txt", "bmp"));
        graphicSurface.Dispose();
    }
}

上記の実装では、初期位置から「上→左→下→右」という4方位の回転パターンを採用し、各線分を進む距離が同じ方向移動ごとに2回ずつ増加する規則に従っています。これにより、螺旋の節目ごとの座標変化を単一のループで管理できます。描画結果では、発見された素数座標を青系統で固定着色し、非素数については現在の進行フェーズと表示領域の尺度比に基づいてグレースケール値を動的に算出する構成としています。

タグ: csharp ulam-spiral computational-geometry prime-checking image-rendering

6月2日 16:44 投稿