{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Transformation toolbox"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This how-to guide explores the different tools available in Mitsuba 3 to manipulate cartesian coordinate systems. When generating datasets, researching advanced light transport algorithms, or developing new appearance models, you will quickly realize how essential those tools are, so we strongly recommend all users to go through this guide."
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"import mitsuba as mi\n",
"\n",
"mi.set_variant(\"scalar_rgb\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Frame\n",
"\n",
"The [Frame3f
][1] class stores a three-dimensional orthonormal coordinate frame. This class is very handy when you wish to convert vectors between different cartesian coordinates systems.\n",
"\n",
"[1]: https://mitsuba.readthedocs.io/en/latest/src/api_reference.html#mitsuba.Frame3f"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Frame initialization\n",
"\n",
"A `Frame3f` can be initialized in different ways as shown below. When given a single vector, it will make use of [coordinate_system()
][1] to compute the other two basis vectors.\n",
"\n",
"[1]: https://mitsuba.readthedocs.io/en/latest/src/api_reference.html#mitsuba.coordinate_system"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Frame[\n",
" s = [1, -0, -0],\n",
" t = [-0, 0, -1],\n",
" n = [0, 1, 0]\n",
"]"
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"mi.Frame3f() # Empty frame\n",
"\n",
"mi.Frame3f(\n",
" [1, 0, 0], # s\n",
" [0, 1, 0], # t\n",
" [0, 0, 1], # n\n",
")\n",
"\n",
"mi.Frame3f([0, 1, 0]) # n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Converting to/from local frames\n",
"\n",
"The two methods below are the main operations you will be using to convert between different coordinate frames.\n",
"\n",
"- [Frame3f.to_local()
][1]\n",
"- [Frame3f.to_world()
][2]\n",
"\n",
"[1]: https://mitsuba.readthedocs.io/en/latest/src/api_reference.html#mitsuba.Frame3f.to_local\n",
"[2]: https://mitsuba.readthedocs.io/en/latest/src/api_reference.html#mitsuba.Frame3f.to_world"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[1.0, 2.0, 3.0]"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"frame = mi.Frame3f(\n",
" [0, 0, 1],\n",
" [0, 1, 0],\n",
" [1, 0, 0],\n",
")\n",
"\n",
"world_vector = mi.Vector3f([3, 2, 1]) # In world frame\n",
"local_vector = frame.to_local(world_vector)\n",
"local_vector"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Spherical coordinates\n",
"\n",
"Mitsuba 3 provides convenience methods to efficiently compute certain trigonometric evaluations of spherical coordinates with respect to a `Frame3f`. We use the naming convention that *theta* is the elevation and *phi* is the azimuth.\n",
"For example, you can call `Frame3f.sin_theta_2()` or `Frame3f.cos_phi()`. As always, the full list of methods is availble in the [reference API][1].\n",
"\n",
"[1]: https://mitsuba.readthedocs.io/en/latest/src/api_reference.html#mitsuba.Frame3f"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Transform\n",
"\n",
"The `Transform4f` and `Transform3f` classes provides several static functions to create common transformations, such as `translate`, `scale`, `rotate` and `look_at`. These are often used for setting `\"to_world\"` object parameters in Python using `load_dict()`. As we will see later, those transformations can also be applied to a `Vector`, `Point`, `Normal` and even a `Ray3f`. \n",
"\n",
"Note that all transforms are in homogenous coordiantes. `Transform4f` can therefore be applied to 3-dimensional objects and `Transform3f` to 2-dimensional objects.\n",
"\n",
"The `Transform4f` and `Transform3f` objects hold both the transformation matrix and its transpose of inverse. For convenience, there is also a `Transform4f.inverse()` method. All put together, this makes transforming back and forth straightforward.\n",
"\n",
"