I am working on some C# code in which I would like to take a 2D rectangle and split it to smaller 2D polygons. I would like the effect to look like the rectangle was made of glass and it was hit with a hammer in a random spot. I was wondering if anyone knows of a good algorithm to help me with this. I have tried the FortuneVoronoi code using random points to simulate this effect but am having a hard time turning the finished VoronoiGraph in to a set of non intersecting polygons in a reasonable amount of CPU time.
Since you mention Voronoi diagrams, I'd go for a Centroidal Voronoi diagram built using a radial density function that is concretated on the point of impact plus some jittering to add a bit of realism. See this page and this paper.
Related
Now I know mesh simplification has been something people have been studying for years, but I dont really need the sort of simplification you may be thinking. I have been working on a game which makes heavy uses of procedural meshes. One of the algorithms im using has a flaw, a big flaw, It creates a ton of artifact triangles in the mesh. For example if I had a flat square plane, and performed this algorithm on it, it would still be a flat square plane, but thousands to millions of useless triangles got added.
So my question is how can I simplify a mesh by collapsing useless triangles, I dont care to reduce overall polygon count, simply to remove triangles that are all on flat surfaces and are 100% useless.
Heres a example picture of the problem, its a flat side of a cube. This picture should pretty clearly describe the problem. Im using Unity and c#.
I have done a ton of research and I keep hearing about Edge Collapse but I cant find anything specifically on this case. Is Edge collapse the correct method to use? and if so how could I go about implementing it in a situation like this? All existing methods use it to do your usual mesh simplification.
Update:
Heres a short clip showing the Before and After mesh's
I would not suggest edge collapse here. What I would do is :
Compute the normal of each triangle and do a classification in several clusters (lists of triangles) that share same plane (=same normal and same distance to origin) .
For each cluster, make a classification in subclusters of triangles that are connected (or overlapping, because it seems that your image has overlaps)
For each subcluster, compute the boundary. Or the convex hull if you have overlapping triangles.
Optative step : check for 3 or more consecutive vertex in the boundary that are aligned, and remove intermediate vertex.
Triangulate the boundary. This is trivial for convex hull, and easy for non-convex boundary.
Exchange all triangles in the subcluster with the triangles of step 4.
The trivial convex hull triangulation consist in choosing an edge and create triangles with that edge and every else vertex in the hull.
I have an application I'm working on that requires a fair amount of 3D graphics programming. I have a series of lines that create both text and 3D cylindrical holes (see images).
I would like to be able to click and drag the objects in question using my mouse through the X,Y plane (Z constant). My understanding is that in order for the bounding boxes to be setup correctly, I have to have everything in using 3D polygons (triangles). I would like to be able to do collision detection without this conversion. Is this possible? If I must convert, can anyone point me to a piece of code that does this rather painlessly?
You can treat each line segment as a cylinder, and check them for collision.
Here's the math, as well as more alternatives.
I have some images that I'd like to draw a polyon around the outer edges. The images themselves are on transparent backgrounds and I've created an array of the pixels in the images which contain a point and are not transparent (or white).
Now, my question is: how do I draw an accurate polygon around the outer edge points? I've used a Graham Scan algorithm that I read about to create a convex hull around the edges but this doesn't seem to work for objects with concavities. For example:
http://i48.tinypic.com/4s0lna.png
The image on the left gets filled in using this method with the one on the right. As you can see, it's 'filling in' a little too much.
I assume there must be some other algorithm or approach that can be used to solve this, but I'm not sure of where to look or what it might be called. Could anyone point me in the right direction? I'm using C#/.net and hopefully there might be something that already exists which could work along these lines.
I think the 2D "Alpha shapes" algorithm would the right choice for you.
http://www.cgal.org/Manual/latest/doc_html/cgal_manual/Alpha_shapes_2/Chapter_main.html
Alpha shapes can be considered as a generalization for the "convex Hull" algorithm that allows for generation of more general shapes.
By using alpha shapes you will be having control over the level of details to be captured by the resultant shape by changing the alpha parameter value.
You can try the java applet here : http://cgm.cs.mcgill.ca/~godfried/teaching/projects97/belair/alpha.html
to have better understanding about does this algorithm do.
You can start on a pixel by pixel level, using a flood-fill approach.
Start in the corner, checking that it does have zero alpha.
Check the neighbours for zero alpha and iterate until we have no unchecked neighhours.
This gives you a mask for the image which will consist of two simply connected regions, the interior and exterior.
The set you seek then consists of:
all the points in the exterior which are on the boundary of the interior.
You can then turn that into a polygon by:
Take an initial polygon that consists of all the points in the edge set
Remove redundant vertices that lie along straight edges.
I'm making a game in C# and XNA, and I was trying to come up with a method to render massive terrains without using a tremendous amount of memory or passing the poly limit hard-coded into XNA.
My solution so far is to create a massive heightmap, and that heightmap is loaded into memory at the beginning of the game in the initialization phase. Then, terrain is only generated nearest to the camera. This is accomplished by projecting a triangle whose vertex is the character and the other two endpoints extend to the sides of the character's viewing area. Then, all the pixels inside that triangle on the heightmap are rendered and drawn into the game, thus only rendering what is seen.
The problem is, I've successfully found (I think, can't test until I get terrain rendering) the three vertices of the triangle. Now I need to find a list of the coordinates for every single pixel inside that triangle - whole numbers only, because I just need a list of pixels to render.
I know it sounds a little confusing, so here's the gist of it:
I have an image, and I project a triangle onto that image. The only thing I know about that triangle are the three vertices. I need a list of the pixels inside that triangle.
I've been Googling around for maybe 20 minutes now, and I figured I midas well go ahead and post something here due to the fact that what I'm trying to do isn't all that common. If I find an answer, I'll be sure to post it here.
But until then, can anyone tell me how to accomplish this?
Edit: A formula, please. If you can provide a formula or algorithm, and an explanation, that would be just perfect.
Edit: I've posted a new question, as I've ditched this method of rendering large terrains. The question is here.
Start here:
http://mathworld.wolfram.com/TriangleInterior.html
One of the non-trivial problems, not mentioned there, that you have to deal with is the pixelization along the boundary.
I'm trying to draw a polygon using c# and directx
All I get is an ordered list of points from a file and I need to draw the flat polygon in a 3d world.
I can load the points and draw a convex shape using a trianglefan and drawuserprimitives.
This obviously leads to incorrect results when the polygon is very concave (which it may be).
I can't imagine I'm the only person to grapple with this problem (tho I'm a gfx/directx neophyte - my background is in gui\windows application development).
Can anyone point me towards a simple to follow resource\tutorial\algorithm which may assist me?
Direct3D can only draw triangles (well, it can draw lines and points as well, but that's besides the point). So if you want to draw any shape that is more complex than a triangle, you have to draw a bunch of touching triangles that equal to that shape.
In your case, it's a concave polygon triangulation problem. Given a bunch of vertices, you can keep them as is, you just need to compute the "index buffer" (in simplest case, three indices per triangle that say which vertices the triangle uses). Then draw that by putting into vertex/index buffers or using DrawUserPrimitives.
Some algorithms for triangulating simple (convex or concave, but without self-intersections or holes) polygons are at VTerrain site.
I have used Ratcliff's code in the past; very simple and works well. VTerrain has a dead link to it; the code can be found here. It's C++, but porting that over to C# should be straightforward.
Oh, and don't use triangle fans. They are of very limited use, inefficient and are going away soon (e.g. Direct3D 10 does not support them anymore). Just use triangle lists.
If you are able to use the stencil buffer, it should not be hard to do. Here's a general algorithm:
Clear the stencil buffer to 1.
Pick an arbitrary vertex v0, probably somewhere near the polygon to reduce floating-point errors.
For each vertex v[i] of the polygon in clockwise order:
let s be the segment v[i]->v[i+1] (where i+1 will wrap to 0 when the last vertex is reached)
if v0 is to the "right" of s:
draw a triangle defined by v0, v[i], v[i+1] that adds 1 to the stencil buffer
else
draw a triangle defined by v0, v[i], v[i+1] that subtracts 1 from the stencil buffer
end for
fill the screen with the desired color/texture, testing for stencil buffer values >= 2.
By "right of s" I mean from the perspective of someone standing on v[i] and facing v[i+1]. This can be tested by using a cross product:
cross(v0 - v[i], v[i+1] - v[i]) > 0
Triangulation is he obvious answer, but it's hard to write a solid triangulator. Unless you have two month time to waste don't even try it.
There are a couple of codes that may help you:
The GPC Library. Very easy to use, but you may not like it's license:
http://www.cs.man.ac.uk/~toby/alan/software/gpc.html
There is also triangle:
http://www.cs.cmu.edu/~quake/triangle.html
And FIST:
http://www.cosy.sbg.ac.at/~held/projects/triang/triang.html
Another (and my prefered) option would be to use the GLU tesselator. You can load and use the GLU library from DirectX programs just fine. It does not need an OpenGL context to use it and it's pre-installed on all windows machines. If you want source you can lift off the triangulation code from the SGI reference implementation. I did that once and it took me just a couple of hours.
So far for triangulation. There is a different way as well: You can use stencil tricks.
The general algorithm goes like this:
Disable color- and depth writes. Enable stencil writes and setup your stencil buffer that it will invert the current stencil value. One bit of stencil is sufficient. Oh - your stencil buffer should be cleared as well.
Pick a random point on the screen. Any will do. Call this point your Anchor.
For each edge of your polygon build a triangle from the two vertices that build the edge and your anchor. Draw that triangle.
Once you've drawn all these triangles, turn off stencil write, turn on stencil test and color-write and draw a fullscreen quad in your color of choice. This will fill just the pixels inside your convex polygon.
It's a good idea to place the anchor into the middle of the polygon and just draw a rectangle as large as the boundary box of your polygon. That saves a bit of fillrate.
Btw - the stencil technique works for self-intersecting polygons as well.
Hope it helps,
Nils
I just had to do this for a project. The simplest algorithm I found is called "Ear Clipping". A great paper on it is here: TriangulationByEarClipping.pdf
I took me about 250 lines of c++ code and 4 hours to implement the brute force version of it. Other algorithms have better performance, but this was simple to implement and understand.