潰れた空間のCG
不規則な生活で頭がおかしくなったのか、
衝動的に、数学的なCGを書いてみたくなりました。
空間から、空間の一部をくりぬくとどう見えるかという、CGを合成します。
で、スクリーンと画像の間をくりぬきます。 くりぬいた空間は球状。
と言っても、物理や幾何はサッパリなので、適当に設定します。
元画像は
ファイル:19-v 2h Vasnetsov.jpg - Wikipedia
から拝借
なんか、ただ単にでっかい凸レンズが置いてあるだけのような・・・
面白くないですが、一応、ソースも置いておきます。
#encoding:shift-jis from __future__ import with_statement, division, print_function import Image from math import * from itertools import * dist_size = (1024, 768) src_image_path = u"岐路に立つ騎士(ヴィクトル・ヴァスネツォフ画,1878).jpg" src = Image.open(src_image_path).convert("RGB") D1 = 2 # 描画先スクリーンとの距離 S1 = (2 * dist_size[0] / dist_size[1], 2) # 描画先スクリーンのサイズ / 2 D0 = 4 # くりぬかれた球体との距離 R = 1 # 球体の半径 D2 = 6 #元画像との距離 S2 = (6 * src.size[0] / src.size[1], 6) MaxTheta = asin(R / D0) assert 0 < MaxTheta def s1pos_to_s2pos(s1pos): r1 = sqrt(s1pos[0]**2 + s1pos[1]**2) theta = atan(r1 / D1) alpha = atan2(s1pos[1], s1pos[0]) if abs(theta) < MaxTheta: r2 = -r1 * (2 * D0 - D2) / D1 else: r2 = r1 * D2 / D1 return (r2 * cos(alpha), r2 * sin(alpha)) def dist_to_src(dist_pixel_pos): s1pos = tuple( S1[i] * (dist_pixel_pos[i] / dist_size[i] - 0.5) for i in [0, 1]) s2pos = s1pos_to_s2pos(s1pos) return tuple( src.size[i] * (s2pos[i] / S2[i] + 0.5) for i in [0, 1]) dist = Image.new("RGB", dist_size, (0, 0, 0)) for dist_pixel_pos in product(xrange(dist_size[0]), xrange(dist_size[1])): src_pixel_pos = dist_to_src(dist_pixel_pos) if (0 <= src_pixel_pos[0] < src.size[0] and 0 <= src_pixel_pos[1] < src.size[1]): c = src.getpixel(src_pixel_pos) else: c = (0, 0, 0) dist.putpixel(dist_pixel_pos, c) dist.save("a.png") dist.show()