Title: Draw a 3D surface overlaid with a grid using WPF and C#
This example shows how to use C# code and XAML to draw a 3D surface overlaid with a grid. The example Apply textures to triangles using WPF and C# shows how to apply textures to triangles. This example simply uses that technique to apply a bitmap holding a large grid to a surface.
At the class level, the program uses the following code to define scale factors that map a point's X and Z coordinates to the range 0.0 - 1.0.
private const double texture_xscale = (xmax - xmin);
private const double texture_zscale = (zmax - zmin);
The following code shows how the program adds a new point to the 3D model.
// A dictionary to hold points for fast lookup.
private Dictionary<Point3D, int> PointDictionary =
new Dictionary<Point3D, int>();
// If the point already exists, return its index.
// Otherwise create the point and return its new index.
private int AddPoint(Point3DCollection points,
PointCollection texture_coords, Point3D point)
{
// If the point is in the point dictionary,
// return its saved index.
if (PointDictionary.ContainsKey(point))
return PointDictionary[point];
// We didn't find the point. Create it.
points.Add(point);
PointDictionary.Add(point, points.Count - 1);
// Set the point's texture coordinates.
texture_coords.Add(
new Point(
(point.X - xmin) * texture_xscale,
(point.Z - zmin) * texture_zscale));
// Return the new point's index.
return points.Count - 1;
}
As in earlier examples, the code defines a dictionary to hold Points so it can look them up quickly. The AddPoint method looks up a point and adds it if it doesn't already exists. It then uses the point's X and Z coordinates to map the point to the 0.0 - 1.0 range of the U-V coordinates used by the object's texture. In other words, points with the smallest X/Z coordinates are mapped to U/V coordinates near (0, 0) and points with the largest X/Z coordinates are mapped to U/V coordinates near (1, 1).
After it creates the triangles, the program uses the following code to create its material.
// Make the surface's material using an image brush.
ImageBrush grid_brush = new ImageBrush();
grid_brush.ImageSource =
new BitmapImage(new Uri("Grid.png", UriKind.Relative));
DiffuseMaterial grid_material = new DiffuseMaterial(grid_brush);
The file Grid.png simply contains a 513×513 pixel grid. Alternatively you could create the grid in code. A third approach would be to use partial derivatives to figure out where the lines should be drawn and then use skinny rectangles or boxes to draw them on top of the surface. (A later post will explain how to draw skinny boxes.) That would be a LOT more work, however.
I know these examples omit a huge amount of detail. They build on each other so you've seen the key points in earlier posts. The details are also fairly long so, to save space, I'm not going to include them in every post.
|
Download the example to experiment with it and to see additional details.
|