8000 Implement get_max_elevation_angle · chr-wei/tinyrenderer_python@dcbbd4c · GitHub
[go: up one dir, main page]

Skip to content

Commit dcbbd4c

Browse files
author
Christian Weihsbach
committed
Implement get_max_elevation_angle
1 parent 030e3bd commit dcbbd4c

File tree

2 files changed

+37
-7
lines changed

2 files changed

+37
-7
lines changed

geom.py

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,11 @@
66
from collections.abc import Iterable
77

88
from itertools import chain
9+
from functools import reduce
910
import operator
1011

11-
import math
12+
from math import sqrt
13+
1214
import numpy as np
1315

1416
class Vector4DType(Enum):
@@ -185,6 +187,10 @@ def tr(self): # pylint: disable=invalid-name
185187
elems = self._asdict().values()
186188
return type(self)(elems, shape = (cols, rows))
187189

190+
def abs(self):
191+
"""Returns length of vector."""
192+
return vect_norm(self.get_field_values())
193+
188194
class Point2D(MixinVector, metaclass=NamedTupleMetaEx):
189195
"""Two-dimensional point with x and y ordinate."""
190196
_shape = (2,1)
@@ -203,6 +209,12 @@ class Barycentric(MixinVector, metaclass=NamedTupleMetaEx):
203209
one_u_v: float
204210
u: float
205211
v: float
212+
213+
class Vector2D(MixinVector, metaclass=NamedTupleMetaEx):
214+
"""Two-dimensional point with x and y ordinate."""
215+
_shape = (2,1)
216+
x: float
217+
y: float
206218
class Vector3D(MixinVector, metaclass=NamedTupleMetaEx):
207219
"""Three-dimensional vector with x, y, z component."""
208220
_shape = (3,1)
@@ -227,10 +239,6 @@ def expand_4D(self, vtype): # pylint: disable=invalid-name
227239

228240
return ValueError
229241

230-
def abs(self):
231-
"""Returns length of vector."""
232-
return math.sqrt(self.x**2 + self.y**2 + self.z**2)
233-
234242
def normalize(self):
235243
"""Normalizes vector to length = 1.0."""
236244
abl = self.abs()
@@ -464,6 +472,11 @@ def compfloor(mat_0: list, shape_0: tuple, divisor: float):
464472
# Return coefficients and shape tuple
465473
return [int(e // divisor) for e in mat_0], shape_0
466474

475+
def vect_norm(all_elems: list):
476+
"""Return norm of n-dim vector."""
477+
squared = [elem**2 for elem in all_elems]
478+
return sqrt(reduce(operator.add, squared))
479+
467480
def matadd(mat_0: list, shape_0: tuple, mat_1: list, shape_1: tuple):
468481
"""Performing componentwise addition."""
469482
(rows_0, cols_0) = shape_0

tiny_shaders.py

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import math
55
import our_gl as gl
66
from geom import Matrix4D, Matrix3D, MatrixUV, \
7-
Vector4DType, Vector3D, Barycentric, PointUV, \
7+
Vector4DType, Vector3D, Vector2D, Point2D, Barycentric, PointUV, \
88
transform_3D4D3D, transform_vertex_to_screen, \
99
cross_product, comp_min
1010

@@ -470,4 +470,21 @@ def fragment(self, bary: Barycentric):
470470
color = comp_min(Vector3D(255, 255, 255), color) // 1
471471

472472
# Do not discard pixel and return color
473-
return (False, color)
473+
return (False, color)
474+
475+
def get_max_elevation_angle(pt_amb: Point2D, z_buffer: list, sweep_dir: Vector2D):
476+
"""Returns max elevation angle ray-casted from starting point pt_amb."""
477+
(im_w, im_h) = len(z_buffer)
478+
fact = 1 / max(pt_amb)
479+
vect_amb = Vector3D(pt_amb.x, pt_amb.x, z_buffer[pt_amb.x][pt_amb.y])
480+
sweep_proj = vect_amb
481+
max_angle = 0
482+
483+
while 0 <= sweep_proj.x < im_w and 0 <= sweep_proj.y < im_h:
484+
sweep_proj += fact * Vector3D(sweep_dir.x, sweep_dir.y, 0)
485+
z_height = z_buffer[int(sweep_proj.x // 1)][int(sweep_proj.y // 1)]
486+
sweep = Vector3D(sweep_proj.x, sweep_proj.y, z_height)
487+
alpha = math.acos((sweep - vect_amb).normalize() * sweep_proj.normalize())
488+
max_angle = max(alpha, max_angle)
489+
490+
return max_angle

0 commit comments

Comments
 (0)
0