Skip to content

Commit e30fd6e

Browse files
authored
Merge pull request #52 from Kwasniok/fix/unify-swirl-manifolds
unify swirl manifolds
2 parents 39bbe78 + d78375d commit e30fd6e

File tree

102 files changed

+7510
-7627
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

102 files changed

+7510
-7627
lines changed

mypy.ini

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ disallow_untyped_decorators = True
1212

1313
# dependencies
1414
# numpy
15+
# (type hints)
1516
plugins = numpy.typing.mypy_plugin
16-
# Pillow (no support of type hints yet)
17+
# Pillow
18+
[mypy-PIL.*]
19+
# (no support of type hints yet)
1720
ignore_missing_imports = True

src/demo_0.py

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,20 @@
1-
"""This demo script renders a test scene in euclidean geometry."""
1+
"""This demo script renders a test scene in standard geometry."""
22

33
import os
44

55
from enum import IntEnum
66

77
from nerte.values.coordinates import Coordinates3D
8-
from nerte.values.domain import Domain1D
98
from nerte.values.linalg import AbstractVector
10-
from nerte.values.manifolds.cartesian import Plane
9+
from nerte.values.interval import Interval
10+
from nerte.values.domains import CartesianProduct2D
11+
from nerte.values.submanifolds import Plane
1112
from nerte.values.face import Face
1213
from nerte.world.object import Object
1314
from nerte.world.camera import Camera
1415
from nerte.world.scene import Scene
15-
from nerte.geometry.geometry import Geometry
16-
from nerte.geometry.carthesian_geometry import CarthesianGeometry
16+
from nerte.geometry import Geometry
17+
from nerte.geometry import StandardGeometry
1718
from nerte.render.projection import ProjectionMode
1819
from nerte.render.image_color_renderer import ImageColorRenderer
1920
from nerte.util.random_color_generator import RandomColorGenerator
@@ -49,15 +50,15 @@ def make_camera(canvas_dimension: int) -> Camera:
4950
"""Creates a camera with preset values."""
5051

5152
location = Coordinates3D((0.0, 0.0, -2.0))
52-
manifold_param_domain = Domain1D(-1.0, 1.0)
53+
interval = Interval(-1.0, 1.0)
54+
domain = CartesianProduct2D(interval, interval)
5355
manifold = Plane(
5456
AbstractVector((1.0, 0.0, 0.0)),
5557
AbstractVector((0.0, 1.0, 0.0)),
56-
x0_domain=manifold_param_domain,
57-
x1_domain=manifold_param_domain,
5858
)
5959
camera = Camera(
6060
location=location,
61+
detector_domain=domain,
6162
detector_manifold=manifold,
6263
canvas_dimensions=(canvas_dimension, canvas_dimension),
6364
)
@@ -174,7 +175,7 @@ def main() -> None:
174175
# NOTE: Increase the canvas dimension to improve the image quality.
175176
# This will also increase rendering time!
176177
scene = make_scene(canvas_dimension=100)
177-
geo = CarthesianGeometry()
178+
geo = StandardGeometry()
178179

179180
render(
180181
scene=scene,

src/demo_1.py

Lines changed: 197 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
"""This demo script renders a test scene in basic Runge-Kutta geometry."""
2+
3+
import os
4+
import math
5+
6+
from enum import IntEnum
7+
8+
from nerte.values.coordinates import Coordinates3D
9+
from nerte.values.linalg import AbstractVector
10+
from nerte.values.interval import Interval
11+
from nerte.values.domains import CartesianProduct2D
12+
from nerte.values.submanifolds import Plane
13+
from nerte.values.manifolds.euclidean.cartesian import Cartesian
14+
from nerte.values.face import Face
15+
from nerte.world.object import Object
16+
from nerte.world.camera import Camera
17+
from nerte.world.scene import Scene
18+
from nerte.geometry import Geometry
19+
from nerte.geometry.runge_kutta_geometry import RungeKuttaGeometry
20+
from nerte.render.projection import ProjectionMode
21+
from nerte.render.image_color_renderer import ImageColorRenderer
22+
from nerte.util.random_color_generator import RandomColorGenerator
23+
24+
25+
class Axis(IntEnum):
26+
"""Representation of an axis."""
27+
28+
X = 0
29+
Y = 1
30+
Z = 2
31+
32+
33+
class Side(IntEnum):
34+
"""Representation of one half of a square (trinagle)."""
35+
36+
THIS = -1
37+
THAT = +1
38+
39+
40+
class Distance(IntEnum):
41+
"""Representation of the negative or positive domain of an axis."""
42+
43+
NEAR = -1
44+
FAR = +1
45+
46+
47+
# pseudo-random color generator
48+
COLOR = RandomColorGenerator()
49+
50+
51+
def make_camera(canvas_dimension: int) -> Camera:
52+
"""Creates a camera with preset values."""
53+
54+
location = Coordinates3D((0.0, 0.0, -2.0))
55+
interval = Interval(-1.0, 1.0)
56+
domain = CartesianProduct2D(interval, interval)
57+
manifold = Plane(
58+
AbstractVector((1.0, 0.0, 0.0)),
59+
AbstractVector((0.0, 1.0, 0.0)),
60+
)
61+
camera = Camera(
62+
location=location,
63+
detector_domain=domain,
64+
detector_manifold=manifold,
65+
canvas_dimensions=(canvas_dimension, canvas_dimension),
66+
)
67+
return camera
68+
69+
70+
def make_triangle_object(fix: Axis, distance: Distance, side: Side) -> Object:
71+
"""
72+
Creates a section of a cube (triangle) where each section gets assigned
73+
a random color.
74+
"""
75+
76+
# intermediate matrix for coordinate coefficients
77+
coords = [[0.0 for _ in range(3)] for _ in range(3)]
78+
# create the coefficients based on the parameters
79+
for coord in coords:
80+
coord[fix.value] = 1.0 * distance.value
81+
axis_u, axis_v = (axis for axis in (0, 1, 2) if axis != fix.value)
82+
coords[0][axis_u] = -1.0
83+
coords[0][axis_v] = -1.0
84+
coords[1][axis_u] = -1.0 * side.value
85+
coords[1][axis_v] = +1.0 * side.value
86+
coords[2][axis_u] = +1.0
87+
coords[2][axis_v] = +1.0
88+
# represent the coefficients as proper coordinates
89+
point0 = Coordinates3D(coords[0]) # type: ignore[arg-type]
90+
point1 = Coordinates3D(coords[1]) # type: ignore[arg-type]
91+
point2 = Coordinates3D(coords[2]) # type: ignore[arg-type]
92+
# create the triangle as an object
93+
tri = Face(point0, point1, point2)
94+
obj = Object(color=next(COLOR)) # pseudo-random color
95+
obj.add_face(tri)
96+
return obj
97+
98+
99+
def make_scene(canvas_dimension: int) -> Scene:
100+
"""
101+
Creates a scene with a camera pointing inside a cube with no front face.
102+
"""
103+
104+
camera = make_camera(canvas_dimension)
105+
scene = Scene(camera=camera)
106+
107+
# add all faces of the hollow cube as separate object to enable
108+
# individual colors for each triange
109+
# object 1
110+
obj = make_triangle_object(Axis.Y, Distance.NEAR, Side.THAT)
111+
scene.add_object(obj)
112+
# object 2
113+
obj = make_triangle_object(Axis.Y, Distance.NEAR, Side.THIS)
114+
scene.add_object(obj)
115+
# object 3
116+
obj = make_triangle_object(Axis.Z, Distance.FAR, Side.THAT)
117+
scene.add_object(obj)
118+
# object 4
119+
obj = make_triangle_object(Axis.Z, Distance.FAR, Side.THIS)
120+
scene.add_object(obj)
121+
# object 5
122+
obj = make_triangle_object(Axis.X, Distance.NEAR, Side.THAT)
123+
scene.add_object(obj)
124+
# object 6
125+
obj = make_triangle_object(Axis.X, Distance.NEAR, Side.THIS)
126+
scene.add_object(obj)
127+
# object 7
128+
obj = make_triangle_object(Axis.X, Distance.FAR, Side.THAT)
129+
scene.add_object(obj)
130+
# object 8
131+
obj = make_triangle_object(Axis.X, Distance.FAR, Side.THIS)
132+
scene.add_object(obj)
133+
# object 9
134+
obj = make_triangle_object(Axis.Y, Distance.FAR, Side.THAT)
135+
scene.add_object(obj)
136+
# object 10
137+
obj = make_triangle_object(Axis.Y, Distance.FAR, Side.THIS)
138+
scene.add_object(obj)
139+
# NOTE: There are no triangles for Axis.Z and Distance.NEAR since they
140+
# would cover up the inside of the cube.
141+
142+
return scene
143+
144+
145+
def render(
146+
scene: Scene,
147+
geometry: Geometry,
148+
output_path: str,
149+
file_prefix: str,
150+
show: bool,
151+
) -> None:
152+
"""
153+
Renders a preset scene with non-euclidean geometry in orthographic and
154+
perspective projection.
155+
"""
156+
157+
for projection_mode in (
158+
ProjectionMode.ORTHOGRAPHIC,
159+
ProjectionMode.PERSPECTIVE,
160+
):
161+
print(f"rendering {projection_mode.name} projection ...")
162+
image_renderer = ImageColorRenderer(projection_mode=projection_mode)
163+
image_renderer.render(scene=scene, geometry=geometry)
164+
os.makedirs("../images", exist_ok=True)
165+
image = image_renderer.last_image()
166+
if image is not None:
167+
image.save(
168+
f"{output_path}/{file_prefix}_{projection_mode.name}.png"
169+
)
170+
if show:
171+
image.show()
172+
173+
174+
def main() -> None:
175+
"""Creates and renders the demo scene."""
176+
177+
# NOTE: Increase the canvas dimension to improve the image quality.
178+
# This will also increase rendering time!
179+
scene = make_scene(canvas_dimension=100)
180+
geo = RungeKuttaGeometry(
181+
manifold=Cartesian(),
182+
max_ray_depth=math.inf,
183+
step_size=1.0,
184+
max_steps=5,
185+
)
186+
187+
render(
188+
scene=scene,
189+
geometry=geo,
190+
output_path="../images",
191+
file_prefix="demo_1",
192+
show=True, # disable if images cannot be displayed
193+
)
194+
195+
196+
if __name__ == "__main__":
197+
main()

src/demo_2.py

Lines changed: 34 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,27 @@
1-
"""This demo script renders a test scene using cylindrical coordinates."""
1+
"""
2+
This demo script renders a test scene using cylindrical coordinates and
3+
Runge-Kutta rays.
4+
"""
25

36
import os
47
import math
58

6-
from nerte.values.coordinates import Coordinates3D
7-
from nerte.values.domain import Domain1D
9+
from nerte.values.coordinates import Coordinates2D, Coordinates3D
810
from nerte.values.linalg import AbstractVector
9-
from nerte.values.face import Face
10-
from nerte.values.manifolds.cylindrical import (
11-
Plane as CarthesianPlaneInCylindric,
11+
from nerte.values.interval import Interval
12+
from nerte.values.domains import CartesianProduct2D, CharacteristicFunction2D
13+
from nerte.values.transitions.cartesian_cylindrical import (
14+
CartesianToCylindricalTransition,
1215
)
16+
from nerte.values.submanifolds import Plane
17+
from nerte.values.submanifolds import PushforwardSubmanifold2DIn3D
18+
from nerte.values.manifolds.euclidean.cylindrical import Cylindrical
19+
from nerte.values.face import Face
1320
from nerte.world.object import Object
1421
from nerte.world.camera import Camera
1522
from nerte.world.scene import Scene
16-
from nerte.geometry.geometry import Geometry
17-
from nerte.geometry.cylindircal_swirl_geometry import (
18-
SwirlCylindricRungeKuttaGeometry,
19-
)
23+
from nerte.geometry import Geometry
24+
from nerte.geometry.runge_kutta_geometry import RungeKuttaGeometry
2025
from nerte.render.projection import ProjectionMode
2126
from nerte.render.image_color_renderer import ImageColorRenderer
2227
from nerte.util.random_color_generator import RandomColorGenerator
@@ -29,15 +34,27 @@ def make_camera(canvas_dimension: int) -> Camera:
2934
"""Creates a camera with preset values."""
3035

3136
location = Coordinates3D((0.1, 0.0, -1.3))
32-
manifold = CarthesianPlaneInCylindric(
33-
b0=AbstractVector((1.0, 0.0, 0.0)),
34-
b1=AbstractVector((0.0, 1.0, 0.0)),
35-
x0_domain=Domain1D(-1.0, +1.0),
36-
x1_domain=Domain1D(-1.0, +1.0),
37+
interval = Interval(-1.0, +1.0)
38+
domain = CartesianProduct2D(interval, interval)
39+
40+
def not_center(coords: Coordinates2D) -> bool:
41+
# pylint: disable=C0103
42+
x, y = coords
43+
return 0 < abs(x) + abs(y) < math.inf
44+
45+
select_domain = CharacteristicFunction2D(not_center)
46+
plane = Plane(
47+
direction0=AbstractVector((1.0, 0.0, 0.0)),
48+
direction1=AbstractVector((0.0, 1.0, 0.0)),
3749
offset=AbstractVector((0.0, 0.0, -1.0)),
3850
)
51+
manifold = PushforwardSubmanifold2DIn3D(
52+
plane, CartesianToCylindricalTransition()
53+
)
3954
camera = Camera(
4055
location=location,
56+
detector_domain=domain,
57+
detector_domain_filter=select_domain,
4158
detector_manifold=manifold,
4259
canvas_dimensions=(canvas_dimension, canvas_dimension),
4360
)
@@ -146,11 +163,11 @@ def main() -> None:
146163
# NOTE: Increase the canvas dimension to improve the image quality.
147164
# This will also increase rendering time!
148165
scene = make_scene(canvas_dimension=100)
149-
geo = SwirlCylindricRungeKuttaGeometry(
166+
geo = RungeKuttaGeometry(
167+
Cylindrical(),
150168
max_ray_depth=math.inf,
151169
step_size=0.1,
152170
max_steps=50,
153-
swirl=5.0,
154171
)
155172

156173
render(

0 commit comments

Comments
 (0)