-
Notifications
You must be signed in to change notification settings - Fork 1
/
Models3D.py
132 lines (123 loc) · 4.47 KB
/
Models3D.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#!/usr/bin/python
# -*- coding: utf-8 -*-
import math
# own modules
from Mesh3D import Mesh3D as Mesh3D
from Face3D import Face3D as Face3D
from Matrix3D import Matrix3D as Matrix3D
from Vector3D import Vector3D as Vector3D
def get_rectangle_points():
"""basic rectangle vertices"""
points = (
Vector3D(-1, 1, 0, 1),
Vector3D( 1, 1, 0, 1),
Vector3D( 1, -1, 0, 1),
Vector3D(-1, -1, 0, 1),
Vector3D(-1, 1, 0, 1),
)
return points
def get_triangle_points():
"""basic triangle vertices"""
points = (
Vector3D(-1, 0, 0, 1),
Vector3D( 0, 1, 0, 1),
Vector3D( 1, 0, 0, 1),
Vector3D(-1, 0, 0, 1),
)
return points
def get_pyramid_mesh():
faces = []
# front
tri = Face3D(get_triangle_points())
#t = Matrix3D.get_shift_matrix(0, 0, 1).dot(Matrix3D.get_rot_x_matrix(-math.pi/4))
face = tri.transform(Matrix3D.get_rot_x_matrix(-math.pi/4))
face = face.transform(Matrix3D.get_shift_matrix(0, 0, 1))
faces.append(face)
# back
face = tri.transform(Matrix3D.get_rot_x_matrix(math.pi/4))
face = face.transform(Matrix3D.get_shift_matrix(0, 0, -1))
faces.append(face)
# left
face = tri.transform(Matrix3D.get_rot_x_matrix(-math.pi/4))
face = face.transform(Matrix3D.get_rot_y_matrix(-math.pi/2))
face = face.transform(Matrix3D.get_shift_matrix(1, 0, 0))
faces.append(face)
# right
face = tri.transform(Matrix3D.get_rot_x_matrix(-math.pi/4))
face = face.transform(Matrix3D.get_rot_y_matrix(math.pi/2))
face = face.transform(Matrix3D.get_shift_matrix(-1, 0, 0))
faces.append(face)
return Mesh3D(faces)
def get_cube_mesh():
# a cube Mesh consist of six Faces
# left
faces = []
rec = Face3D(get_rectangle_points())
t = Matrix3D.get_shift_matrix(-1, 0, 0).dot(Matrix3D.get_rot_y_matrix(math.pi/2))
faces.append(rec.transform(t))
# right
t = Matrix3D.get_shift_matrix(1, 0, 0).dot(Matrix3D.get_rot_y_matrix(math.pi/2))
faces.append(rec.transform(t))
# bottom
t = Matrix3D.get_shift_matrix(0, -1, 0).dot(Matrix3D.get_rot_x_matrix(math.pi/2))
faces.append(rec.transform(t))
# top
t = Matrix3D.get_shift_matrix(0, 1, 0).dot(Matrix3D.get_rot_x_matrix(math.pi/2))
faces.append(rec.transform(t))
# front
t = Matrix3D.get_shift_matrix(0, 0, -1)
faces.append(rec.transform(t))
# back
t = Matrix3D.get_shift_matrix(0, 0, 1)
faces.append(rec.transform(t))
return Mesh3D(faces)
def get_scale_rot_matrix(scale_tuple, aspect_tuple, shift_tuple):
"""
create a affine transformation matrix
scale is of type tuple (200, 200, 1)
shift is of type tuple (0, 0, -10)
degreees of type tuple for everx axis steps in degrees
aspect of type tuple to correct aspect ratios
steps is of type int
rotates around x/y/z in 1 degree steps and precalculates
360 different matrices
"""
aspect_ratio = aspect_tuple[0] / aspect_tuple[1]
scale_matrix = get_scale_matrix(*scale_tuple)
shift_matrix = get_shift_matrix(*shift_tuple)
alt_basis = (
(1, 0, 0, 0),
(0, aspect_ratio, 0, 0),
(0, 0, 1, 0),
(0, 0, 0, 1)
)
# TODO : majke inversion function
alt_basis_inv = np.linalg.inv(alt_basis)
# combine scale and change of basis to one transformation
# static matrix
# TODO : make dot function for matrices
static_transformation = shift_matrix.dot(alt_basis_inv.dot(scale_matrix))
return static_transformation
def get_rot_matrix(static_transformation, degrees, steps):
"""
static_transformation of type Matrix3d, will be applied to every step
degrees of type tuple, for every axis one entry in degrees
steps of type int, how many steps to precalculate
"""
deg2rad = math.pi / 180
transformations = []
for step in range(steps):
factor = step * deg2rad
angle_x = degrees[0] * factor
angle_y = degrees[1] * factor
angle_z = degrees[2] * factor
# this part of tranformation is calculate for every step
transformation = get_rot_z_matrix(angle_z).dot(
get_rot_x_matrix(angle_x).dot(
get_rot_y_matrix(angle_y)))
# combine with static part of transformation,
# which does scaling, shifting and aspect ration correction
# to get affine transformation matrix
transformation = static_transformation.dot(transformation)
transformations.append(transformation)
return transformations