Browse Source

add Axes3D

Alexander Rose 5 years ago
parent
commit
a36ead9ef1

+ 4 - 2
src/mol-math/geometry.ts

@@ -1,7 +1,8 @@
 /**
- * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2018-2019 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>
  */
 
 export * from './geometry/common'
@@ -10,4 +11,5 @@ export * from './geometry/spacegroup/construction'
 export * from './geometry/lookup3d/common'
 export * from './geometry/lookup3d/grid'
 export * from './geometry/primitives/box3d'
-export * from './geometry/primitives/sphere3d'
+export * from './geometry/primitives/sphere3d'
+export * from './geometry/primitives/axes3d'

+ 63 - 0
src/mol-math/geometry/primitives/axes3d.ts

@@ -0,0 +1,63 @@
+/**
+ * Copyright (c) 2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ *
+ * @author Alexander Rose <alexander.rose@weirdbyte.de>
+ */
+
+import { Vec3, Mat4, Mat3 } from '../../linear-algebra'
+
+interface Axes3D { origin: Vec3, dirA: Vec3, dirB: Vec3, dirC: Vec3 }
+
+function Axes3D() {
+    return Axes3D.empty();
+}
+
+namespace Axes3D {
+    export function create(origin: Vec3, dirA: Vec3, dirB: Vec3, dirC: Vec3): Axes3D { return { origin, dirA, dirB, dirC } }
+    export function empty(): Axes3D { return { origin: Vec3(), dirA: Vec3(), dirB: Vec3(), dirC: Vec3() } }
+
+    export function copy(out: Axes3D, a: Axes3D): Axes3D {
+        Vec3.copy(out.origin, a.origin);
+        Vec3.copy(out.dirA, a.dirA);
+        Vec3.copy(out.dirB, a.dirB);
+        Vec3.copy(out.dirC, a.dirC);
+        return out;
+    }
+
+    export function clone(a: Axes3D): Axes3D {
+        return copy(empty(), a);
+    }
+
+    /** Get size of each direction */
+    export function size(size: Vec3, axes: Axes3D): Vec3 {
+        return Vec3.set(size, Vec3.magnitude(axes.dirA) * 2, Vec3.magnitude(axes.dirB) * 2, Vec3.magnitude(axes.dirC) * 2);
+    }
+
+    const tmpSizeV = Vec3()
+    /** Get volume of the oriented box wrapping the axes */
+    export function volume(axes: Axes3D): number {
+        size(tmpSizeV, axes)
+        return tmpSizeV[0] * tmpSizeV[1] * tmpSizeV[2]
+    }
+
+    export function normalize(out: Axes3D, a: Axes3D) {
+        Vec3.copy(out.origin, a.origin)
+        Vec3.normalize(out.dirA, a.dirA)
+        Vec3.normalize(out.dirB, a.dirB)
+        Vec3.normalize(out.dirC, a.dirC)
+        return out;
+    }
+
+    const tmpTransformMat3 = Mat3.zero()
+    /** Transform axes with a Mat4 */
+    export function transform(out: Axes3D, a: Axes3D, m: Mat4): Axes3D {
+        Vec3.transformMat4(out.origin, a.origin, m)
+        const n = Mat3.directionTransform(tmpTransformMat3, m)
+        Vec3.transformMat3(out.dirA, a.dirA, n)
+        Vec3.transformMat3(out.dirB, a.dirB, n)
+        Vec3.transformMat3(out.dirC, a.dirC, n)
+        return out
+    }
+}
+
+export { Axes3D }

+ 6 - 3
src/mol-math/geometry/primitives/box3d.ts

@@ -19,13 +19,16 @@ namespace Box3D {
     export function create(min: Vec3, max: Vec3): Box3D { return { min, max }; }
     export function empty(): Box3D { return { min: Vec3(), max: Vec3() }; }
 
-    export function clone(a: Box3D): Box3D {
-        const out = empty();
+    export function copy(out: Box3D, a: Box3D): Box3D {
         Vec3.copy(out.min, a.min);
         Vec3.copy(out.max, a.max);
         return out;
     }
 
+    export function clone(a: Box3D): Box3D {
+        return copy(empty(), a);
+    }
+
     export function computeBounding(data: PositionData): Box3D {
         const min = Vec3.create(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE);
         const max = Vec3.create(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE);
@@ -49,7 +52,7 @@ namespace Box3D {
     }
 
     const tmpSizeV = Vec3()
-    /** Get size of the box */
+    /** Get volume of the box */
     export function volume(box: Box3D): number {
         size(tmpSizeV, box)
         return tmpSizeV[0] * tmpSizeV[1] * tmpSizeV[2]

+ 7 - 0
src/mol-math/geometry/primitives/sphere3d.ts

@@ -10,6 +10,7 @@ import { PositionData } from '../common'
 import { OrderedSet } from '../../../mol-data/int';
 import { NumberArray } from '../../../mol-util/type-helpers';
 import { Box3D } from './box3d';
+import { Axes3D } from './axes3d';
 
 interface Sphere3D { center: Vec3, radius: number }
 
@@ -87,6 +88,12 @@ namespace Sphere3D {
         return out
     }
 
+    export function fromAxes3D(out: Sphere3D, axes: Axes3D) {
+        Vec3.copy(out.center, axes.origin)
+        out.radius = Math.max(Vec3.magnitude(axes.dirA), Vec3.magnitude(axes.dirB), Vec3.magnitude(axes.dirC))
+        return out
+    }
+
     const tmpAddVec3 = Vec3()
     export function addVec3(out: Sphere3D, s: Sphere3D, v: Vec3) {
         const d = Vec3.distance(s.center, v)