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 {
readonly position: CoordinateMapper,
x(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 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 position = operator.isIdentity ? invariantPosition : SymmetryOperator.createCoordinateMapper(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 {
......@@ -74,6 +75,8 @@ namespace SymmetryOperator {
export { SymmetryOperator }
function _zeroRadius(i: number) { return 0; }
interface Projections { x(index: number): number, y(index: number): number, z(index: number): number }
function createProjections(t: SymmetryOperator, coords: SymmetryOperator.Coordinates): Projections {
......
......@@ -324,22 +324,12 @@ namespace Structure {
}
const distVec = Vec3.zero();
function atomicOrGaussianDistance(u: Unit.Atomic | Unit.Gaussians, p: Vec3, r: number) {
const { elements, conformation } = u;
function unitElementMinDistance(unit: Unit, p: Vec3, eRadius: number) {
const { elements, conformation: { position, r } } = unit, dV = distVec;
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;
if (d < minD) minD = d;
}
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]];
const e = elements[i];
const d = Vec3.distance(p, position(e, dV)) - eRadius - r(e);
if (d < minD) minD = d;
}
return minD;
......@@ -347,19 +337,10 @@ namespace Structure {
export function minDistanceToPoint(s: Structure, point: Vec3, radius: number) {
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++) {
const unit = units[i];
switch (unit.kind) {
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;
}
const d = unitElementMinDistance(unit, point, radius);
if (d < minD) minD = d;
}
return minD;
......@@ -370,30 +351,16 @@ namespace Structure {
if (a.elementCount === 0 || b.elementCount === 0) return 0;
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++) {
const unit = units[i];
const { elements, conformation } = unit;
switch (unit.kind) {
case Unit.Kind.Atomic:
// TODO: assign radius to gaussian elements?
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;
const { elements, conformation: { position, r } } = unit;
for (let i = 0, _i = elements.length; i < _i; i++) {
const d = minDistanceToPoint(b, conformation.position(elements[i], distPivot), radius[elements[i]]);
const e = elements[i];
const d = minDistanceToPoint(b, position(e, distPivot), r(e));
if (d < minD) minD = d;
}
break;
}
if (d < minD) minD = d;
}
return minD;
}
......
......@@ -29,9 +29,9 @@ namespace Unit {
export function create(id: number, kind: Kind, model: Model, operator: SymmetryOperator, elements: StructureElement.Set): Unit {
switch (kind) {
case Kind.Atomic: return new Atomic(id, unitIdFactory(), model, elements, SymmetryOperator.createMapping(operator, model.atomicConformation), AtomicProperties());
case Kind.Spheres: return createCoarse(id, unitIdFactory(), model, Kind.Spheres, elements, SymmetryOperator.createMapping(operator, model.coarseConformation.spheres));
case Kind.Gaussians: return createCoarse(id, unitIdFactory(), model, Kind.Gaussians, elements, SymmetryOperator.createMapping(operator, model.coarseConformation.gaussians));
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, getSphereRadiusFunc(model)));
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 {
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();
// A bulding block of a structure that corresponds
......@@ -95,7 +105,7 @@ namespace Unit {
applyOperator(id: number, operator: SymmetryOperator, dontCompose = false): Unit {
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() {
......@@ -163,7 +173,7 @@ namespace Unit {
applyOperator(id: number, operator: SymmetryOperator, dontCompose = false): Unit {
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;
return ret;
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment