diff --git a/src/mol-model/structure/model/model.ts b/src/mol-model/structure/model/model.ts index de0649f49d31dc0f95a416a90f45f387cf04e408..5c2a45a64744a1bea3489673a199f20b4d9a6f47 100644 --- a/src/mol-model/structure/model/model.ts +++ b/src/mol-model/structure/model/model.ts @@ -15,6 +15,8 @@ import { CustomProperties } from '../common/custom-property'; import { SecondaryStructure } from './properties/seconday-structure'; import { SaccharideComponentMap } from '../structure/carbohydrates/constants'; import { ModelFormat } from '../../../mol-model-formats/structure/format'; +import { calcModelCenter } from './util'; +import { Vec3 } from '../../../mol-math/linear-algebra'; /** * Interface to the "source data" of the molecule. @@ -75,4 +77,12 @@ export interface Model extends Readonly<{ export namespace Model { // TODO: is this enough? export type Trajectory = ReadonlyArray<Model> + + const CenterProp = '__Center__' + export function getCenter(model: Model): Vec3 { + if (model._dynamicPropertyData[CenterProp]) return model._dynamicPropertyData[CenterProp] + const center = calcModelCenter(model.atomicConformation, model.coarseConformation) + model._dynamicPropertyData[CenterProp] = center + return center + } } \ No newline at end of file diff --git a/src/mol-model/structure/model/util.ts b/src/mol-model/structure/model/util.ts new file mode 100644 index 0000000000000000000000000000000000000000..2793632f772a453cd2e41801d7b7f59697def1e4 --- /dev/null +++ b/src/mol-model/structure/model/util.ts @@ -0,0 +1,45 @@ +/** + * Copyright (c) 2019 mol* contributors, licensed under MIT, See LICENSE file for more info. + * + * @author Alexander Rose <alexander.rose@weirdbyte.de> + */ + +import { Vec3 } from '../../../mol-math/linear-algebra'; +import { AtomicConformation } from './properties/atomic'; +import { CoarseConformation } from './properties/coarse'; +import { arrayMinMax } from '../../../mol-util/array'; + +export function calcModelCenter(atomicConformation: AtomicConformation, coarseConformation?: CoarseConformation) { + let rangesX: number[] = [] + let rangesY: number[] = [] + let rangesZ: number[] = [] + + if (atomicConformation.x.length) { + rangesX.push(...arrayMinMax(atomicConformation.x)) + rangesY.push(...arrayMinMax(atomicConformation.y)) + rangesZ.push(...arrayMinMax(atomicConformation.z)) + } + + if (coarseConformation) { + if (coarseConformation.spheres.x.length) { + rangesX.push(...arrayMinMax(coarseConformation.spheres.x)) + rangesY.push(...arrayMinMax(coarseConformation.spheres.y)) + rangesZ.push(...arrayMinMax(coarseConformation.spheres.z)) + } + if (coarseConformation.gaussians.x.length) { + rangesX.push(...arrayMinMax(coarseConformation.gaussians.x)) + rangesY.push(...arrayMinMax(coarseConformation.gaussians.y)) + rangesZ.push(...arrayMinMax(coarseConformation.gaussians.z)) + } + } + + const [minX, maxX] = arrayMinMax(rangesX) + const [minY, maxY] = arrayMinMax(rangesY) + const [minZ, maxZ] = arrayMinMax(rangesZ) + + const x = minX + (maxX - minX) / 2 + const y = minY + (maxY - minY) / 2 + const z = minZ + (maxZ - minZ) / 2 + + return Vec3.create(x, y, z) +} \ No newline at end of file