OpenGL line rasterization with integer endpoints - opengl

In the OpenGL specification, line rasterization is defined by the 'diamond-exit' rule.
For each fragment f with center at window coordinates xf and yf,
define a diamond-shaped region that is the intersection of four half planes:
Rf = {(x, y) | |x−xf| + |y−yf| < 1/2}.
Essentially, a line segment starting at pa and ending at pb produces those fragments f for which the segment intersects Rf, except if pb is contained in Rf.
(from the OpenGL 1.5 specification, section 3.4.1)
This means that a line parallel to the x or y axis with integer endpoints will not be drawn at all. E.g. a line starting at (x,y) = (5, 5) and ending at (5,10) will never have a manhattan distance smaller than 1/2 to any fragment center.
Is there any reason why the spec left such a "hole" between two fragments?
In the following part an additional criterion is described to determine if a fragment is drawn:
To avoid difficulties when an endpoint lies on a boundary of Rf we (in principle) perturb the supplied endpoints by a tiny amount. Let pa and pb have window coordinates (xa, ya) and (xb, yb), respectively. Obtain the perturbed endpoints p′a given by (xa, ya) − (ϵ, ϵ2) and p′b given by (xb, yb) − (ϵ, ϵ2). Rasterizing the line segment starting at pa and ending at pb produces those fragments f for which the segment starting at p′a and ending on p′b intersects Rf, except if p′b is contained in Rf. ϵ is chosen to be so small that rasterizing the line segment produces the same fragments when δ is substituted for ϵ for any 0 < δ ≤ ϵ.
(from the OpenGL 1.5 specification, section 3.4.1)
I assume they have added this extra rule to account for edge cases like my example. But why didn't they allow points with a distance of exactly 1/2 in the first place?
Also, since δ and ϵ are positive, does this mean that lines that pass perfectly in the middle between two fragment centers will default to the lower fragment (with a horizontal line) or the leftmost fragment (with a vertical line)?

But why didn't they allow points with a distance of exactly 1/2 in the first place?
Because that would result in generating two fragments in these cases, resulting in a thicker line than intended. One needs some kind of tie-breaking rule, and the formulation chosen in the GL spec is just that.
Also, since δ and ϵ are positive, does this mean that lines that pass perfectly in the middle between two fragment centers will default to the lower fragment (with a horizontal line) or the leftmost fragment (with a vertical line)?
No. Because the GL spec doesn't require implementations to use the diamond exit rule. The paragraph you quoted from actually begins with
Ideally, the GL uses a “diamond-exit" rule to determine those fragments that
are produced by rasterizing a line segment. [...]
In later paragraphs it is stated:
Because the initial and final conditions of the diamond-exit rule may be difficult
to implement, other line segment rasterization algorithms are allowed, subject to
the following rules:
The coordinates of a fragment produced by the algorithm may not deviate by
more than one unit in either x or y window coordinates from a corresponding
fragment produced by the diamond-exit rule.
The total number of fragments produced by the algorithm may differ from
that produced by the diamond-exit rule by no more than one.
[...]
Rule 1 alone already allows an implementation to use some tie-breaking rule of it's own choosing.

Related

How to fill polygons with even-odd rule?

I have n polygons. Each Polygon has n points, and some other properties like bounding box and etc. I can fill them separetly in some color , but i want to fill polygons with even-odd rule. Which algorithms are there for this ? (may be vector based or raster based)
If raster is OK for you, calculate all cross points of edges vs line (list of intersections per line). Put horizontal lines between raster lines, so [for square] line above has no edge intersections, line under has two intersections.
Now go for every line from left to right per intersection, you start "outside", and every intersection you invert the current state.
(BTW, you may assert that you end "outside" as well ... of course I'm talking about infinite x-res, you may further constrain it to some fixed resolution, but calculation starts where ever is the first intersection, and I would run till the last one, just for that assert check)
It may be tricky to get the almost-horizontal lines correctly, and connection between two edges (imagine sharp end of star, going down and up at the same raster pixel, with only 0.1px x-coord diff, etc.).
I would probably draw some pictures on paper, if clean math will do, or some corner-case logic is needed, then unit test heavily.
If you want full vector, it's basically the same, just it's not per line, but per each end of edge y-coord (creating virtual line) to calculate all intersections with other edges.
Actually this may be tad easier to write, but then it may be tad more difficult to apply the result on raster image. IMHO (far from feeling "sure", been long time since I did this).
Using stencil flipping should be the most efficient raster-based method to do this. Do one pass to populate the stencil buffer ( e.g. glStencilOp(GL_KEEP, GL_KEEP,GL_INVERT)) and a second pass with a full-screen quad that sets the color depending on the stencil buffer's values (e.g. glStencilFunc(GL_EQUAL, 1 ,1))

Recognize pattern in 3D environment

I'm currently developing 3rd person building game (as bacheleor thesis). I need to recognize constructed patterns co I can mark corresponding structure as some building (so player can start using that building).
I have folowing rules:
3 types of building blocks (all based on cube) (and in future there will be more types)
any block can be scaled up to k multiple in each axis (k = 20)
blocks can be rotated by any axis (but stays in 3D grid)
Problem definition:
4 cubes of base size (1,1,1) in a grid 2x2 should be equivalent to 1
box size (2,2,1), so all possible variants (mainly different in rotation) could be evaluated as valid pattern construction.
I expect that my patterns will be up to 30x30x30 multiple of base size.
For example, I'd like to recognize structure like this: (currently placed in level by hand)
Size is 21x21x22 and it is constructed from multiple objects.
As a limitation, I will border pattern search from exact point (lets say control console for that structure). Current limitation constant is around 50x50x50 multiple of base cube. (Limit is subject to change based on answers here.)
I searched over 20hrs and result was only papers to recognize 3D structure from 2D image or recognize exact structure in 2D.
My problem is that with growing K( each X,Y,Z) there is exponencially growing number of structures, which should be accepted as correct pattern construction.
Question: What algorithm (+ heurestic) should I use?
Following 3 images contains visualization of structures, that are considered as correct variant of pattern at image 4, thus they should be found and accepted.
All together has same final shape (and has same material at same places). I simplified the problem only to 2D shape, but extending in 3D space is obvious.
Thank you for all answers / comments.
If every building block whose axes can be scaled can be subdivided into smaller 1x1x1 building blocks, and if the following conditions adequately describe whether a built structure should match a given template:
Arbitrarily subdividing a template building block should not cause a mismatch
Arbitrarily "extruding through" any axis-aligned plane (imagine slicing through the world in some axis-aligned plane and then pulling the two halves apart, while new matter continuously fills in the gaps between points that were originally touching) should not cause a mismatch
Any other difference forces a mismatch
then it should be possible to efficiently recognise built instances of a template structure in time O(b + t^2), where b is the voxel volume of the built structure and t is the (typically very small; see below) voxel volume of the template. The basic idea is to transform any built structure into a canonical form in which any "extruded range" is compacted down to a single voxel in length.
Atomise then canonicalise
First, atomise all building blocks in the built structure down to their equivalent 1x1x1-building-block forms. The next step, compacting extruded ranges, is essentially the same algorithm as for eliminating duplicates from a sorted list, but in 3D:
For each axis d (X, Y, Z):
Set j = 1.
For i from 1 to the maximum co-ord in axis d:
Is the planar voxel "slice" of the built structure at co-ord i on axis d (e.g., if d is Y, then the set of voxels (x, i, z) for all x and z) identical to the immediately preceding "slice" at co-ord i-1?
If not, copy the slice at co-ord i on top of the slice at co-ord j, and then increment j.
This will produce a canonical version of the built structure in which all adjacent slices are different; typically this version will be much smaller, since all "long" features are collapsed to length 1. The role of j here is to point to the earliest location where we can put the next non-identical slice. Since j <= i always, we never have to worry about overwriting a slice we haven't processed yet. Also note that it doesn't matter in which order the directions are processed, the final result is the same.
The same canonicalisation process should have been applied to each template structure at the outset as preprocessing. Now the two canonical forms (template and built structure) can be compared directly via a brute-force voxel-by-voxel comparison (basically like strstr(), but looking for a cuboid inside a cuboid instead of a string inside a string). Any rotations or flips that should be considered valid transformations should also be tried at this point.
Features and caveats
Given the template
X.X
XXX
it will recognise e.g. the following as matches,
X.X
X.X XXX XX
X.X XXXXXXX
XXX XXXXXXX
but not e.g.
X..
X.X
X.X
XXX
But if you want to detect such U-shaped structures with different-length legs, you need only supply an additional template:
X..
X.X
XXX
This template will match all U-shaped structures with different-length legs (but not U-shaped structures with equal-length legs!). Depending on which rotations you consider, you may also need the mirror image.
Structures whose AABBs intersect won't be handled correctly. These can be separated easily enough in a prior step.
Interestingly enough, this algorithm is capable of recognising structures that comprise more than one connected component. For example, the template
X.X.X
will recognise three equal-size cuboids in a row (or column, if rotations are allowed).
I would write a function to check if a 1x1x1 area has a specific shape (full block, half block + rotation, edge block + rotation) and then define and check the pattern in this manner.

Draw arbitrary convex shape knowing the lengths of its sides

I've got a list of values, which are the lengths of the sides of an arbitrary convex shape (polygon).
How can I draw this shape? What algorithm can help me with this task?
For example, I have a list: 2, 5, 2, 3. The drawing has to look like this:
There is a relatively simple (if somewhat math heavy) O(N log N) to O(N^2) (depending on implementation) recursive geometry/trigonometry based solution to this.
The concept starts with a line segment with length equal to the sum of the lengths.
Break that line segment into a triangle (see related info near bottom).
Recursively break each edge of the triangle into more triangles as needed.
Step 2, requires ensuring that smaller two edges of the triangle are longer than the bigger one.
Step 3, can be done by turning a triangle into 2 triangles.
For the input and outputs I would use:
Input: List of edges
Output: list of interior angles.
So output[a] is the interior angle of the vertex either before after the edge at input[a].
A good reference is located here.
Method #1 gif, shows the triangles at for that many vertices.
Method #2 gif, P is an example of where the break might occur in step 2.
Method #4 gif, here P could be considered moved out like in #3, note that in this case, the line lengths would not be to scale and in fact would be unknown. Notice that only the vertex positions of a1 and a2 would change. Resulting in changes to the interior angles of the vertices before and after a1 and a2. In this case, a1,a2,a3,an,p.
As for determining the interior angles. Use trigonometry and/or geometry. Given 3 sides of a triangle, it's possible to determine what the angles are. Given 2 sides and an angle (or 1 angle and 2 sides) it's possible to determine the missing sides and angles.
Of course, you may have to be careful as to where you break the edge so a triangle can be formed.
I will quote here an answer I posted on MathOverflow:
A chain of edges can close iff the longest edge is not longer than the sum of the lengths of all the other edges.
In your example, the longest edge is 5, and it is not longer than 2+2+3=7.
If you replace the edge of length 5 by an edge of length 8, then the four segments
cannot close to a convex polygon.
Whenever you have more than 3 edges, the resulting convex polygon is not
uniquely determined: there is flexibility in its shape.
See the references cited above for pointers to proofs.

Fragment shader - drawing a line?

I was interested in how to draw a line with a specific width (or multiple lines) using a fragment shader. I stumbled on the this post which seems to explain it.
The challenge I have is understanding the logic behind it.
A couple of questions:
Our coordinate space in this example is (0.0-1.0,0.0-1.0), correct?
If so, what is the purpose of the "uv" variable. Since thickness is 500, the "uv" variable will be very small. Therefore the distances from it to pont 1 and 2 (stored in the a and b variables)?
Finally, what is the logic behind the h variable?
i will try to answer all of your questions one by one:
1) Yes, this is in fact correct.
2) It is common in 3d computer graphics to express coordinates(within certain boundaries) with floating-point values between 0 and 1(or between -1 and 1). First of all, this makes it quite easy to decide whether a given value crosses said boundary or not, and abstracts away from a concept of "pixel" being a discrete image unit; furthermore this common practise can be found pretty much everywhere else(think of device coordinates or texture coordinates)
Don't be afraid that values that you are working with are less than one; in fact, in computer graphics you usually deal with floating-point arithmetics, and FLOAT types are quite good at expressing Real values line around the "1" point.
3) The formula give for h consists of 2 parts: the square-root part, and the 2/c coefficient. The square root part should be well known from scholl math classes - this is Heron formula for the area of a triangle(between a,b,c). 2/c extracts the height of the said triangle, which is stored in h and is also the distance between point uv and the "ground line" of the triangle. This distance is then used to decide, where is uv in relation to the line p1-p2.

Algorithms for Collision Detection between Arbitrarily sized Convex Polygons

I am working on an asteroids clone. Everything is 2D, and written in C++.
For the asteroids, I am generating random N-sided polygons. I have guaranteed that they are Convex. I then rotate them, give them a rotspeed, and have them fly through space. It all works, and is very pretty.
For collision, I'm using an Algorithm I thought of myself. This is probably a bad idea, and if push comes to shove, I'll probably scrap the whole thing and find a tutorial on the internet.
I've written and implemented everything, and the collision detection works alright.... most of the time. It will randomly fail when there's obviously a collision on screen, and sometimes indicate collision when nothing is touching. Either I have flubbed my implementation somewhere, or my algorithm is horrible. Due to the size/scope of my implementation (over several source files) I didn't want to bother you with that, and just wanted someone to check that my algorithm is, in fact, sound. At that point I can go on a big bug hunt.
Algorithm:
For each Asteroid, I have a function that outputs where each vertex should be when drawing the asteroid. For each pair of adjacent Vertices, I generate the Formula for the line that they sit on, y=mx+b format. I then start with one of my ships vertices, testing that point to see whether it is inside the asteroid. I start by plugging in the X coordinate of the point, and comparing the output to the Actual Y value. This tells me if the point is above or below the line. I then do the same with the Center of the Asteroid, to determine which half of the line is considered "Inside" the asteroid. I then repeat for each pair of Vertices. IF I ever find a line for which my point is not on the same side as the center of the asteroid, I know there is no collision, and exit detection for that point. Since there are 3 points on my ship, I then have to test for the next point. If all 3 points exit early, then There are no collisions for any of the points on the ship, and we're done. If any point is bound on all sides by the lines made up by the asteroid, then it is inside the asteroid, and the collision flag is set.
The two Issues I've discovered with this algorithm is that:
it doesn't work on concave polygons, and
It has problems with an Edge case where the Slope is Undefined.
I have made sure all polygons are Convex, and have written code to handle the Undefined Slope issue (doubles SHOULD return NAN if we divide by 0, so it's pretty easy to test for that).
So, should this work?
The standard solution to this problem is using the separating axis theorem (SAT). Given two convex polygons, A and B, the algorithm basically goes like this:
for each normal N of the edges of A and B
intervalA = [min, max] of projecting A on N
intervalB = [min, max] of projecting B on N
if intervalA doesn't overlap intervalB
return did not collide
return collided
I did something similar to compute polygon intersections, namely finding if a vertex sits within a given polygon.
Your algorithm is sound, and indeed does not work for concave polys. The line representation you chose is also problematic at slopes approaching infinity. I chose to use a couple of vectors for mine, one for the line direction, and one for a reference point on the line. From these, I can easily derive a parameterized equation of the line, and use that in various ways to find intersections with other shapes.
P = S + t * D
Any point P of the line can be caracterized by its coordinate t on the the line, given the above relation, where S is the reference point, and D the direction vector.
This representation lets you easily define which parts of the plane is the positive and the negative one (ie. above and below the line), thanks to the direction orientation. Now, any region of the plane can be defined as an intersection of several lines' negative or positive subplanes. So your "point within polygon" algorithm could be slightly changed to use that representation, with the added constraint of all the direction pointing clockwise, and testing for the point being in the negative subplane of all the lines (so you don't need the centre of the polygon anymore).
The formula to compute the side of a point wrt a line I used is the following:
(xs - xp) * yd - (ys - yp) * xd
The slope issue appears here when point P is close to S.
That representation can be computed using the edge vertices, but in order to have correct subplanes, you must keep your vertices in your polygon in condecutive orders.
For concave polygons, the problem is a bit more complicated: briefly, you have to test that the point is between two consecutive convex edges. This can be achieved by checking the coordinate of the point on the edge when projected on it, and ensuring it stands between 0 and length(edge) (assuming that the direction is normalized). Note that it boils down to check if the point belongs to a triangle within the polygon.