# 3D grid of lines

Hello! I was asked by someone on SO to post this as a demo here. Here’s a simple way to make a 3D grid of lines from a grid of points, using the `index` attribute of `BufferGeometry`.

The interesting bit is:

``````let xSize = 3;
let ySize = 4;
let zSize = 5;
let n = xSize * ySize * zSize;

let geometry = new THREE.BufferGeometry();

function mapTo3D(i) {
let z = Math.floor(i / (xSize * ySize));
i -= z * xSize * ySize;
let y = Math.floor(i / xSize);
let x = i % xSize;
return { x: x, y: y, z: z };
}

function mapFrom3D(x, y, z) {
return x + y * xSize + z * xSize * ySize;
}

let positions = [];
for (let i = 0; i < n; i++) {
let p = mapTo3D(i);
positions.push((p.x - xSize / 2) / xSize);
positions.push((p.y - ySize / 2) / ySize);
positions.push((p.z - zSize / 2) / zSize);
}
let positionAttribute = new THREE.Float32BufferAttribute(positions, 3);

let indexPairs = [];
for (let i = 0; i < n; i++) {
let p = mapTo3D(i);
if (p.x + 1 < xSize) {
indexPairs.push(i);
indexPairs.push(mapFrom3D(p.x + 1, p.y, p.z));
}
if (p.y + 1 < ySize) {
indexPairs.push(i);
indexPairs.push(mapFrom3D(p.x, p.y + 1, p.z));
}
if (p.z + 1 < zSize) {
indexPairs.push(i);
indexPairs.push(mapFrom3D(p.x, p.y, p.z + 1));
}
}
geometry.setIndex(indexPairs);
let lines = new THREE.LineSegments(geometry, new THREE.LineBasicMaterial());
``````

A dynamic 2D grid would be very similar (simpler).

One example of this being useful is this thing I made.

6 Likes

Hi!
Thanks for sharing

Just OOI, how would you turn this from a perspective to an orthographic view?

Just use `OrthographicCamera` instead of `PerspectiveCamera`. You’ll also want to turn off `sizeAttenuation` for `PointsMaterial`.

2 Likes

Thanks for the speedy reply. I need to play with the OthographicCamera positions to get something to actually show up and rotate with the mouse, but I can try that

FYI eventually I’d like to adapt this for drawing mathematical magic cubes.

(BTW there’s a typo in the PEN: `sizeAttentuation: false`)