Design
A quad mesh on a regular grid is completely determined by a tiny
recipe: the grid dimension (nx, ny cells), the
extent (xmin, xmax, ymin, ymax), and the y orientation
(ydown). Everything in textures is a view of that recipe at
some level of materialization:
-
quad_spec()- the recipe itself, a plain serializable list, nothing materialized -
quad_edges()- the unexpanded intermediate, the x and y coordinates of the cell edges as two short vectors (nx + 1 and ny + 1 values) -
quad_index(),quad_vertex()- the materialized components, the 4 x (nx * ny) vertex index and the expanded vertex coordinates -
quad_mesh(),quad(),quad_texture()- assembled ‘mesh3d’ objects
‘mesh3d’ objects are constructed directly (rgl is not required, it
lives in Suggests). With rgl installed they plot with
plot3d(), shade3d(), persp3d(),
wire3d(), or dot3d(), and
as.mesh3d() works on a quad_spec via delayed S3
registration. A 2D base graphics plot() method is
included.
Conventions
- Default extent is the unit square, “y-up” (y begins at 0).
- Quads are emitted in cell order, x fastest - the
matrix()/image()convention, and raster cell order whenydown = TRUE. Face-indexed values (colours,na.rm) align with grid cell order. - Quad vertex winding is counter-clockwise, as required by rgl (see
material3dbackargument). -
ydownflips the orientation so y coordinates begin at the top and count down, and rotates the index cycle so winding remains correct. - Texture coordinates are the extent-normalized vertex coordinates, so
they remain valid for any mesh whose vertices lie in the extent. Mesh
density (
dimension) is independent of the pixel dimension of a texture image: a coarse mesh may carry a full-resolution image, the graphics engine interpolates within each quad. - Coordinate transformation belongs outside the core: the mesh vertex matrix is the interchange, transform it (e.g. with reproj) and the texture drapes unchanged.
Large grids
quad_index() returns integer storage where it fits, and
transparently promotes to double storage (exact for integer values to
2^53) when the vertex count or index length exceeds the integer maximum.
R subsetting and ‘mesh3d’ use accept double indexes natively; take care
not to apply as.integer() to such an index. The compact
spec and the edges intermediate are the escape hatch when full
materialization is not wanted at all.
Headers
inst/include/textures/quad.h, namespace
quad, installed so that other packages may generate mesh
components via LinkingTo: textures:
cpp11::writable::integers quad_ib(int nx, int ny, bool ydown)
cpp11::writable::doubles quad_ib_dbl(double nx, double ny, bool ydown)
cpp11::writable::doubles quad_vb(int nx, int ny, bool ydown, bool zh)
cpp11::writable::doubles_matrix<> quad_matrix_vb(int nx, int ny, bool ydown, bool zh)quad_ib and quad_vb return flat vectors (4
values per quad, and interleaved x, y with optional constant z and
homogeneous h), quad_matrix_vb returns the matrix form.