開発環境
- macOS Mojave - Apple (OS)
- Emacs (Text Editor)
- Windows 10 Pro (OS)
- Visual Studio Code (Text Editor)
- Python 3.7 (プログラミング言語)
- GIMP (ビットマップ画像編集・加工ソフトウェア、PPM形式(portable pixmap)の画像用)
The Ray Tracer Challenge: A Test-Driven Guide to Your First 3D Renderer (Jamis Buck(著)、Pragmatic Bookshelf)、Chapter 14(Groups)のFinding the Normal on a Child Object、Test #7(Convert a Point from World Space to Object Space)を取り組んでみる。
コード
shapes_test.py
#!/usr/bin/env python3 import math from unittest import TestCase, main from shapes import Shape from transformations import translation from matrices import IDENTITY_MATRIX, Matrix from materials import Material from rays import Ray from tuples import Point, Vector from transformations import scaling, rotation_y from groups import Group from spheres import Sphere class ShapeTest(TestCase): def setUp(self): self.shape = Shape(material=Material()) def tearDown(self): pass def test_default_transformation(self): self.assertEqual(self.shape.transform, IDENTITY_MATRIX) def test_material(self): self.assertEqual(self.shape.material.ambient, 0.1) self.assertEqual(self.shape.material, Material()) def test_transform(self): self.assertEqual(Shape().transform, IDENTITY_MATRIX) s = Shape() t = translation(2, 3, 4) s.transform = t self.assertEqual(s.transform, t) def test_parent_attribute(self): s = Shape() self.assertIsNone(s.parent) def test_converting_point_from_world_to_object_space(self): group1 = Group(transform=rotation_y(math.pi / 2)) group2 = Group(transform=scaling(2, 2, 2)) group1.add_child(group2) sphere = Sphere(translation(5, 0, 0)) group2.add_child(sphere) point = sphere.world_to_obj(Point(-2, 0, -10)) self.assertEqual(point, Point(0, 0, -1)) if __name__ == '__main__': main()
shapes.py
from matrices import Matrix, IDENTITY_MATRIX from materials import Material class Shape: def __init__(self, transform=None, material=None, parent=None): if transform is None: self.transform = IDENTITY_MATRIX else: self.transform = transform if material is None: self.material = Material() else: self.material = material self.parent = None def __repr__(self): return f'{self.__class__.__name__}({self.transform},{self.material})' def intersect(self, ray): raise NotImplementedError() def normal_at(self, point): raise NotImplementedError() def world_to_obj(self, point): if self.parent is not None: point = self.parent.world_to_obj(point) return self.transform.inverse() * point
入出力結果(Bash、cmd.exe(コマンドプロンプト)、Terminal、Jupyter(IPython))
C:\Users\...>py shapes_test.py ..... ---------------------------------------------------------------------- Ran 5 tests in 0.002s OK C:\Users\...>
0 コメント:
コメントを投稿