123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123 |
- /**
- * Copyright (c) 2018-2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
- *
- * @author Alexander Rose <alexander.rose@weirdbyte.de>
- */
- import { StructureElement } from './structure'
- import { Link } from './structure/structure/unit/links'
- import { Shape, ShapeGroup } from './shape';
- import { Sphere3D } from 'mol-math/geometry';
- import { CentroidHelper } from 'mol-math/geometry/centroid-helper';
- import { Vec3 } from 'mol-math/linear-algebra';
- import { OrderedSet } from 'mol-data/int';
- import { Structure } from './structure/structure';
- /** A Loci that includes every loci */
- export const EveryLoci = { kind: 'every-loci' as 'every-loci' }
- export type EveryLoci = typeof EveryLoci
- export function isEveryLoci(x: any): x is EveryLoci {
- return !!x && x.kind === 'every-loci';
- }
- /** A Loci that is empty */
- export const EmptyLoci = { kind: 'empty-loci' as 'empty-loci' }
- export type EmptyLoci = typeof EmptyLoci
- export function isEmptyLoci(x: any): x is EmptyLoci {
- return !!x && x.kind === 'empty-loci';
- }
- /** A generic data loci */
- export interface DataLoci {
- readonly kind: 'data-loci',
- readonly data: any,
- readonly tag: string
- readonly indices: OrderedSet<number>
- }
- export function isDataLoci(x: any): x is DataLoci {
- return !!x && x.kind === 'data-loci';
- }
- export function areDataLociEqual(a: DataLoci, b: DataLoci) {
- return a.data === b.data && a.tag === b.tag && OrderedSet.areEqual(a.indices, b.indices)
- }
- export function createDataLoci(data: any, tag: string, indices: OrderedSet<number>): DataLoci {
- return { kind: 'data-loci', data, tag, indices }
- }
- export { Loci }
- type Loci = StructureElement.Loci | Structure.Loci | Link.Loci | EveryLoci | EmptyLoci | DataLoci | Shape.Loci | ShapeGroup.Loci
- namespace Loci {
- export function areEqual(lociA: Loci, lociB: Loci) {
- if (isEveryLoci(lociA) && isEveryLoci(lociB)) return true
- if (isEmptyLoci(lociA) && isEmptyLoci(lociB)) return true
- if (isDataLoci(lociA) && isDataLoci(lociB)) {
- return areDataLociEqual(lociA, lociB)
- }
- if (Structure.isLoci(lociA) && Structure.isLoci(lociB)) {
- return Structure.areLociEqual(lociA, lociB)
- }
- if (StructureElement.isLoci(lociA) && StructureElement.isLoci(lociB)) {
- return StructureElement.areLociEqual(lociA, lociB)
- }
- if (Link.isLoci(lociA) && Link.isLoci(lociB)) {
- return Link.areLociEqual(lociA, lociB)
- }
- if (Shape.isLoci(lociA) && Shape.isLoci(lociB)) {
- return Shape.areLociEqual(lociA, lociB)
- }
- if (ShapeGroup.isLoci(lociA) && ShapeGroup.isLoci(lociB)) {
- return ShapeGroup.areLociEqual(lociA, lociB)
- }
- return false
- }
- const sphereHelper = new CentroidHelper(), tempPos = Vec3.zero();
- export function getBoundingSphere(loci: Loci, boundingSphere?: Sphere3D): Sphere3D | undefined {
- if (loci.kind === 'every-loci' || loci.kind === 'empty-loci') return void 0;
- if (!boundingSphere) boundingSphere = Sphere3D.zero()
- sphereHelper.reset();
- if (loci.kind === 'structure-loci') {
- return Sphere3D.copy(boundingSphere, loci.structure.boundary.sphere)
- } else if (loci.kind === 'element-loci') {
- return StructureElement.Loci.getBoundary(loci).sphere;
- } else if (loci.kind === 'link-loci') {
- for (const e of loci.links) {
- e.aUnit.conformation.position(e.aUnit.elements[e.aIndex], tempPos);
- sphereHelper.includeStep(tempPos);
- e.bUnit.conformation.position(e.bUnit.elements[e.bIndex], tempPos);
- sphereHelper.includeStep(tempPos);
- }
- sphereHelper.finishedIncludeStep();
- for (const e of loci.links) {
- e.aUnit.conformation.position(e.aUnit.elements[e.aIndex], tempPos);
- sphereHelper.radiusStep(tempPos);
- e.aUnit.conformation.position(e.bUnit.elements[e.bIndex], tempPos);
- sphereHelper.radiusStep(tempPos);
- }
- } else if (loci.kind === 'shape-loci') {
- // TODO
- return void 0;
- } else if (loci.kind === 'group-loci') {
- // TODO
- return void 0;
- } else if (loci.kind === 'data-loci') {
- // TODO maybe add loci.getBoundingSphere()???
- return void 0;
- }
- Vec3.copy(boundingSphere.center, sphereHelper.center)
- boundingSphere.radius = Math.sqrt(sphereHelper.radiusSq)
- return boundingSphere
- }
- const tmpSphere3D = Sphere3D.zero()
- export function getCenter(loci: Loci, center?: Vec3): Vec3 | undefined {
- const boundingSphere = getBoundingSphere(loci, tmpSphere3D)
- return boundingSphere ? Vec3.copy(center || Vec3.zero(), boundingSphere.center) : undefined
- }
- }
|