## 2019年5月9日木曜日

### Python - Matrix Transformations - translation, scaling, rotation(x, y, z axises), shearing, chaining, clock

The Ray Tracer Challenge: A Test-Driven Guide to Your First 3D Renderer (Jamis Buck(著)、Pragmatic Bookshelf)、Chapter 4(Matrix Transformations)のPut It Together(54)を取り組んでみる。

コード

Python 3

transformations_test.py

```#!//usr/bin/env python3
from unittest import TestCase, main
from tuples import Point, Vector
from transformations import translation, scaling
from transformations import rotation_x, rotation_y, rotation_z
from transformations import shearing
import math

class TransformationsTest(TestCase):
def setUp(self):
pass

def tearDown(self):
pass

def test_translation(self):
transform = translation(5, -3, 2)
inv = transform.inverse()
p = Point(-3, 4, 5)
self.assertEqual(transform * p, Point(2, 1, 7))

def test_translation_vector(self):
transform = translation(5, -3, 2)
v = Vector(-3, 4, 5)
self.assertEqual(transform * v, v)

def test_scaling_point(self):
transform = scaling(2, 3, 4)
p = Point(-4, 6, 8)
self.assertEqual(transform * p, Point(-8, 18, 32))

def test_scaling_vector(self):
transform = scaling(2, 3, 4)
v = Vector(-4, 6, 8)
self.assertEqual(transform * v, Vector(-8, 18, 32))

def test_scaling_vector_inv(self):
transform = scaling(2, 3, 4)
v = inv = transform.inverse()
v = Vector(-4, 6, 8)
self.assertEqual(inv * v, Vector(-2, 2, 2))

def test_scaling_negative(self):
transform = scaling(-1, 1, 1)
p = Point(2, 3, 4)
self.assertEqual(transform * p, Point(-2, 3, 4))

def test_rotation_x(self):
p = Point(0, 1, 0)
half_quarter = rotation_x(math.pi / 4)
full_quarter = rotation_x(math.pi / 2)
self.assertEqual(half_quarter * p,
Point(0, math.sqrt(2) / 2, math.sqrt(2) / 2))
self.assertEqual(full_quarter * p,
Point(0, 0, 1))

def test_rotation_x_opposite(self):
p = Point(0, 1, 0)
half_quarter = rotation_x(math.pi / 4)
inv = half_quarter.inverse()
self.assertEqual(inv * p,
Point(0, math.sqrt(2) / 2, -math.sqrt(2) / 2))

def test_rotation_y(self):
p = Point(0, 0, 1)
half_quarter = rotation_y(math.pi / 4)
full_quarter = rotation_y(math.pi / 2)
self.assertEqual(half_quarter * p,
Point(math.sqrt(2) / 2, 0, math.sqrt(2) / 2))
self.assertEqual(full_quarter * p,
Point(1, 0, 0))

def test_rotation_z(self):
p = Point(0, 1, 0)
half_quarter = rotation_z(math.pi / 4)
full_quarter = rotation_z(math.pi / 2)
self.assertEqual(half_quarter * p,
Point(-math.sqrt(2) / 2, math.sqrt(2) / 2, 0))
self.assertEqual(full_quarter * p,
Point(-1, 0, 0))

def test_shearing_x_to_y(self):
transform = shearing(1, 0, 0, 0, 0, 0)
p = Point(2, 3, 4)
self.assertEqual(transform * p, Point(5, 3, 4))

def test_shearing_x_z(self):
transform = shearing(0, 1, 0, 0, 0, 0)
p = Point(2, 3, 4)
self.assertEqual(transform * p, Point(6, 3, 4))

def test_shearing_y_x(self):
transform = shearing(0, 0, 1, 0, 0, 0)
p = Point(2, 3, 4)
self.assertEqual(transform * p, Point(2, 5, 4))

def test_shearing_y_z(self):
transform = shearing(0, 0, 0, 1, 0, 0)
p = Point(2, 3, 4)
self.assertEqual(transform * p, Point(2, 7, 4))

def test_shearing_z_x(self):
transform = shearing(0, 0, 0, 0, 1, 0)
p = Point(2, 3, 4)
self.assertEqual(transform * p, Point(2, 3, 6))

def test_shearing_z_y(self):
transform = shearing(0, 0, 0, 0, 0, 1)
p = Point(2, 3, 4)
self.assertEqual(transform * p, Point(2, 3, 7))

def test_transformation_sequence(self):
p = Point(1, 0, 1)
A = rotation_x(math.pi / 2)
B = scaling(5, 5, 5)
C = translation(10, 5, 7)
p2 = A * p
p3 = B * p2
p4 = C * p3
for a, b in zip([p2, p3, p4], [Point(1, -1, 0),
Point(5, -5, 0),
Point(15, 0, 7)]):
self.assertEqual(a, b)

def test_transformation_chain(self):
p = Point(1, 0, 1)
A = rotation_x(math.pi / 2)
B = scaling(5, 5, 5)
C = translation(10, 5, 7)
T = C * B * A
self.assertEqual(T * p, Point(15, 0, 7))

if __name__ == '__main__':
main()
```

transformations.py

```from matrices import Matrix
import math

def translation(x: float, y: float, z: float) -> Matrix:
return Matrix([[1, 0, 0, x],
[0, 1, 0, y],
[0, 0, 1, z],
[0, 0, 0, 1]])

def scaling(x: float, y: float, z: float) -> Matrix:
return Matrix([[x, 0, 0, 0],
[0, y, 0, 0],
[0, 0, z, 0],
[0, 0, 0, 1]])

def rotation_x(r: float) -> Matrix:
return Matrix(((1, 0, 0, 0),
(0, math.cos(r), -math.sin(r), 0),
(0, math.sin(r), math.cos(r), 0),
(0, 0, 0, 1)))

def rotation_y(r: float) -> Matrix:
return Matrix(((math.cos(r), 0, math.sin(r), 0),
(0, 1, 0, 0),
(-math.sin(r), 0, math.cos(r), 0),
(0, 0, 0, 1)))

def rotation_z(r: float) -> Matrix:
return Matrix(((math.cos(r), -math.sin(r), 0, 0),
(math.sin(r), math.cos(r), 0, 0),
(0, 0, 1, 0),
(0, 0, 0, 1)))

def shearing(xy: float, xz: float,
yx: float, yz: float,
zx: float, zy: float) -> Matrix:
return Matrix(((1, xy, xz, 0),
(yx, 1, yz, 0),
(zx, zy, 1, 0),
(0, 0, 0, 1)))
```

clock.py

```#!/usr/bin/env python3
from tuples import *
from transformations import *
from canvas import Canvas
import random

width = 500
height = 500

def p(msg, ponts):
print(msg)
for p in points:
print(p)

if __name__ == '__main__':
r = rotation_y(math.pi / 6)
twelve = Point(0, 0, 1)
points = [twelve]
for i in range(11):
points.append(r * points[i])
p('回転', points)

canvas = Canvas(width, height)
radius = width * 3 / 8
points = [s * point for point in points]
p('拡大(縮小)', points)

t = translation(width / 2, 0, height / 2)
points = [t * point for point in points]
p('移動', points)

for point in points:
color = Color(*[random.random() for _ in range(3)])
x, z = point.x, point.z
xzs = [(x + i, z + j) for i in range(-5, 6) for j in range(-5, 6)]
for x0, z0 in xzs:
canvas.write_pixel(int(x0), int(z0), color)

ppm = canvas.to_ppm()
with open('clock.ppm', 'w') as f:
print(ppm, file=f)
```

```C:\Users\...>py transformations_test.py
..................
----------------------------------------------------------------------
Ran 18 tests in 0.003s

OK

C:\Users\...>py transformations_test.py -v
test_rotation_x (__main__.TransformationsTest) ... ok
test_rotation_x_opposite (__main__.TransformationsTest) ... ok
test_rotation_y (__main__.TransformationsTest) ... ok
test_rotation_z (__main__.TransformationsTest) ... ok
test_scaling_negative (__main__.TransformationsTest) ... ok
test_scaling_point (__main__.TransformationsTest) ... ok
test_scaling_vector (__main__.TransformationsTest) ... ok
test_scaling_vector_inv (__main__.TransformationsTest) ... ok
test_shearing_x_to_y (__main__.TransformationsTest) ... ok
test_shearing_x_z (__main__.TransformationsTest) ... ok
test_shearing_y_x (__main__.TransformationsTest) ... ok
test_shearing_y_z (__main__.TransformationsTest) ... ok
test_shearing_z_x (__main__.TransformationsTest) ... ok
test_shearing_z_y (__main__.TransformationsTest) ... ok
test_transformation_chain (__main__.TransformationsTest) ... ok
test_transformation_sequence (__main__.TransformationsTest) ... ok
test_translation (__main__.TransformationsTest) ... ok
test_translation_vector (__main__.TransformationsTest) ... ok

----------------------------------------------------------------------
Ran 18 tests in 0.003s

OK

C:\Users\...>py clock.py

Point(0,0,1,1)
Point(0.49999999999999994,0,0.8660254037844387,1)
Point(0.8660254037844386,0.0,0.5000000000000002,1.0)
Point(1.0,0.0,2.7755575615628914e-16,1.0)
Point(0.8660254037844388,0.0,-0.4999999999999997,1.0)
Point(0.5000000000000004,0.0,-0.8660254037844385,1.0)
Point(5.551115123125783e-16,0.0,-1.0,1.0)
Point(-0.49999999999999944,0.0,-0.8660254037844389,1.0)
Point(-0.8660254037844383,0.0,-0.5000000000000007,1.0)
Point(-1.0,0.0,-8.326672684688674e-16,1.0)
Point(-0.8660254037844392,0.0,0.4999999999999992,1.0)
Point(-0.5000000000000009,0.0,0.8660254037844382,1.0)

Point(0.0,0,187.5,1)
Point(93.74999999999999,0.0,162.37976320958225,1.0)
Point(162.37976320958225,0.0,93.75000000000004,1.0)
Point(187.5,0.0,5.204170427930421e-14,1.0)
Point(162.37976320958228,0.0,-93.74999999999994,1.0)
Point(93.75000000000009,0.0,-162.37976320958222,1.0)
Point(1.0408340855860843e-13,0.0,-187.5,1.0)
Point(-93.7499999999999,0.0,-162.3797632095823,1.0)
Point(-162.37976320958217,0.0,-93.75000000000013,1.0)
Point(-187.5,0.0,-1.5612511283791264e-13,1.0)
Point(-162.37976320958234,0.0,93.74999999999986,1.0)
Point(-93.75000000000017,0.0,162.37976320958217,1.0)

Point(250.0,0.0,437.5,1.0)
Point(343.75,0.0,412.3797632095823,1.0)
Point(412.3797632095823,0.0,343.75000000000006,1.0)
Point(437.5,0.0,250.00000000000006,1.0)
Point(412.3797632095823,0.0,156.25000000000006,1.0)
Point(343.7500000000001,0.0,87.62023679041778,1.0)
Point(250.0000000000001,0.0,62.5,1.0)
Point(156.2500000000001,0.0,87.62023679041769,1.0)
Point(87.62023679041783,0.0,156.2499999999999,1.0)
Point(62.5,0.0,249.99999999999986,1.0)
Point(87.62023679041766,0.0,343.7499999999999,1.0)
Point(156.24999999999983,0.0,412.37976320958217,1.0)

C:\Users\...>
```

#### 2 コメント:

دريم هاوسさんのコメント...

شركة نقل اثاث بالرياض http://sites.social/haytham6 نقل عفش بتعتبر أعمال نقل العفش من أهم الأعمال على الاطلاق ؛فالكثير من الأفراد يحتاجون الى القيام بأعمال النقل المميزة لحمايه كافه أجزاء الاثاث من التعرض للتكسير أو الخدوش وغيرها من الأمور الأخرى ؛لذلك نحن شركة نقل عفش بالرياض التى تعتمد على أفضل العاملين المتخصصين وأفضل الأساليب الحديثة للقيام بنقل جميع أجزاء الاثاث سواء غرف النوم والسفر والصالونات وغيرها من الأدوات المكتبية والأدوات الخاصه بالأمور الفندقية وغيرها من أجزاء الاثاث التى تتعلق بالشقق والقصور والفلل وجميع الأمور الأخرى .

تتخصص الشركة فى أعمال نقل الأجهزة الكهربية وغيرها من الأمور الأخرى التى تتعلق بالمطابخ وغيرها من الأمور الأخرى ؛فقط نحن شركة نقل عفش بالرياض التى تعتمد على أفضل الأساليب الحديثة والطرق المميزة للقيام بأعمال نقل العفش .… اقرأ المزيد

المصدر: شركة نقل اثاث بالرياض

دريم هاوسさんのコメント...

من الخدمات التي لا تقل أهمية عن كافة الخدمات التي تقدمها شركة تنظيف بالبخار بالرياض http://pages.today/theme3 هي تنظيف موكيت ,ولأننا جميعاً نعلم أن الموكيت سهل التلف للغاية إذا تم غسله أو تنظيفه بطريقة غير صحيحة فتقوم شركتنا بتوفير هذه الخدمة على قدر عالي من الجودة باستخدام أجهزة تنظيف بالبخار على أعلى مستوى حتى يعود الموكيت نظيفاً وجديداً بدون أي تلف أو خسائر. .… اقرأ المزيد

المصدر: شركة تنظيف بالبخار بالرياض

افضل شركة نقل اثاث برابغ http://visit.news/theme38 طرق نقل العفش برابغ ؟
تتمكن الشركة من القيام بأعمال نقل العفش برابغ اعتمادا على مجموعه من أفضل الطرق والأساليب ؛فقط يمكن الحديث عن أبرز الطرق :

1-الاعتماد على الأوناش الحديثة
تعتبر الأوناش الحديثة سواء الكهربية والهيدرليكية من أهم الأساليب المعتمد عليها فى أعمال نقل العفش ؛تلك الأوناش تتمكن من الوصول الى الأماكن الاكثر ارتفاعا بسهوله كبيرة ويتم الوصول الى النوافذ والقيام بأعمال نقل صحيحة ومميزة ؛فالأوناش توفر الوقت والجهد للقيام بأعمال النقل دون تعرض الاثاث لأى خدوش أو تكسير .

يتم التوجه الى الأوناش بسبب ضيق حجم المنزل وعدم القدرة على نقل الاثاث بالطرق اليدوية ؛وأيضا كبر حجم الاثاث من الطرق التى تصعب من القيام بأعمال النقل بالطريقة الصحيحة ؛لذلك تعتبر الأوناش أفضل الوسائل المعتمد عليها ؛وتأخذ شركة نقل اثاث بالرياض فى اعتبارها القيام بأعمال صيانة سريعه ومميزة منعا للتعرض لأى تلفيات أو مشكلات أو مخاطر لأى عاملين يعتمدون على الأوناش فى القيام بالنقل.

2-الاعتماد على السيارات الحديثة
تعتمد شركة نقل عفش برابغ على مجموعه من السيارات الحديثة ذات الأحجام المختلفه من أجل القيام بأعمال نقل العفش بطريقه صحيحة ؛تلك السيارات تم اعدادها خصيصا من أجل القيام بنقل العفش من مكان الى مكان أخر ؛تلك السيارات لها مجموعه من الأغطية التى تحمى الأثاث بمختلف أشكاله من التعرض للأتربه أو الشوائب أو العوالق الخطيرة ؛كما أن الاثاث سرعان ما يتعرض للأمطار الغزيرة خلال فصل الشتاء .

تلك السيارات تتمكن من القيام بأعمال نقل العفش من مكان الى مكان أخر ؛كما تتمكن الشركة من الانتقال الى كافه الأماكن واختيار الطرق الممهدة .

3-الاعتماد على الناقلات
تعتمد الشركة على مجموعه من أفضل الناقلات الحديثة التى تتمكن من تحمل جميع الأوزان ؛والحفاظ على سلامة المنقولات من مكان الى مكان أخر دون تعرض الاثاث لأى خدوش أو عوالق خطيرة .

خطوات القيام بأعمال نقل العفش برابغ
1-أعمال تعبئة العفش
تعتمد الشركة على مجموعه من أفضل أدوات التعبئة والعلب الكرتونية والحاويات المختلف مساحاتها من أجل القيام بأعمال تعبئة صحيحة تساعد على حمايه الاثاث أو العفش من التعرض للعديد من الكسور والخدوش بأشكالها المختلفه .

2-أعمال فك وتركيب الاثاث
هذه الطريقه من أحدث الأساليب المعتمد عليها من أجل نقل الاثاث بطريقه صحيحة منعا للتعرض لأى خدوش أو تلفيات ؛لذلك يتم تفكيك قطع الاثاث الى قطع صغيرة ويتم ترقيمه بأرقام محددة مما يساعد الأمر على سهوله نقله من مكان الى مكان أخر وتركيبه مرة أخرى بعد التفكيك ؛لذلك يتم ترتيب العفش بطريقه صحيحة داخل السيارات من أجل سهوله نزوله مرة أخرى .

3-أعمال تغليف الاثاث
تتمكن شركة نقل اثاث برابغ من القيام بأعمال تغليف الاثاث اعتمادا على مجموعه من الأدوات المميزة سواء البطاطين السميكة التى تساعد على حمايه الاثاث من التعرض لأى خدوش أو قطع ؛كما يتم الاعتماد على فريق عمل مميز من أفضل العاملين المتخصصين اللذين لديهم خبرات واسعه فى اختيار أفضل أدوات التغليف من أجل حمايه الاثاث من التعرض للمزيد من الخدوش أو التلفيات أو القطع .

4-أعمال تخزين العفش
تعتمد شركة نقل عفش برابغ على مجموعه من أفضل أماكن التخزين سواء مجموعه من المخازن أو المستودعات الكبرى التى تمكن الأفراد من القيام بأعمال التخزين لكافه أشكال الاثاث مهما بلغت أوزانها أو أحجامها .… اقرأ المزيد

المصدر: شركة نقل اثاث برابغ