Wednesday, February 6, 2013

The most important tool in M&S toolbox:

"All models are wrong, some of them are useful"
- George Box

3D Distance Function of a Rectangle

Signed distance functions are useful tools in solving many computer graphics and computational geometry problems. I use them to implement an enrichment technique to overcome some of the problems that I face when trying to reconstruct implicit surfaces. The technique is based on Barbieri et al.'s "A new weight-function enrichment in meshless methods for multiple cracks in linear elasticity" paper.

In my work, I use rectangular surfaces in the 3D space as the separating entity between two subsets of points. I don't want these two subsets to influence each other in weighted averaging operations, so I place a rectangular dividend in-between. Let's define a rectangle by these variables:
  • c : center of the rectangle
  • u, v : normalized vectors that define the extent direction of the rectangle from the center
  • eU, eV : extent values.
 For a given 3D point p, first I need to find the distance of p to the border of the rectangle on the rectangle's local coordinate system. In Mathematica code, this translates to:
d = p - c;
dist = Abs[Dot[d, u]] - eu;
du = Abs[dist] + dist;
dist = Abs[Dot[d, v]] - ev;
dv = Abs[dist] + dist;
Return[Sqrt[du^2 + dv^2]];
If I go deeper into this code, when I take the dot product of d with u and v, essentially I obtain the coordinate of the projection of p onto the plane that the rectangle lies on in terms of the rectangle's local coordinate system. Other absolute value stuff are there because I want the function to have a value of 0 inside the rectangle and a positive value outside of the rectangle. When I have the contour plot of this function with Mathematica, I obtain something like this:

 Now, I need to combine this information with the distance of the point to the rectangle in the rectangle's normal direction. This is simply achieved by taking the dot product of the d vector with the normalized normal vector of the rectangle.
s = Abs[Dot[d, n]];
Return[Sqrt[(du^2 + dv^2) + s^2]];
This results in the 3D distance function of an arbitrary rectangle:

Monday, January 28, 2013

#SitesILike: OverAPI CheatSheet Repository

OverAPI has obtained a mission to collect all information technology related cheat sheets into a single point. The technologies are ordered from A to Z. It is possible to find over 200 technologies, tools, applications, ...etc.

Monday, March 21, 2011

Rendering Regular Grids on XNA

First of all credits to the thought process and article of Dan Lecocq. In this very first post of my blog about this and that, I would like to keep things easy for me and provide an implementation of rendering regular 2D grids in XNA.

In my Grid class, I have the following class members:


// The 2-D array to hold the height values at grid points.
double[,] height;

// x-resolution and y-resolution of the 2D grid.
int xRes;
int yRes;

// the difference in x and y-direction of
// two successive grid points.
double xStep;
double yStep;

// Vertex position, color, and index arrays.
VertexPositionColor[] vertices;
int[] indices;


As you can guess, I have used XNA's DrawUserIndexedPrimitive method. The data is allocated in the constructor as follows:


public Grid(int nX, int nY, double x_Length, double y_Length)
{
height = new double[nX, nY];

xRes = nX;
yRes = nY;

xStep = x_Length / (double)nX;
yStep = y_Length / (double)nY;

vertices = new VertexPositionColor[xRes * yRes];
indices = new int[2 * xRes * (yRes - 1)];

InitVertexBuffer();
}


The real deal is initializing the vertex buffer, especially the index information.


private void InitVertexBuffer()
{
// First initialize vertex buffer
for (int j = 0; j < yRes; j++)
{
for (int i = 0; i < xRes; i++)
{
vertices[j * xRes + i] =
new VertexPositionColor(new Vector3((float)(i * xStep), (float)(j * yStep), (float)(height[i, j])),
new Color(0f, 0.9f, 0.9f, 0.6f)); // Of course give it any color you want...
}
}

// Now initialize indices
int index = 0;
for (int j = 0; j < yRes - 1; j++)
{
int toSub = j % 2 == 0 ? (xRes - 1) : (xRes + 1);

for (int i = 0; i < xRes; i++)
{
indices[j * 2 * xRes + i * 2] = index;
index += xRes;
indices[j * 2 * xRes + i * 2 + 1] = index;
index -= toSub;
}
index += toSub;
}
}


And finally, rendering of the grid:


public void DrawGrid(GraphicsDevice graphicsDevice)
{
graphicsDevice.DrawUserIndexedPrimitives
(PrimitiveType.TriangleStrip,
vertices,
0,
xRes * yRes,
indices,
0,
(xRes) * (yRes - 1) * 2 - 2);
}


So, you have setup your Game class, added your Grid class, and hit F5. What? Displaying strips instead of the whole grid? If I were you, I would check back face culling :).

That's it, hope it will help anyone out there!