Algorithm for mapping segment with floating point vertices onto 2D integer space (pseudo-pixels) - algorithm

I want to render a line segment onto a virtual integer space in minimum average time for any segment orientation/length. The segment is defined by two points with real number values (doubles).
I have already come up with several ideas that would probably work, but they strike me as horrific, heuristic hacks. (I.e. There is a clear "better direction" to begin from depending on orientation of the segment).
Surely there is a better way than the brute force method (find the "long" direction (x- or y-axis) between the end points then step along each integer value along that axis and round the value in the orthogonal axis to determine exactly one pixel (integer point) location at every integer value along the "long" axis.)

What you say regarding the "better direction" reminds me of the Bresenham line algorithm, is this maybe what you want?
http://www.cs.helsinki.fi/group/goa/mallinnus/lines/bresenh.html
[edit]
The difference with non-integer endpoints wasn't obvious to me but there's an illustration here.
As you're drawing one pixel per integer span on the long axis I'm assuming your drawing points with equal intensity (no antialiasing).
So you can just implement bresenham without the integer optimisation (what you did already) and round points at the end.
Or use fixed point math through integer bresenham (i.e. multiply your coordinates by 65536 and round, run bresenham with a longer step on the long axis, and divide or shift the output points back down to the required values before drawing).
But depending whether you are drawing fonts, or tesellated curves, or wireframe rectangles it might look better with straight bresenhams or with an antialiasing algorithm.

You should find the equation of the line that relates the X and Y values. and then evaluate it at each integer x coordinate. This will give you the y coordinate as a float which you can then round off and draw.

Related

Algorithm: find minimum space spanning points defined only by their separations

I have a collection of points in some N-dimensional space, where all I know is the distances between them. Let's say it's an unordered collection of structs like the following:
struct {
int first; // Just some identifier that uniquely specifies a point
int second; // No importance to which point is first or second
float separation; // The distance between the first and second points -- always positive
};
Of course the algorithm doesn't have to be C code. I just wrote the struct in this style to make the problem clear. It rather upsets me that the struct spoils the symmetry between the two end-points, but fixing this just makes things more complicated.
Let's say that the separations are defined by the Pythagorean distance between them, and the space is Euclidean. Let's also specify that the separations are internally consistent. For example, given separations AB, BC and AC, we know that AB + BC >= AC.
I want an algorithm that finds the minimal dimensional space that can contain all the points. Within this algorithm, we can assume that separations that deviate from that defined by the space by less than some specified tolerance can be ignored.
Does anyone know an algorithm that does this? So far, I've only been able to think up non-polynominal algorithms. Can anybody improve on that, or at least make something that is clean and extensible?
Why is this interesting? In Physics there are some low-level theories such as String Theory or Quantum Loop Gravity that do not obviously predict our three dimensional world. This algorithm could be part of a project to find how a 3d world can be emergent.
Thank you everybody who posted ideas here. I now have an answer to my own question. It's not great, in that it executes O(n^3) but at least it's polynomial. Roughly, it works like this:
Represent the problem as a symmetric matrix with zero diagonal -- representing the distances between any two points. This is equivalent to the representation using structs, but much easier to work with.
Assume the ordering of the points implied by the matrix (first column/row = first point) is sensible. (It may be worth pivoting to find a better ordering, but that is todo.)
Now create a rectangular coordinate system to fit the points, starting with the first point, which WLOG we take to be the origin.
Second point defines the x axis
For each subsequent point, we calculate its coordinates one at a time, starting with the x axis. We know the distance from the origin and the distance from point 2. This allows us to calculate the x coordinate, as we end up with two simultaneous equations x^2 + y^2 + ... = s1^2 and (x - x2)^2 + y^2 + ... = s2^2, which allows us to calculate x easily from x2, the x coordinate of point 2, and the distances from points 1 and 2, s1 and s2.
Each new coordinate can be calculated easily, because the matrix of coordinates calculated so far is triangular -- there is only one unknown each time.
The last coordinate for each point is on a new axis -- a dimension that has not yet been used. Calculate its coordinate using Pythagoras on the distance from the origin, as we know all the other coordinates.
It is possible that the coordinate on the new axis will come out imaginary -- a general set of distances cannot always be represented by a coordinate system of any number of dimensions -- at least not with real numbers. If this is the case, I error.
Keep going in this way for each new point, building up a vector of coordinate vectors for each point. In general, this is triangular, but there may be cases where the final coordinate we calculate is near enough to zero that we consider the point's position to be represented by the existing dimensions. I store the coordinates anyway, but keep the number of dimensions the same as the previous point. I also skip these points, as they are not needed for calculating further points (see step 10).
Finally, we have represented all points such that the distances are consistent.
As a final check, I validate that the distances match for all points, including those skipped in step 9.
The number of dimensions needed is the number used for the last point.
If anyone is interested in an implementation of this (in Haskell), it is on my GitHub page at https://github.com/MarcusRainbow/EmergentDimensions/coords.hs.

Linear depth buffer

Many people use usual perspective matrix with third line like this:
(0 0 (n+f)/(n-f) 2*n*f/(n-f))
But it has problem with float precision near far clipping surface. The result is z-fighting.
What about to use linear transformation of z? Let's change the matrix third line to this:
(0 0 -2/(f-n) (-f-n)/(f-n))
It will be linear transformation z from [-n, -f] to [-1, 1]. Then, we will add the line in vertex shader:
gl_Position.z *= gl_Position.w;
After perspective divide the z value will be restored.
Why don't it used everywhere? I found a lot of articles in internet. All of them used a usual matrix.
Is linear transformation described by me has problems what I don't see?
Update: This is not a duplicate of this. My question is not about how to do linear depth buffer. In my case, the buffer is already linear. I don't understand, why is this method not used? Are there traps in the inner webgl pipeline?
The approach you're describing simply doesn't work. One advantage of a hyperbolic Z buffer is that we can interpolate the resulting depth values linearly in screen space. If you multiply gl_Position.z by gl_Position.w, the resulting z value will not be linear in screen space any more, but the depth test will still use linearly interpolated values. This results in your primitives becoming bend in the z-dimension, leading to completely wrong occlusions and intersections between nearby primitives (especially if the vertices of on primitive lie near the center of the other).
The only way to use a linear depth buffer is to actually do the non-linear interpolation for the Z value yourself in the fragment shader. This can be done (and boil's down to just linearly transform the perspective-corrected interpolated w value for each fragment, hence it is sometimes called "W buffering"), but you're losing the benefits of the early Z test and - much worse - of the hierarchical depth test.
An interesting way to improve the precision of the depth test is to use a floating point buffer in combination with a reversed Z projection matrix, as explained in this Depth Precision Visualized blog article.
UPDATE
From your comment:
Depth in screen space is linear interpolation of NDC, how I understand form here. In my case, it will be linear interpolation of linear interpolation of z from camera space. Thus, depth in screen space interpolated already.
You mis-understood this. May main point was that the linear interpolation in screen space is only valid if you're using Z values which are already hyperbolically distorted (like NDC Z). If you want to use eye-space Z, this can not be linearly interpolated. I made some drawings of the situation:
This is a top-down view on eye-space and NDC. All drawings are actually to scale. The green ray is a view ray going through some pixel. This pixel happens to be the one which directly represents the mid-point of that one triangle (green point).
After the projection matrix is applied and the division by w has happened, we are in normalized device coordinates. Note that the direction of the viewing ray is now just +z, and all view rays of all pixels became parallel (so that we can just ignore Z when rasterizing). Due to the hyperbolic relation of the z value, the green point now does not lie on exactly on the center any more, but is squeezed towards the far plane. However, the important point is that this point now lies on the straight line formed by the (hyperbolically distorted) end points of the primitive - hence we simply can interpolate z_ndc linearly in screen space.
If you use a linear depth buffer, the green point now lies at z in the center of the primitive again, but that point is not on the straight line - you actually bend your primitives.
Since the depth test will use a linear interpolation, it will just get the points as in the rightmost drawing as input from the vertex shader, but will interpolate them linearly - connecting those points by straight lines. As a result, the intersection between primitives will not be where it actually has to be.
Another way to think of this: Imagine you draw some primitive which extents into the z-dimension, with some perspective projection. Due to perspective, stuff that is farther away will appear smaller. So if you just go one pixel to the right in screen space, the z extent covered by that step will actually bigger if the primitive is far away, while it will become smaller and smaller as closer you get. So if you just go in equal-sized steps to the right, the z-steps you're making will vary depending on the orientation and position of your primitive. However, we want to use a linear interpolation, so we want to make the same z step size for every x step. The only we to do this is by distorting the space z is in - and the hyperbolical distortion introduced by the division by w exactly does that.
We don't use a linear transformation because that will have precision problems at all distances equally. At least now, the precision problems only show up far away, where you're less likely to notice. A linear mapping spaces the error out evenly, which makes errors more likely to happen close to the camera.

what is meant by symmetric DDA?

I have read about DDA. But I just came across the term symmetric DDA. What is it ? How is it different from DDA ?
The DDA (Digital Differential Analyzer) algorithm is used to find out interpolating points between any given two points, linearly (i.e. straight line). Now since this is to be done on a digital computer - speed is an important factor.
The equation of a straight line is given by m=Δx/Δy eq(i), where Δx = x(2)-x(1) & Δy = y(2)-y(1),now using this equation we could compute successive points that lie on the line. But then this is the discrete world of raster graphics - so we require integral coordinates.
In simple DDA eq(i) is transformed to m=eΔx/eΔy where e, call it the increment factor, is a positive real number. since putting the same number in numerator and denominator does not change anything - but if suitably chosen - it can help us in generating discrete points thereby reducing the overload of having to round off the resultant points.
Basically what we need to do is: increment the coordinates by a fixed small amount, beginning from the starting point, and each time we have a new point progressing towards the end point.
In simple DDA - e is chosen as 1/max(|Δx|,|Δy|) such that one of the coordinate is integral and only the other coordinate has to be rounded. i.e. P(i+1) = P(i)+(1,Round(e*Δy)) here one coordinate is being incremented by 1 and the other by e*Δy
In symmetric DDA - e is chosen such that though both the co-ordinates of the resultant points has to be rounded off, it can be done so very efficiently, thus quickly.
Specifically e is chosen as 1/2^n where 2^(n-1) <= max(|Δx|,|Δy|) < 2^n. In other words the length of the line is taken to be 2^n aligned. The increments for the two coordinates are e*Δx and e*Δy. With suitably chosen initial fraction part of the beginning coordinates: this causes the points to be generated as mixed fractions whose fractional parts are in a cyclic series, i.e. they repeat over a small length. The resultant coordinates can thus easily be rounded off based on two fixed length look-up tables, one for each coordinate.
refer http://w3.msi.vxu.se/~gsu/DAB726-Ht06/Symm-DDA.pdf for an example.
Notice the cyclic repetition in the fractional part of the resultant coordinates.

finding saddle points in 3d heightmap

Given a 3d heightmap (from a laser scanner), how do I find the saddle points?
I.e. given something like this:
I am looking for all points where the curvature is positive in one direction and negative in the other.
(These directions should not need to be aligned with the X and Y axis.
I know how to check whether the curvature in X direction has the opposite sign as the curvature in Y direction, but that does not cover all cases. To make matters worse, the resolution in X is different from the resolution in Y)
Ideally I am looking for an algorithm that can tolerate some amount of noise and only mark "significant" saddle points.
I've been exploring a similar problem for a computational topology class and have had some success with the method outlined below.
First you will need a comparison function that will evaluate the height at two input points and will return < or > (not equal) for any input. One way to do this is that if the points are equal height you use some position-based or random index to find the greater point. You can think of this as adding an infinitesimal perturbation to the height.
Now, for each point, you will compare the height at all the surrounding neighbors (there will be 8 neighbors on a 2D rectangular grid). The lower link for a point will be the set of all neighbors for which the height is less than the point.
If all the neighboring values are in the lower link, you are at a local maximum. If none of the points are in the lower link you are at a local minimum. Otherwise, if the lower link is a single connected set, you are at a regular point on a slope. But if the lower link is two unconnected sets, you are at a saddle.
In 2D you can construct a list of the 8 neighboring point in cyclic order around the point you are checking. You assign a value of +/-1 for each neighbor depending on your comparison function. You can then step through that list (remember to compare the two end points) and count how many times the sign changes to determine the number of connected components in the lower link.
Determining which saddles are "important" is a more difficult analysis. You may wish to look at this: http://www.cs.jhu.edu/~misha/ReadingSeminar/Papers/Gyulassy08.pdf for some guidance.
-Michael
(From a guess at the maths rather than practical experience)
Fit a quadratic to the surface in a small patch around each candidate point, e.g. with least squares. How big the patch is is one way of controlling noise, and you might gain by weighting points depending on their distance from the candidate point. In matrix notation, you can represent the quadratic as x'Ax + b'x + c, where A is symmetric.
The quadratic will have zero gradient at x = (A^-1)b/2. If this not within the patch, discard it.
If A has both +ve and -ve eigenvalues you have a saddle point at x. Since A is only 2x2 and so has at most two eigenvalues, you can ignore the case when it as a zero eigenvalue and so you couldn't invert it at the previous stage.

Intersection of a 3D Grid's Vertices

Imagine an enormous 3D grid (procedurally defined, and potentially infinite; at the very least, 10^6 coordinates per side). At each grid coordinate, there's a primitive (e.g., a sphere, a box, or some other simple, easily mathematically defined function).
I need an algorithm to intersect a ray, with origin outside the grid and direction entering it, against the grid's elements. I.e., the ray might travel halfway through this huge grid, and then hit a primitive. Because of the scope of the grid, an iterative method [EDIT: (such as ray marching) ]is unacceptably slow. What I need is some closed-form [EDIT: constant time ]solution for finding the primitive hit.
One possible approach I've thought of is to determine the amount the ray would converge each time step toward the primitives on each of the eight coordinates surrounding a grid cell in some modular arithmetic space in each of x, y, and z, then divide by the ray's direction and take the smallest distance. I have no evidence other than intuition to think this might work, and Google is unhelpful; "intersecting a grid" means intersecting the grid's faces.
Notes:
I really only care about the surface normal of the primitive (I could easily find that given a distance to intersection, but I don't care about the distance per se).
The type of primitive intersected isn't important at this point. Ideally, it would be a box. Second choice, sphere. However, I'm assuming that whatever algorithm is used might be generalizable to other primitives, and if worst comes to worst, it doesn't really matter for this application anyway.
Here's another idea:
The ray can only hit a primitive when all of the x, y and z coordinates are close to integer values.
If we consider the parametric equation for the ray, where a point on the line is given by
p=p0 + t * v
where p0 is the starting point and v is the ray's direction vector, we can plot the distance from the ray to an integer value on each axis as a function of t. e.g.:
dx = abs( ( p0.x + t * v.x + 0.5 ) % 1 - 0.5 )
This will yield three sawtooth plots whose periods depend on the components of the direction vector (e.g. if the direction vector is (1, 0, 0), the x-plot will vary linearly between 0 and 0.5, with a period of 1, while the other plots will remain constant at whatever p0 is.
You need to find the first value of t for which all three plots are below some threshold level, determined by the size of your primitives. You can thus vastly reduce the number of t values to be checked by considering the plot with the longest (non-infinite) period first, before checking the higher-frequency plots.
I can't shake the feeling that it may be possible to compute the correct value of t based on the periods of the three plots, but I can't come up with anything that isn't scuppered by the starting position not being the origin, and the threshold value not being zero. :-/
Basically, what you'll need to do is to express the line in the form of a function. From there, you will just mathematically have to calculate if the ray intersects with each object, as and then if it does make sure you get the one it collides with closest to the source.
This isn't fast, so you will have to do a lot of optimization here. The most obvious thing is to use bounding boxes instead of the actual shapes. From there, you can do things like use Octrees or BSTs (Binary Space Partitioning).
Well, anyway, there might be something I am overlooking that becomes possible through the extra limitations you have to your system, but that is how I had to make a ray tracer for a course.
You state in the question that an iterative solution is unacceptably slow - I assume you mean iterative in the sense of testing every object in the grid against the line.
Iterate instead over the grid cubes that the line intersects, and for each cube test the 8 objects that the cube intersects. Look to Bresenham's line drawing algorithm for how to find which cubes the line intersects.
Note that Bresenham's will not return absolutely every cube that the ray intersects, but for finding which primitives to test I'm fairly sure that it'll be good enough.
It also has the nice properties:
Extremely simple - this will be handy if you're running it on the GPU
Returns results iteratively along the ray, so you can stop as soon as you find a hit.
Try this approach:
Determine the function of the ray;
Say the grid is divided in different planes in z axis, the ray will intersect with each 'z plane' (the plane where the grid nodes at the same height lie in), and you can easily compute the coordinate (x, y, z) of the intersect points from the ray function;
Swipe z planes, you can easily determine which intersect points lie in a cubic or a sphere;
But the ray may intersects with the cubics/spheres between the z planes, so you need to repeat the 1-3 steps in x, y axises. This will ensure no intersection is left off.
Throw out the repeated cubics/spheres found from x,y,z directions searches.

Resources