先日ノーベル物理学賞を受賞した
ロジャー・ペンローズさんの話です。

 
解説動画はこちら


2020年のノーベル物理学賞は
ブラックホールに関係する物でしたね。

去年こちらのサイトでも
ブラックホール関連を
取り上げていたりしますので
気になる方はこちらもどうぞ。

ブラックホールデカすぎワロタ

さて、今年ノーベル物理学賞を受賞した
ロジャーペンローズさんですが
1931年生まれの89歳くらいの方で
イギリスの数理物理学者、数学者、科学哲学者

受賞理由としては
ブラックホールの形成が一般相対性理論の
強力な裏付けであることの発見だそうです。

一応相対性理論は20世紀初頭に
アインシュタインが創始した
時間と空間に関する理論の事で

ブラックホールの形成過程を
数学的に示したことの論文(1965年)
Gravitational Collapse and Space-Time Singularities
(重力崩壊と時空特異点) 

これが受賞の決め手になったようですね。

アインシュタイン自身はブラックホールを
否定していたけども
ペンローズさんはそれを数学的に
証明したよーって事みたいですね
よくは分かりませんが。


そんなペンローズさんは
色々な不可思議図形を残していたりします。

ペンローズの階段
スクリーンショット 2020-10-10 16.51.39


ペンローズの三角形
スクリーンショット 2020-10-10 16.51.45

こう言う不可思議図形を
考えたりするのが得意だったんでしょうね。

もう一つ有名なのが
「ペンローズのタイル」と言う物で
2種類のひし形で平面を埋めつくす
と言う物です。

いわゆる平面充填問題の一つで
現在では電気剃刀用の網刃として
実用化されているようです。

このペンローズの三角形を
生成するプログラムを
ご紹介します。

なおこのプログラムはこちらの記事を
参考にしています。
参考

なおこの実行には
pycairoと言うライブラリが必要なので
事前にインストールが必要です。

MacOSの方は
brew install cairo pkg-config

conda install pycairo

Anacondaを利用している方は
これでインストール出来るかと思います。

さてコードの方ですが
# 要pycairo のインストール
import math
import cmath
import cairo
import matplotlib.pyplot as plt
from PIL import Image
%matplotlib inline

ratio = (1 + math.sqrt(5)) / 2

# 分割関数
def divine(trs):
    result = []
    for color, a, b, c in trs:
        if color == 0:
            P = a + (b - a) / ratio
            result += [(0, c, P, b), (1, P, c, a)]
        else:
            Q , R = b + (a - b) / ratio , b + (c - b) / ratio
            result += [(1, R, c, a), (1, Q, R, b), (0, R, Q, a)]
    return result

# ペンローズのタイルを作る関数
def make_penrose_tile():
    # 三角形生成
    triangles = []
    for i in range(10):
        b = cmath.rect(1, (2*i - 1) * math.pi / 10)
        c = cmath.rect(1, (2*i + 1) * math.pi / 10)
        if i % 2 == 0:
            b, c = c, b
        triangles.append((0, 0j, b, c))
    for i in range(SUBDIVISIONS):
        triangles = divine(triangles)

    # 描画設定
    surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, SIZE[0], SIZE[1])
    cr = cairo.Context(surface)
    cr.translate(SIZE[0] / 2.0, SIZE[1] / 2.0)
    radius = 1.2 * math.sqrt((SIZE[0] / 2.0) ** 2 + (SIZE[1] / 2.0) ** 2)
    cr.scale(radius, radius)

    # 赤三角の描画
    for color, a, b, c in triangles:
        if color == 0:
            cr.move_to(a.real, a.imag)
            cr.line_to(b.real, b.imag)
            cr.line_to(c.real, c.imag)
            cr.close_path()
    cr.set_source_rgb(t_color1[0],t_color1[1],t_color1[2])
    cr.fill()    

    # 青三角の描画
    for color, a, b, c in triangles:
        if color == 1:
            cr.move_to(a.real, a.imag)
            cr.line_to(b.real, b.imag)
            cr.line_to(c.real, c.imag)
            cr.close_path()
    cr.set_source_rgb(t_color2[0],t_color2[1],t_color2[2])
    cr.fill()

    # 三角形のサイズから線幅を決定
    color, a, b, c = triangles[0]
    cr.set_line_width(abs(b - a) / 10.0)
    cr.set_line_join(cairo.LINE_JOIN_ROUND)

    # 外枠の描画
    for color, a, b, c in triangles:
        cr.move_to(c.real, c.imag)
        cr.line_to(a.real, a.imag)
        cr.line_to(b.real, b.imag)
    cr.set_source_rgb(l_color[0],l_color[1],l_color[2])
    cr.stroke()

    # 画像の保存
    surface.write_to_png('penrose.png')

実行部分はコレ
# 設定
SIZE,SUBDIVISIONS = (1000, 1000) , 8
t_color1, t_color2 , l_color = (1.0, 0.1, 0.1),(0.4, 0.4, 1.0),(0.2, 0.2, 0.2)
# タイルの作成
make_penrose_tile()
im = Image.open("penrose.png")
plt.figure(figsize=(8,8));plt.imshow(im);plt.show()

実行するには画像サイズ(SIZE)と
分割数(SUBDIBISIONS)を変えてもらい
色を変えたければcolorは3つ変更箇所があるので
そこの数値を弄ると変更できます。

実行するとローカルに画像が生成され
それを表示しています。

download-2

こんな感じのタイルが生成されます。

分割数を大きくすると
download-3

より細かくなっていきます。

ひし形2種類の色合いを変えれば
download-1
こんなモノクロも生成できますんで
興味がある方は試してみてください。

それでは。