grid.ts 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. /**
  2. * Copyright (c) 2018-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
  3. *
  4. * @author David Sehnal <david.sehnal@gmail.com>
  5. * @author Alexander Rose <alexander.rose@weirdbyte.de>
  6. */
  7. import { SpacegroupCell, Box3D, Sphere3D } from '../../mol-math/geometry';
  8. import { Tensor, Mat4, Vec3 } from '../../mol-math/linear-algebra';
  9. /** The basic unit cell that contains the grid data. */
  10. interface Grid {
  11. readonly transform: Grid.Transform,
  12. readonly cells: Tensor,
  13. readonly stats: Readonly<{
  14. min: number,
  15. max: number,
  16. mean: number,
  17. sigma: number
  18. }>
  19. }
  20. namespace Grid {
  21. export const One: Grid = {
  22. transform: { kind: 'matrix', matrix: Mat4.identity() },
  23. cells: Tensor.create(Tensor.Space([1, 1, 1], [0, 1, 2]), Tensor.Data1([0])),
  24. stats: { min: 0, max: 0, mean: 0, sigma: 0 },
  25. };
  26. export type Transform = { kind: 'spacegroup', cell: SpacegroupCell, fractionalBox: Box3D } | { kind: 'matrix', matrix: Mat4 }
  27. const _scale = Mat4.zero(), _translate = Mat4.zero();
  28. export function getGridToCartesianTransform(grid: Grid) {
  29. if (grid.transform.kind === 'matrix') {
  30. return Mat4.copy(Mat4(), grid.transform.matrix);
  31. }
  32. if (grid.transform.kind === 'spacegroup') {
  33. const { cells: { space } } = grid;
  34. const scale = Mat4.fromScaling(_scale, Vec3.div(Vec3.zero(), Box3D.size(Vec3.zero(), grid.transform.fractionalBox), Vec3.ofArray(space.dimensions)));
  35. const translate = Mat4.fromTranslation(_translate, grid.transform.fractionalBox.min);
  36. return Mat4.mul3(Mat4.zero(), grid.transform.cell.fromFractional, translate, scale);
  37. }
  38. return Mat4.identity();
  39. }
  40. export function areEquivalent(gridA: Grid, gridB: Grid) {
  41. return gridA === gridB;
  42. }
  43. export function isEmpty(grid: Grid) {
  44. return grid.cells.data.length === 0;
  45. }
  46. export function getBoundingSphere(grid: Grid, boundingSphere?: Sphere3D) {
  47. if (!boundingSphere) boundingSphere = Sphere3D();
  48. const dimensions = grid.cells.space.dimensions as Vec3;
  49. const transform = Grid.getGridToCartesianTransform(grid);
  50. return Sphere3D.fromDimensionsAndTransform(boundingSphere, dimensions, transform);
  51. }
  52. }
  53. export { Grid };