| |
| |
| |
| |
| |
|
|
| export const CUBE = 0.72; |
| const PITCH = 1.0; |
|
|
| export function makeLayout(shape) { |
| const rank = shape.length; |
| const strides = new Array(rank); |
| const dimOf = new Array(rank); |
| const blockExtent = [CUBE, CUBE, CUBE]; |
|
|
| for (let i = 0; i < rank; i++) { |
| const sd = i % 3; |
| const level = Math.floor(i / 3); |
| const gap = level === 0 ? PITCH - CUBE : PITCH * (0.8 + 1.4 * level); |
| strides[i] = blockExtent[sd] + gap; |
| dimOf[i] = sd; |
| blockExtent[sd] = strides[i] * (shape[i] - 1) + blockExtent[sd]; |
| } |
|
|
| const center = blockExtent.map((e) => (e - CUBE) / 2); |
|
|
| function position(coord) { |
| const p = [0, 0, 0]; |
| for (let i = 0; i < rank; i++) p[dimOf[i]] += coord[i] * strides[i]; |
| return [p[0] - center[0], center[1] - p[1], p[2] - center[2]]; |
| } |
|
|
| |
| function axisCoord(coord, axis) { |
| return coord[axis]; |
| } |
|
|
| |
| |
| |
| |
| function screenOffset(axis, coord) { |
| const sd = dimOf[axis]; |
| const along = coord * strides[axis]; |
| return sd === 1 ? center[1] - along : along - center[sd]; |
| } |
|
|
| const radius = Math.hypot(...blockExtent) / 2; |
| return { |
| position, |
| axisCoord, |
| screenOffset, |
| strides, |
| dimOf, |
| center, |
| blockExtent, |
| radius, |
| rank, |
| }; |
| } |
|
|