I have been carrying out 2D and 3D operations, including graphics, for many years and have never used quaternions so I don't have a feel for them. I know that they can be used for certain operations that are difficult in Euler angles and also that they can be used to find the rotation required to best fit one set of coordinates (X1, X2...XN, X=(xyz)) onto another (X1', X2'... XN').
Are there places where quaternions are essential? And are there places where they make solutions more elegant or more efficient?
They have a smaller memory footprint than rotation matrices and they are more efficient than both matrix and angle/axis representations.
Also:
It's extremely easy to interpolate between two quaternions, which is useful for smooth camera movements etc.
Unit normalisation of floating point quaternions suffers from fewer rounding defects than matrix representations.
Quaternions have many advantages over Euler angles and are often preferable for 3D rotations:
Easier (and well-defined) interpolation between quaternions (or: orientations): the resulting movement has constant angular velocity around a single axis, which is often aesthetically more pleasing. This process is called "slerp" and critical for animation/rotation blending. Furthermore, quaternion interpolation does not suffer from Gimbal locks.
They are easy to renormalize.
Disadvantages:
The main disadvantage is that they require a bit more math and are less intuitive than Euler/Cardanic angles.
Compared to affine transformation matrices, Quaternions only contain a rotation, and no translation and scaling.
With quaternions you also handle the problem of the gimbal lock. And they are easier to work with when you want to perform arbitrary rotations.
Pros of quaternions
Fast multiplication
Fast to/from matrix conversion
Avoid additional (from computation) noise (scale , shear) , and represent pure rotation
Simple rotation interpolation, in custom case for real time animation can be used linear interpolation.
Some tricky operations available, fast rotation integration, twist swing decompositions
Cons.
Transformation of vector is not so fast as with 3x3 matrix.
Contains 4 scalar, but compact rotation representation can use only 3.
The advantage of quaternions over matrices is not only faster computation, but mostly because a matrix representation of successive rotations around arbitrary angles eventually give in to dreadful floating-point round-off errors and no longer represent proper, affine rotations. "Restoring" a rotation matrix is computationally more expensive than normalizing a quaternion. Therefore, quaternions should be chosen over pure rotation matrices.
Compared to Euler angles they are simpler to compose and avoid the problem of gimbal lock.
Compared to rotation matrices they are more numerically stable and the representation (4 numbers) is more compact.
Related
I have been using the cgal library to generate convex hulls which are further used for discrete element simulations. Currently, I am trying to make the polyhedral particles break, which is right now implemented as plane clipping of the polyhedron. The problem is that after several (sometimes even one) clipping, the polyhedrons start having "bad" attributes, such as nearly degenerate faces, nearly coplanar edges or nearly degenerate edges, which cause problems in the contact calculation. I have been looking at CGAL/Surface_mesh_simplification routines and used the edge_collapse function, but it does not preserve convexity of the particles. Is there any way to use routines from cgal for convex polyhedra simplifications while preserving convexity?
You can try using the function isotropic_remeshing(). While there is no guarantee that the output will stay convex, the points are guaranteed to be on the input mesh. If you have some sharp edges you want to preserve, you can specify it to the function and it will take them into account.
I have historical aircraft trajectory data with points varying from 1 second - 1 minute separation. Often these points present sharp turns. I'm looking for suggestions of best methods of resampling the data to generate smooth paths (e.g. point every n seconds) that more realistically represent the path followed. It would be useful to be able to parameterize the function with certain performance characteristics (e.g. rate of change of direction).
I'm aware of algorithms like the Kalman filter, Bezier curve fitting, splines etc. for data smoothing. But what algorithms would you suggest exploring as a starting point for generating smooth turns?
Schneider's Algorithm is an algorithm that approximately fits curves through a series of points.
The resulting curves have a drastically reduced point-count and it's error-tolerance is configurable, so you can adjust it as much as you need to.
In general:
Lower error-tolerance: More points, more accurate, less execution
Higher error-tolerance: Less points, less accurate, faster execution
Some useful links:
A live Javascript example, and it's implementation here.
Python Example
C++ implementation
If the resulting curve must pass exactly through your points, you need an interpolation algorithm instead of an approximation algorithm, but keep in mind that those do not reduce point-count.
A really good type of interpolating spline is the Centripetal Catmull-Rom Spline.
I figured someone probably asked this question before but I wasn't able to find an answer.
I'm writing a physics library for my game engine (2d, currently in actionscript3, but easily translatable to C based languages).
I'm having problems finding a good formula to calculate the inertia of my game objects.
The thing is, there are plenty of proven formulas to calculate inertia around a centroid of a convex polygon, but my structure is slightly different: I have game-objects with their own local space. You can add convex shapes such as circles and convex polygons to this local space to form complex objects. The shapes themselves again have their own local space. So there are three layers: World, object & shape space.
I would have no problems calculating the inertia of each individual polygon in the shape with the formulas provided on the moments of inertia Wikipedia article.
or the ones provided in an awesome collision detection & response article.
But I'm wondering how to relate this to my object structure, do I simply add all the inertia's of the shapes of the object? That's what another writer uses to calculate the inertia of triangulated polygons, he adds all the moments of inertia of the triangles. Or is there more to it?
I find this whole inertia concept quite difficult to understand as I don't have a strong physics background. So if anyone could provide me with an answer, preferably with the logic behind inertia around a given centroid, I would be very thankful. I actually study I.T. - Game development at my university, but to my great frustration none of the teachers in their ranks are experienced in the area of physics.
Laurens, the physics is much simpler if you stay in two dimensional space. In 2D space, rotations are described by a scalar, resistance to rotation (moment of inertia) is described by a scalar, and rotations are additive and commutative. Things get hairy (much, much hairier) in three dimensional space.
When you connect two objects, the combined object has its own center of mass. To calculate the moment of inertia of this combined object, you need to sum the moments of inertia of the individual objects and also add on offset term given by the Steiner parallel axis theorem for each individual object. This offset term is the mass of the object times the square of the distance to the composite center of mass.
The primary reason you need to know the moment of inertia is so that you can simulate the response to torques that act on your object. This is fairly straightforward in 2D physics. Rotational behavior is an analog to Newton's second law. Instead of F=ma you use T=Iα. (Things once again are much hairier in 3D space.) You need to find the external forces and torques, solve for linear acceleration and rotational acceleration, and then integrate numerically.
A good beginner's book on game physics is probably in order. You can find a list of recommended texts in this question at the gamedev sister site.
For linear motion you can just add them. Inertia is proportional to mass. Adding the masses of your objects and calculating the inertia of the sum is equivalent to adding their individual inertias.
For rotation it gets more complicated, you need to find the centre of mass.
Read up on Newton's laws of motion. You'll need to understand them if you're writing a physics engine. The laws themselves are very short but understanding them requires more context so google around.
You should specifically try to understand the concepts: Mass, Inertia, Force, Acceleration, Momentum, Velocity, Kinetic energy. They're all related.
I'm considering exploiting ray coherence in my software per-pixel realtime raycaster.
AFAICT, using a uniform grid, if I assign ray coherence to patches of say 4x4 pixels (where at present I have one raycast per pixel), given 16 parallel rays with different start (and end) point, how does this work out to a coherent scene? What I foresee is:
There is a distance within which the ray march would be exactly the same for adjacent/similar rays. Within that distance, I am saving on processing. (How do I know what that distance is?)
I will end up with a slightly to seriously incorrect image, due to the fact that some rays didn't diverge at the right times.
Given that my rays are cast from a single point rather than a plane, I guess I will need some sort of splitting function according to distance traversed, such that the set of all rays forms a tree as it move outward. My concern here is that finer detail will be lost when closer to the viewer.
I guess I'm just not grasping how this is meant to be used.
If done correctly, ray coherence shouldn't affect the final image. Because the rays are very close together, there's a good change that they'll all take similar paths when traversing the acceleration structure (kd-tree, aabb tree, etc). You have to go down each branch that any of the rays could hit, but hopefully this doesn't increase the number of branches much, and it saves on memory access.
The other advantage is that you can use SIMD (e.g. SSE) to accelerate some of your tests, both in the acceleration structure and against the triangles.
Implementing convolution in a pixel shader is somewhat costly as to the very high number of texture fetches.
A direct way of implementing a convolution filter is to make N x N lookups per fragment using two for cycles per fragment. A simple calculation says that a 1024x1024 image blurred with a 4x4 Gaussian kernel would need 1024 x 1024 x 4 x 4 = 16M lookups.
What can one do about this?
Can one use some optimization that would need less lookups? I am not interested in kernel-specific optimizations like the ones for the Gaussian (or are they kernel specific?)
Can one at least make these lookups faster by somehow exploiting the locality of the pixels one would work with?
Thanks!
Gaussian kernels are separable, which means you can do a horizontal pass first, then a vertical pass (or the other way around). That turns O(N^2) into O(2N). That works for all separable filters, not just for blur (not all filters are separable, but many are, and some are "as good as").
Or,in the particular case of a blur filter (Gauss or not), which are all kind of "weighted sums", you can take advantage of texture interpolation, which may be faster for small kernel sizes (but definitively not for large kernel sizes).
EDIT: image for the "linear interpolation" method
EDIT (as requested by Jerry Coffin) to summarize the comments:
In the "texture filter" method, linear interpolation will produce a weighted sum of adjacent texels according to the inverse distance from the sample location to the texel center. This is done by the texturing hardware, for free. That way, 16 pixels can be summed in 4 fetches. Texture filtering can be exploited in addition to separating the kernel.
In the example image, on the top left, your sample (the circle) hits the center of a texel. What you get is the same as "nearest" filtering, you get that texel's value. On the top right, you are in the middle between two texels, what you get is the 50/50 average between them (pictured by the lighter shader of blue). On the bottom right, you sample in between 4 texels, but somewhat closer to the top left one. That gives you a weighted average of all 4, but with the weight biased towards the top left one (darkest shade of blue).
The following suggestions are courtesy of datenwolf (see below):
"Another methods I'd like suggest is operating in fourier space, where convolution turns into a simple product of fourier transformed signal and fourier transformed kernel. Although the fourier transform on the GPU itself is quite tedious to implement, at least using OpenGL shaders. But it's quite easy done in OpenCL. Actually I implement such things using OpenCL, now, a lot of image processing in my 3D engine happens in OpenCL.
OpenCL has been specifically designed for running on GPUs. A Fast Fourier Transform is actually the piece of example code on Wikipedia's OpenCL article: en.wikipedia.org/wiki/OpenCL and yes the performance gain is tremendous. A FFT executes with at most O(n log n), the reverse the same. The filter kernel fourier representation can be precomputed. The way is FFT -> multiply with kernel -> IFFT, which boils down to O(n + 2n log n) operations. Take note the the actual convolution is just O(n) there.
In the case of a separable, finite convolution like a gaussian blur the separation solution will outperform the fourier method. But in case of generalized, possible non-separable kernels the fourier methods is probably the fastest method available.
OpenCL integrates nicely with OpenGL, e.g. you can use OpenGL buffers (textures and vertex) for both input and ouput of OpenCL programs."
More than being separable, Gaussian filters are also computable in O(1) :
There are recursive computations like the Deriche one :
http://hal.inria.fr/docs/00/07/47/78/PDF/RR-1893.pdf
Rotoglup's answer to my question here my be worth reading; in particular, this blog post about Gaussian blur really helped me understand the concept of separable filters.
One more approach is approximating Gaussian curve with step-wise function: https://arxiv.org/pdf/1107.4958.pdf (I guess piece-wise linear functions can be also used of course).