1. 中心から、連続して、らせん状に正方形をsetしていく
大きさ10の正方形を使って、色を順に1から15を割り当て、画面640x480の中央でset,
右1進みset
上1進みset
左2進みset
下2進みsetと、らせん状に進めていく。中心から、連続して、正方形をsetしていくようにする。
import pyxel
# 色範囲の定義(Pyxelの16色パレットから使用する範囲)
COLOR_START = 1 # 開始色番号
COLOR_END = 15 # 終了色番号
SIZE = 10 # 各正方形のサイズ(ピクセル)
WIDTH = 640 # 画面幅
HEIGHT = 480 # 画面高さ
class SpiralSquares:
def __init__(self):
# Pyxelの初期化(画面サイズとタイトルを設定)
pyxel.init(WIDTH, HEIGHT, title="Spiral Squares")
# 使用する色のリストを生成(COLOR_STARTからCOLOR_ENDまで)
self.colors = [i for i in range(COLOR_START, COLOR_END + 1)]
# 正方形の位置と色を格納するリスト(各要素は(x, y, color)のタプル)
self.positions = []
# 螺旋の中心座標(画面中央)
self.cx = WIDTH // 2
self.cy = HEIGHT // 2
# 現在の描画位置(中心からスタート)
self.x = self.cx
self.y = self.cy
# 移動方向ベクトル(最初は右方向)
self.dx = 1 # x方向の移動量(正:右、負:左)
self.dy = 0 # y方向の移動量(正:下、負:上)
# 螺旋のセグメント管理変数
self.segment_length = 1 # 現在のセグメントの長さ(何マス進むか)
self.segment_passed = 0 # 現在のセグメント内で進んだマス数
self.segment_count = 0 # 完了したセグメント数(方向転換の回数)
# 色の管理変数
self.color_index = 0 # 現在使用している色のインデックス
# 配置した正方形の総数(アニメーション進行度の管理)
self.set_count = 0
# メインループを開始(updateとdrawを毎フレーム呼び出す)
pyxel.run(self.update, self.draw)
def update(self):
"""
フレームごとの更新処理
Rキーでリセット、毎フレーム1個ずつ正方形を追加してアニメーション
"""
# Rキーが押されたら全ての状態を初期化してリセット
if pyxel.btnp(pyxel.KEY_R):
# 描画位置を中心に戻す
self.x = self.cx
self.y = self.cy
# 移動方向を右にリセット
self.dx = 1
self.dy = 0
# セグメント管理変数をリセット
self.segment_length = 1
self.segment_passed = 0
self.segment_count = 0
# 色インデックスをリセット
self.color_index = 0
# 配置済みの正方形をクリア
self.positions = []
# カウンターをリセット
self.set_count = 0
# まだ目標数に達していない場合、毎フレーム1個ずつ正方形を追加
# 2209 = 47×47(画面を埋め尽くすのに十分な数)
if self.set_count < 2209:
# 現在位置に正方形を配置(座標と色を記録)
self.positions.append((self.x, self.y, self.colors[self.color_index]))
# 次の色に進む(色リストの範囲を超えたら最初に戻る)
self.color_index += 1
if self.color_index > COLOR_END - COLOR_START:
self.color_index = 0
# 現在の方向に1マス進む(SIZE分だけ移動)
self.x += self.dx * SIZE
self.y += self.dy * SIZE
# 現在のセグメント内での進行カウントを増やす
self.segment_passed += 1
# 配置した正方形の総数をカウント
self.set_count += 1
# 現在のセグメントを完了したら方向転換
if self.segment_passed == self.segment_length:
# セグメント内カウンターをリセット
self.segment_passed = 0
# セグメント完了回数を増やす
self.segment_count += 1
# 時計回りに90度回転(右→下→左→上→右...)
# (dx, dy) を (-dy, dx) に変換することで90度回転
# 例: (1,0)→(0,1)→(-1,0)→(0,-1)→(1,0)
self.dx, self.dy = -self.dy, self.dx
# 2回方向転換するごとにセグメント長を1増やす
# 螺旋パターン: 1右→1下→2左→2上→3右→3下→...
if self.segment_count % 2 == 0:
self.segment_length += 1
def draw(self):
"""
フレームごとの描画処理
画面をクリアして現在配置されている全ての正方形を描画
"""
# 画面を黒(色番号0)でクリア
pyxel.cls(0)
# これまでに配置された全ての正方形を描画
for px, py, c in self.positions:
# 各正方形を指定位置・サイズ・色で描画
# rect(x, y, width, height, color)
pyxel.rect(px, py, SIZE, SIZE, c)
# スクリプトとして実行された場合のみインスタンスを生成
if __name__ == "__main__":
SpiralSquares()
リアルタイム生成: update()内で毎フレーム1個ずつ正方形を追加
- アニメーション効果: 螺旋が中心から外側に向かって徐々に描かれる様子が見える
- リセット機能: Rキーで全ての状態を初期化して最初からアニメーションを再生
螺旋生成のアルゴリズム
- 時計回りの螺旋: 右→下→左→上の順で方向転換
- セグメント長の規則: 1, 1, 2, 2, 3, 3, 4, 4, ... と増加
- 色のサイクル: 15色(1〜15)を順番に使用し、繰り返す
配置数の計算
2. set_countが素数の時、正方形をsetしていく
import pyxel
# 色範囲の定義(Pyxelの16色パレットから使用する範囲)
COLOR_START = 1 # 開始色番号
COLOR_END = 15 # 終了色番号
SIZE = 10 # 各正方形のサイズ(ピクセル)
WIDTH = 640 # 画面幅
HEIGHT = 480 # 画面高さ
class SpiralSquares:
def __init__(self):
# Pyxelの初期化(画面サイズとタイトルを設定)
pyxel.init(WIDTH, HEIGHT, title="Spiral Squares")
# 使用する色のリストを生成(COLOR_STARTからCOLOR_ENDまで)
self.colors = [i for i in range(COLOR_START, COLOR_END + 1)]
# 正方形の位置と色を格納するリスト(各要素は(x, y, color)のタプル)
# 素数番目の位置にある正方形のみ記録される
self.positions = []
# 螺旋の中心座標(画面中央)
self.cx = WIDTH // 2
self.cy = HEIGHT // 2
# 現在の描画位置(中心からスタート)
self.x = self.cx
self.y = self.cy
# 移動方向ベクトル(最初は右方向)
self.dx = 1 # x方向の移動量(正:右、負:左)
self.dy = 0 # y方向の移動量(正:下、負:上)
# 螺旋のセグメント管理変数
self.segment_length = 1 # 現在のセグメントの長さ(何マス進むか)
self.segment_passed = 0 # 現在のセグメント内で進んだマス数
self.segment_count = 0 # 完了したセグメント数(方向転換の回数)
# 色の管理変数
self.color_index = 0 # 現在使用している色のインデックス
# 螺旋上の位置カウンター(1から開始、素数判定に使用)
# 1番目、2番目、3番目...という螺旋上の順序を表す
self.set_count = 1
# メインループを開始(updateとdrawを毎フレーム呼び出す)
pyxel.run(self.update, self.draw)
def is_prime(self, n):
"""
素数判定関数
引数nが素数かどうかを判定する
アルゴリズム:
1. 1以下は素数ではない
2. 2は素数
3. 偶数は素数ではない(2を除く)
4. 3以降の奇数で割り切れるかチェック(√nまで)
計算量: O(√n)
"""
# 1以下は素数ではない
if n <= 1:
return False
# 2は最小の素数
if n == 2:
return True
# 2以外の偶数は素数ではない
if n % 2 == 0:
return False
# 3から√nまでの奇数で割り切れるかチェック
# i * i <= n は i <= √n と同じ意味(浮動小数点演算を避けるため)
i = 3
while i * i <= n:
# nがiで割り切れたら素数ではない
if n % i == 0:
return False
# 次の奇数をチェック(偶数は既に除外済み)
i += 2
# どの数でも割り切れなかったら素数
return True
def update(self):
"""
フレームごとの更新処理
Rキーでリセット、毎フレーム螺旋上を1マス進み、素数番目のみ正方形を配置
"""
# Rキーが押されたら全ての状態を初期化してリセット
if pyxel.btnp(pyxel.KEY_R):
# 描画位置を中心に戻す
self.x = self.cx
self.y = self.cy
# 移動方向を右にリセット
self.dx = 1
self.dy = 0
# セグメント管理変数をリセット
self.segment_length = 1
self.segment_passed = 0
self.segment_count = 0
# 色インデックスをリセット
self.color_index = 0
# 配置済みの正方形をクリア
self.positions = []
# カウンターを1にリセット
self.set_count = 1
# まだ目標数に達していない場合、毎フレーム螺旋上を1マス進む
# 2209 = 47×47(画面を埋め尽くすのに十分な数)
if self.set_count < 2209:
# 現在の位置番号が素数かどうかをチェック
# 素数番目の位置にのみ正方形を配置(素数の視覚化)
if self.is_prime(self.set_count):
# 素数番目の位置に正方形を配置(座標と色を記録)
self.positions.append((self.x, self.y, self.colors[self.color_index]))
# 次の色に進む(色リストの範囲を超えたら最初に戻る)
self.color_index += 1
if self.color_index > COLOR_END - COLOR_START:
self.color_index = 0
# 素数かどうかに関わらず、螺旋上を1マス進む
# 現在の方向に1マス移動(SIZE分だけ移動)
self.x += self.dx * SIZE
self.y += self.dy * SIZE
# 現在のセグメント内での進行カウントを増やす
self.segment_passed += 1
# 螺旋上の位置番号を増やす(次のフレームで素数判定に使用)
self.set_count += 1
# 現在のセグメントを完了したら方向転換
if self.segment_passed == self.segment_length:
# セグメント内カウンターをリセット
self.segment_passed = 0
# セグメント完了回数を増やす
self.segment_count += 1
# 時計回りに90度回転(右→下→左→上→右...)
# (dx, dy) を (-dy, dx) に変換することで90度回転
# 例: (1,0)→(0,1)→(-1,0)→(0,-1)→(1,0)
self.dx, self.dy = -self.dy, self.dx
# 2回方向転換するごとにセグメント長を1増やす
# 螺旋パターン: 1右→1下→2左→2上→3右→3下→...
if self.segment_count % 2 == 0:
self.segment_length += 1
def draw(self):
"""
フレームごとの描画処理
画面をクリアして素数番目に配置された全ての正方形を描画
素数の分布パターンを視覚的に表現
"""
# 画面を黒(色番号0)でクリア
pyxel.cls(0)
# 素数番目の位置に配置された全ての正方形を描画
for px, py, c in self.positions:
# 各正方形を指定位置・サイズ・色で描画
# rect(x, y, width, height, color)
pyxel.rect(px, py, SIZE, SIZE, c)
# スクリプトとして実行された場合のみインスタンスを生成
if __name__ == "__main__":
SpiralSquares()
素数の視覚化(ウラムの螺旋)
- このプログラムは「ウラムの螺旋(Ulam Spiral)」として知られる数学的パターンを実装しています。
螺旋上の番号付け: 中心から1, 2, 3, 4, ...と順番に番号を振る
- 素数のみ表示: 素数番目の位置(2, 3, 5, 7, 11, 13, ...)にのみ正方形を配置
- パターンの出現: 素数が対角線状に並ぶ興味深いパターンが視覚化される
素数判定アルゴリズム
- 試し割り法: 3から√nまでの奇数で割り切れるかチェック
最適化: - 偶数は事前に除外(2以外の偶数は素数ではない)
- √nまでしかチェックしない(それ以上は不要)
- 奇数のみチェック(i += 2で2ずつ増やす)
正方形4にして、if self.set_count < 14161:

いろいろ、試してみるですね。ありがとうございます。


