浏览代码

added EPOS for bounding sphere calculation

Alexander Rose 5 年之前
父节点
当前提交
9cffce55c9
共有 2 个文件被更改,包括 89 次插入6 次删除
  1. 8 6
      src/mol-gl/renderable/util.ts
  2. 81 0
      src/mol-math/geometry/epos-helper.ts

+ 8 - 6
src/mol-gl/renderable/util.ts

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2018-2019 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 Alexander Rose <alexander.rose@weirdbyte.de>
  */
@@ -7,6 +7,7 @@
 import { Sphere3D } from '../../mol-math/geometry'
 import { Vec3 } from '../../mol-math/linear-algebra'
 import { BoundaryHelper } from '../../mol-math/geometry/boundary-helper';
+import { Epos14 } from '../../mol-math/geometry/epos-helper';
 
 export function calculateTextureInfo (n: number, itemSize: number) {
     const sqN = Math.sqrt(n)
@@ -79,20 +80,21 @@ export function printImageData(imageData: ImageData, scale = 1, pixelated = fals
 
 const v = Vec3.zero()
 const boundaryHelper = new BoundaryHelper()
+const eposHelper = Epos14()
 
 export function calculateInvariantBoundingSphere(position: Float32Array, positionCount: number, stepFactor: number): Sphere3D {
     const step = stepFactor * 3
-    boundaryHelper.reset(0)
+    eposHelper.reset()
     for (let i = 0, _i = positionCount * 3; i < _i; i += step) {
         Vec3.fromArray(v, position, i)
-        boundaryHelper.boundaryStep(v, 0)
+        eposHelper.includeStep(v)
     }
-    boundaryHelper.finishBoundaryStep()
+    eposHelper.finishedIncludeStep()
     for (let i = 0, _i = positionCount * 3; i < _i; i += step) {
         Vec3.fromArray(v, position, i)
-        boundaryHelper.extendStep(v, 0)
+        eposHelper.radiusStep(v)
     }
-    return boundaryHelper.getSphere()
+    return eposHelper.getSphere()
 }
 
 export function calculateTransformBoundingSphere(invariantBoundingSphere: Sphere3D, transform: Float32Array, transformCount: number): Sphere3D {

+ 81 - 0
src/mol-math/geometry/epos-helper.ts

@@ -0,0 +1,81 @@
+/**
+ * Copyright (c) 2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ *
+ * @author Alexander Rose <alexander.rose@weirdbyte.de>
+ */
+
+import { Vec3 } from '../linear-algebra/3d';
+import { CentroidHelper } from './centroid-helper';
+
+// implementing http://www.ep.liu.se/ecp/034/009/ecp083409.pdf
+
+export class EposHelper {
+    private minDist: number[] = []
+    private maxDist: number[] = []
+    private extrema: Vec3[] = []
+    private centroidHelper = new CentroidHelper()
+
+    private computeExtrema(i: number, p: Vec3) {
+        const d = Vec3.dot(this.dir[i], p)
+
+        if (d < this.minDist[i]) {
+            this.minDist[i] = d
+            Vec3.copy(this.extrema[i * 2], p)
+        }
+        if (d > this.maxDist[i]) {
+            this.maxDist[i] = d
+            Vec3.copy(this.extrema[i * 2 + 1], p)
+        }
+    }
+
+    includeStep(p: Vec3) {
+        for (let i = 0, il = this.dir.length; i < il; ++i) {
+            this.computeExtrema(i, p)
+        }
+    }
+
+    finishedIncludeStep() {
+        for (let i = 0; i < this.extrema.length; i++) {
+            this.centroidHelper.includeStep(this.extrema[i]);
+        }
+        this.centroidHelper.finishedIncludeStep();
+    }
+
+    radiusStep(p: Vec3) {
+        this.centroidHelper.radiusStep(p);
+    }
+
+    getSphere() {
+        return this.centroidHelper.getSphere();
+    }
+
+    reset() {
+        for (let i = 0, il = this.dir.length; i < il; ++i) {
+            this.minDist[i] = Infinity
+            this.maxDist[i] = -Infinity
+            this.extrema[i * 2] = Vec3()
+            this.extrema[i * 2 + 1] = Vec3()
+        }
+        this.centroidHelper.reset()
+    }
+
+    constructor(private dir: Vec3[]) {
+        this.reset()
+    }
+}
+
+const DirEpos6 = [
+    Vec3.create(1, 0, 0), Vec3.create(0, 1, 0), Vec3.create(0, 0, 1)
+]
+export function Epos6() {
+    return new EposHelper(DirEpos6)
+}
+
+const DirEpos14 = [
+    Vec3.create(1, 0, 0), Vec3.create(0, 1, 0), Vec3.create(0, 0, 1),
+    Vec3.create(1/3, 1/3, 1/3), Vec3.create(-1/3, 1/3, 1/3),
+    Vec3.create(-1/3, -1/3, 1/3), Vec3.create(1/3, -1/3, 1/3)
+]
+export function Epos14() {
+    return new EposHelper(DirEpos14)
+}