Skip to content
Snippets Groups Projects
Commit 51ef3f36 authored by David Sehnal's avatar David Sehnal
Browse files

Add "radius" property to conformation

parent a9127093
No related branches found
No related tags found
No related merge requests found
...@@ -54,16 +54,17 @@ namespace SymmetryOperator { ...@@ -54,16 +54,17 @@ namespace SymmetryOperator {
readonly position: CoordinateMapper, readonly position: CoordinateMapper,
x(index: number): number, x(index: number): number,
y(index: number): number, y(index: number): number,
z(index: number): number z(index: number): number,
r(index: number): number
} }
export interface Coordinates { x: ArrayLike<number>, y: ArrayLike<number>, z: ArrayLike<number> } export interface Coordinates { x: ArrayLike<number>, y: ArrayLike<number>, z: ArrayLike<number> }
export function createMapping(operator: SymmetryOperator, coords: Coordinates): ArrayMapping { export function createMapping(operator: SymmetryOperator, coords: Coordinates, radius: ((index: number) => number) | undefined): ArrayMapping {
const invariantPosition = SymmetryOperator.createCoordinateMapper(SymmetryOperator.Default, coords); const invariantPosition = SymmetryOperator.createCoordinateMapper(SymmetryOperator.Default, coords);
const position = operator.isIdentity ? invariantPosition : SymmetryOperator.createCoordinateMapper(operator, coords); const position = operator.isIdentity ? invariantPosition : SymmetryOperator.createCoordinateMapper(operator, coords);
const { x, y, z } = createProjections(operator, coords); const { x, y, z } = createProjections(operator, coords);
return { operator, invariantPosition, position, x, y, z }; return { operator, invariantPosition, position, x, y, z, r: radius ? radius : _zeroRadius };
} }
export function createCoordinateMapper(t: SymmetryOperator, coords: Coordinates): CoordinateMapper { export function createCoordinateMapper(t: SymmetryOperator, coords: Coordinates): CoordinateMapper {
...@@ -74,6 +75,8 @@ namespace SymmetryOperator { ...@@ -74,6 +75,8 @@ namespace SymmetryOperator {
export { SymmetryOperator } export { SymmetryOperator }
function _zeroRadius(i: number) { return 0; }
interface Projections { x(index: number): number, y(index: number): number, z(index: number): number } interface Projections { x(index: number): number, y(index: number): number, z(index: number): number }
function createProjections(t: SymmetryOperator, coords: SymmetryOperator.Coordinates): Projections { function createProjections(t: SymmetryOperator, coords: SymmetryOperator.Coordinates): Projections {
......
...@@ -324,22 +324,12 @@ namespace Structure { ...@@ -324,22 +324,12 @@ namespace Structure {
} }
const distVec = Vec3.zero(); const distVec = Vec3.zero();
function atomicOrGaussianDistance(u: Unit.Atomic | Unit.Gaussians, p: Vec3, r: number) { function unitElementMinDistance(unit: Unit, p: Vec3, eRadius: number) {
const { elements, conformation } = u; const { elements, conformation: { position, r } } = unit, dV = distVec;
let minD = Number.MAX_VALUE; let minD = Number.MAX_VALUE;
for (let i = 0, _i = elements.length; i < _i; i++) { for (let i = 0, _i = elements.length; i < _i; i++) {
const d = Vec3.distance(p, conformation.position(elements[i], distVec)) - r; const e = elements[i];
if (d < minD) minD = d; const d = Vec3.distance(p, position(e, dV)) - eRadius - r(e);
}
return minD;
}
function sphereDistance(u: Unit.Spheres, p: Vec3, r: number) {
const { elements, conformation } = u;
const radius = u.coarseConformation.radius;
let minD = Number.MAX_VALUE;
for (let i = 0, _i = elements.length; i < _i; i++) {
const d = Vec3.distance(p, conformation.position(elements[i], distVec)) - r - radius[elements[i]];
if (d < minD) minD = d; if (d < minD) minD = d;
} }
return minD; return minD;
...@@ -347,19 +337,10 @@ namespace Structure { ...@@ -347,19 +337,10 @@ namespace Structure {
export function minDistanceToPoint(s: Structure, point: Vec3, radius: number) { export function minDistanceToPoint(s: Structure, point: Vec3, radius: number) {
const { units } = s; const { units } = s;
let minD = Number.MAX_VALUE, d = 0; let minD = Number.MAX_VALUE;
for (let i = 0, _i = units.length; i < _i; i++) { for (let i = 0, _i = units.length; i < _i; i++) {
const unit = units[i]; const unit = units[i];
switch (unit.kind) { const d = unitElementMinDistance(unit, point, radius);
case Unit.Kind.Atomic:
// TODO: assign radius to gaussian elements?
case Unit.Kind.Gaussians:
d = atomicOrGaussianDistance(unit, point, radius);
break;
case Unit.Kind.Spheres:
d = sphereDistance(unit, point, radius);
break;
}
if (d < minD) minD = d; if (d < minD) minD = d;
} }
return minD; return minD;
...@@ -370,30 +351,16 @@ namespace Structure { ...@@ -370,30 +351,16 @@ namespace Structure {
if (a.elementCount === 0 || b.elementCount === 0) return 0; if (a.elementCount === 0 || b.elementCount === 0) return 0;
const { units } = a; const { units } = a;
let minD = Number.MAX_VALUE, d = 0; let minD = Number.MAX_VALUE;
for (let i = 0, _i = units.length; i < _i; i++) { for (let i = 0, _i = units.length; i < _i; i++) {
const unit = units[i]; const unit = units[i];
const { elements, conformation } = unit; const { elements, conformation: { position, r } } = unit;
for (let i = 0, _i = elements.length; i < _i; i++) {
switch (unit.kind) { const e = elements[i];
case Unit.Kind.Atomic: const d = minDistanceToPoint(b, position(e, distPivot), r(e));
// TODO: assign radius to gaussian elements? if (d < minD) minD = d;
case Unit.Kind.Gaussians:
for (let i = 0, _i = elements.length; i < _i; i++) {
const d = minDistanceToPoint(b, conformation.position(elements[i], distPivot), 0);
if (d < minD) minD = d;
}
break;
case Unit.Kind.Spheres:
const radius = unit.coarseConformation.radius;
for (let i = 0, _i = elements.length; i < _i; i++) {
const d = minDistanceToPoint(b, conformation.position(elements[i], distPivot), radius[elements[i]]);
if (d < minD) minD = d;
}
break;
} }
if (d < minD) minD = d;
} }
return minD; return minD;
} }
......
...@@ -29,9 +29,9 @@ namespace Unit { ...@@ -29,9 +29,9 @@ namespace Unit {
export function create(id: number, kind: Kind, model: Model, operator: SymmetryOperator, elements: StructureElement.Set): Unit { export function create(id: number, kind: Kind, model: Model, operator: SymmetryOperator, elements: StructureElement.Set): Unit {
switch (kind) { switch (kind) {
case Kind.Atomic: return new Atomic(id, unitIdFactory(), model, elements, SymmetryOperator.createMapping(operator, model.atomicConformation), AtomicProperties()); case Kind.Atomic: return new Atomic(id, unitIdFactory(), model, elements, SymmetryOperator.createMapping(operator, model.atomicConformation, void 0), AtomicProperties());
case Kind.Spheres: return createCoarse(id, unitIdFactory(), model, Kind.Spheres, elements, SymmetryOperator.createMapping(operator, model.coarseConformation.spheres)); case Kind.Spheres: return createCoarse(id, unitIdFactory(), model, Kind.Spheres, elements, SymmetryOperator.createMapping(operator, model.coarseConformation.spheres, getSphereRadiusFunc(model)));
case Kind.Gaussians: return createCoarse(id, unitIdFactory(), model, Kind.Gaussians, elements, SymmetryOperator.createMapping(operator, model.coarseConformation.gaussians)); case Kind.Gaussians: return createCoarse(id, unitIdFactory(), model, Kind.Gaussians, elements, SymmetryOperator.createMapping(operator, model.coarseConformation.gaussians, getGaussianRadiusFunc(model)));
} }
} }
...@@ -64,6 +64,16 @@ namespace Unit { ...@@ -64,6 +64,16 @@ namespace Unit {
readonly lookup3d: Lookup3D readonly lookup3d: Lookup3D
} }
function getSphereRadiusFunc(model: Model) {
const r = model.coarseConformation.spheres.radius;
return (i: number) => r[i];
}
function getGaussianRadiusFunc(model: Model) {
// TODO: compute radius for gaussians
return (i: number) => 0;
}
const unitIdFactory = idFactory(); const unitIdFactory = idFactory();
// A bulding block of a structure that corresponds // A bulding block of a structure that corresponds
...@@ -95,7 +105,7 @@ namespace Unit { ...@@ -95,7 +105,7 @@ namespace Unit {
applyOperator(id: number, operator: SymmetryOperator, dontCompose = false): Unit { applyOperator(id: number, operator: SymmetryOperator, dontCompose = false): Unit {
const op = dontCompose ? operator : SymmetryOperator.compose(this.conformation.operator, operator); const op = dontCompose ? operator : SymmetryOperator.compose(this.conformation.operator, operator);
return new Atomic(id, this.invariantId, this.model, this.elements, SymmetryOperator.createMapping(op, this.model.atomicConformation), this.props); return new Atomic(id, this.invariantId, this.model, this.elements, SymmetryOperator.createMapping(op, this.model.atomicConformation, this.conformation.r), this.props);
} }
get lookup3d() { get lookup3d() {
...@@ -163,7 +173,7 @@ namespace Unit { ...@@ -163,7 +173,7 @@ namespace Unit {
applyOperator(id: number, operator: SymmetryOperator, dontCompose = false): Unit { applyOperator(id: number, operator: SymmetryOperator, dontCompose = false): Unit {
const op = dontCompose ? operator : SymmetryOperator.compose(this.conformation.operator, operator); const op = dontCompose ? operator : SymmetryOperator.compose(this.conformation.operator, operator);
const ret = createCoarse(id, this.invariantId, this.model, this.kind, this.elements, SymmetryOperator.createMapping(op, this.getCoarseElements())); const ret = createCoarse(id, this.invariantId, this.model, this.kind, this.elements, SymmetryOperator.createMapping(op, this.getCoarseElements(), this.conformation.r));
(ret as Coarse<K, C>)._lookup3d = this._lookup3d; (ret as Coarse<K, C>)._lookup3d = this._lookup3d;
return ret; return ret;
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment