利用者:TrumanBlending/Four Dimensional Vectors
目次
Proposal: Four Dimensional Mathutils Vectors
Introduction
Vectors are utilised throughout Blender in order to represent positions in many different situations, such as vertex positions or object locations. Currently Blender supports 2D, 3D and 4D vectors.
In most situations 2D and 3D vectors suffice for a user's needs as they are easy to conceptualise as we inhabit a world of three spatial dimensions (or 11 if you ask some people, but that's another story). By manipulating vectors using matrices, common transformations such a rotation, scaling, orthographic projection, reflection and shearing can be easily achieved. For an explanation of rotation matrices in 3D see [1]. A three dimensional vector is commonly denoted v = (x, y, z).
However, in order to correctly handle certain matrix transformations a standard 3D vector is no longer sufficient. In order to represent translations and perspective projections we must add a fourth component to our vector, w. Thus a 4D vector has been created. A position in space which previously had been written (x, y, z) is now written as (w * x, w * y, w * z, w) = (x, y, z, 1). This particular system of coordinates is known as homogeneous coordinates, see [2]. Using this representation we can now represent the most common transformations in 3D space.
Blender's Implementation
Blender currently contains implementations of 2D, 3D and 4D vectors within the mathutils Python module, importantly it also contains matrices which may be used to perform transformations on the vectors. Typically 2D and 3D vectors are commonly used to represent data in a plane (e.g. UV coordinates and UI position) and data in three dimensions (e.g. object position and orientation) respectively.
As previously noted some transformations require the use of homogeneous coordinates and it is for this reason that Blender also supports 4D vectors.
Current Issues
The implementation used by Blender has some current issues which I will highlight here.
- Incorrect Handling of Homogeneous Coordinates
- Currently, calculations using 4D vectors do not respect the fact that we are using homogeneous coordinates, not four spatial coordinates. The upshot is that an equation such as; (x1, y1, z1, 1) + (x2, y2, z2, 1) = (x1+x2, y1+y2, z1+z2, 2) which is incorrect when translated back to regular 3D coordinates. The correct result is (x1+x2, y1+y2, z1+z2, 1). This issue is also present in scalar multiplication and vector normalisation. It also requires special handling in almost all situations where a 3D vector is expected.
- Inconsistent Internal Handling
- Although mathematically speaking, homogeneous coordinates are required in order to correctly apply translations and perspective projections, Blender allows translation matrices to be applied to 3D vectors, it does this by assuming the w coordinate is 1. This is always true of positions when first translated to homogeneous coordinates. However, in the case of perspective projections, Blender does not permit this assumption and as such a 4D vector must be used explicitly.
Possible Solutions
As I see it, there are two possible solutions to remedy this problem.
- Ensure all vector operations respect homogeneous coordinates. This requires handling of the special case where vec->size==4.
- Remove support for 4D vectors and ensure matrix multiplications make the assumption that the w coordinate is 1.
I personally favour the latter option. I'll detail why in the next section.
Proposed Solution and Justification
Removing support for 4D vectors has several favourable attributes;
- Ease of Use
- The user can simply apply transformations to the vector without first having to worry about the type of transformation (translation, rotation etc.) taking place.
- Consistency
- We can already multiply a translation matrix with a 3D vector although not this is not mathematically correct and should require the use of homogeneous coordinates. However, we cannot do the same with a perspective projection matrix.
- Better Generalisation to N-Dimensional Vectors
- If we wish to extend mathutils Vectors to arbitrary length for data manipulation we do not need to worry about the special N=4 case in all the addition/scalar multiplication code.
Drawbacks to the Above Solution
- Breaking Scripts
- Since support for 4D vectors for geometric purposes will be removed any script using them will be forced to change. However, I know of only one script which currently uses 4D vectors for their homogeneous coordinates and this is for perspective projection which will now be permitted for 3D vectors.
- No Explicit Use of Homogeneous Coordinates
- By removing 4D vectors the explicit use of homogeneous coordinates by the user will be removed and handled internally instead. However, as highlighted above, all but the simplest uses of homogeneous coordinates fail in the current implementation. As this is the case but has not been accompanied by user complaints of inconsistent results, we may conclude that they are not in a high level of usage.
- Matrix Multiplication and Homogeneous Coordinates
- If homogeneous coordinates are to be assumed for the 3D vectors then all matrix multiplications involving them must account for the w=1 coordinate. This includes rescaling of the vector to ensure that after each matrix multiplication the w cooordinate is returned to 1.
Conclusion
I believe that the above arguments are in favour of the removal of 4D vectors for geometric transformations. They currently are only required for perspective projections but even in this case it is inconsistent with translations transformations. By removing support for 4D vectors we preclude the need for handling homogeneous coordinates in all vector functions and instead confine changes to matrix/vector multiplications, which may be handled much more generally. This also removes the need to continually ensure that the w coordinate is 1 when converting back to ordinary spatial coordinates.
--TrumanBlending 12:36, 2 December 2011 (CET)