Bladeren bron

calculate model center as dynamic prop

Alexander Rose 5 jaren geleden
bovenliggende
commit
da3acd9d19
2 gewijzigde bestanden met toevoegingen van 55 en 0 verwijderingen
  1. 10 0
      src/mol-model/structure/model/model.ts
  2. 45 0
      src/mol-model/structure/model/util.ts

+ 10 - 0
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
+    }
 }

+ 45 - 0
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)
+}