Browse Source

add CentroidHelper utils .fromProvider and .fromPairProvider

Alexander Rose 5 years ago
parent
commit
2dd863e711

+ 47 - 9
src/mol-math/geometry/centroid-helper.ts

@@ -1,7 +1,8 @@
 /**
- * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2018-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author David Sehnal <david.sehnal@gmail.com>
+ * @author Alexander Rose <alexander.rose@weirdbyte.de>
  */
 
 import { Vec3 } from '../../mol-math/linear-algebra/3d';
@@ -12,7 +13,7 @@ export { CentroidHelper }
 class CentroidHelper {
     private count = 0;
 
-    center: Vec3 = Vec3.zero();
+    center: Vec3 = Vec3();
     radiusSq = 0;
 
     reset() {
@@ -46,21 +47,58 @@ class CentroidHelper {
 }
 
 namespace CentroidHelper {
-    const helper = new CentroidHelper(), p = Vec3.zero();
+    const helper = new CentroidHelper()
+    const posA = Vec3()
+    const posB = Vec3()
 
-    export function compute({ x, y, z }: { x: ArrayLike<number>, y: ArrayLike<number>, z: ArrayLike<number> }, to: Vec3) {
+    export function fromArrays({ x, y, z }: { x: ArrayLike<number>, y: ArrayLike<number>, z: ArrayLike<number> }, to: Sphere3D) {
         helper.reset();
         const n = x.length;
         for (let i = 0; i < n; i++) {
-            Vec3.set(p, x[i], y[i], z[i]);
-            helper.includeStep(p);
+            Vec3.set(posA, x[i], y[i], z[i]);
+            helper.includeStep(posA);
         }
         helper.finishedIncludeStep();
         for (let i = 0; i < n; i++) {
-            Vec3.set(p, x[i], y[i], z[i]);
-            helper.radiusStep(p);
+            Vec3.set(posA, x[i], y[i], z[i]);
+            helper.radiusStep(posA);
         }
-        Vec3.copy(to, helper.center);
+        Vec3.copy(to.center, helper.center);
+        to.radius = Math.sqrt(helper.radiusSq)
+        return to;
+    }
+
+    export function fromProvider(count: number, getter: (i: number, pos: Vec3) => void, to: Sphere3D) {
+        helper.reset();
+        for (let i = 0; i < count; i++) {
+            getter(i, posA)
+            helper.includeStep(posA);
+        }
+        helper.finishedIncludeStep();
+        for (let i = 0; i < count; i++) {
+            getter(i, posA)
+            helper.radiusStep(posA);
+        }
+        Vec3.copy(to.center, helper.center);
+        to.radius = Math.sqrt(helper.radiusSq)
+        return to;
+    }
+
+    export function fromPairProvider(count: number, getter: (i: number, posA: Vec3, posB: Vec3) => void, to: Sphere3D) {
+        helper.reset();
+        for (let i = 0; i < count; i++) {
+            getter(i, posA, posB)
+            helper.includeStep(posA);
+            helper.includeStep(posB);
+        }
+        helper.finishedIncludeStep();
+        for (let i = 0; i < count; i++) {
+            getter(i, posA, posB)
+            helper.radiusStep(posA);
+            helper.radiusStep(posB);
+        }
+        Vec3.copy(to.center, helper.center);
+        to.radius = Math.sqrt(helper.radiusSq)
         return to;
     }
 }

+ 3 - 2
src/mol-math/linear-algebra/3d/minimize-rmsd.ts

@@ -9,6 +9,7 @@ import Vec3 from './vec3';
 import { EVD } from '../matrix/evd';
 import { CentroidHelper } from '../../../mol-math/geometry/centroid-helper';
 import Matrix from '../matrix/matrix';
+import { Sphere3D } from '../../geometry/primitives/sphere3d';
 
 export { MinimizeRmsd };
 namespace MinimizeRmsd {
@@ -58,10 +59,10 @@ class RmsdTransformState {
         this.b = data.b;
 
         if (data.centerA) this.centerA = data.centerA;
-        else this.centerA = data.centerA = CentroidHelper.compute(data.a, Vec3.zero());
+        else this.centerA = data.centerA = CentroidHelper.fromArrays(data.a, Sphere3D()).center;
 
         if (data.centerB) this.centerB = data.centerB;
-        else this.centerB = data.centerB = CentroidHelper.compute(data.b, Vec3.zero());
+        else this.centerB = data.centerB = CentroidHelper.fromArrays(data.b, Sphere3D()).center;
 
         this.result = into;
     }

+ 7 - 28
src/mol-model/structure/structure/unit/bonds.ts

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2017-2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2017-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author David Sehnal <david.sehnal@gmail.com>
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
@@ -10,7 +10,6 @@ import Structure from '../structure';
 import { BondType } from '../../model/types';
 import { SortedArray, Iterator } from '../../../../mol-data/int';
 import { CentroidHelper } from '../../../../mol-math/geometry/centroid-helper';
-import { Vec3 } from '../../../../mol-math/linear-algebra';
 import { Sphere3D } from '../../../../mol-math/geometry';
 
 export * from './bonds/data'
@@ -223,32 +222,12 @@ namespace Bond {
         }
     }
 
-    //
-
-    const sphereHelper = new CentroidHelper()
-    const tmpPos = Vec3()
-
-    export function getBoundingSphere(loci: Loci, boundingSphere?: Sphere3D) {
-        if (!boundingSphere) boundingSphere = Sphere3D()
-        sphereHelper.reset();
-
-        for (const e of loci.bonds) {
-            e.aUnit.conformation.position(e.aUnit.elements[e.aIndex], tmpPos);
-            sphereHelper.includeStep(tmpPos);
-            e.bUnit.conformation.position(e.bUnit.elements[e.bIndex], tmpPos);
-            sphereHelper.includeStep(tmpPos);
-        }
-        sphereHelper.finishedIncludeStep();
-        for (const e of loci.bonds) {
-            e.aUnit.conformation.position(e.aUnit.elements[e.aIndex], tmpPos);
-            sphereHelper.radiusStep(tmpPos);
-            e.aUnit.conformation.position(e.bUnit.elements[e.bIndex], tmpPos);
-            sphereHelper.radiusStep(tmpPos);
-        }
-
-        Vec3.copy(boundingSphere.center, sphereHelper.center)
-        boundingSphere.radius = Math.sqrt(sphereHelper.radiusSq)
-        return boundingSphere
+    export function getBoundingSphere(loci: Loci, boundingSphere: Sphere3D) {
+        return CentroidHelper.fromPairProvider(loci.bonds.length, (i, pA, pB) => {
+            const { aUnit, aIndex, bUnit, bIndex } = loci.bonds[i]
+            aUnit.conformation.position(aUnit.elements[aIndex], pA)
+            bUnit.conformation.position(bUnit.elements[bIndex], pB)
+        }, boundingSphere)
     }
 }