in packages/ketcher-react/src/script/editor/tool/helper/locate.ts [236:404]
function getElementsInPolygon(restruct: ReStruct, rr) {
// eslint-disable-line max-statements
const bondList: Array<number> = [];
const atomList: Array<number> = [];
const r: any = [];
const sGroups = restruct.sgroups;
const functionalGroups = restruct.molecule.functionalGroups;
const struct: Struct = restruct.molecule;
for (let i = 0; i < rr.length; ++i) {
r[i] = new Vec2(rr[i].x, rr[i].y);
}
restruct.bonds.forEach((bond, bid) => {
if (
FunctionalGroup.isBondInContractedFunctionalGroup(
bond.b,
sGroups,
functionalGroups,
)
) {
return;
}
let center: Vec2;
if (bond.b.isExternalBondBetweenMonomers(struct)) {
const firstMonomer = struct.getGroupFromAtomId(bond.b.begin);
const secondMonomer = struct.getGroupFromAtomId(bond.b.end);
assert(firstMonomer);
assert(secondMonomer);
center =
firstMonomer?.pp && secondMonomer?.pp
? Vec2.centre(firstMonomer.pp, secondMonomer.pp)
: bond.b.center;
} else {
center = bond.b.center;
}
if (isPointInPolygon(r, center)) {
bondList.push(bid);
}
});
restruct.atoms.forEach((atom, aid) => {
const relatedFGId = FunctionalGroup.findFunctionalGroupByAtom(
functionalGroups,
aid,
);
const sGroup = struct.sgroups.get(relatedFGId as number);
if (struct.isAtomFromMacromolecule(aid)) {
if (sGroup && sGroup.pp && isPointInPolygon(r, sGroup.pp)) {
atomList.push(aid);
}
} else {
if (
isPointInPolygon(r, atom.a.pp) &&
(!FunctionalGroup.isAtomInContractedFunctionalGroup(
atom.a,
sGroups,
functionalGroups,
true,
) ||
aid === sGroup?.atoms[0])
) {
atomList.push(aid);
}
}
});
const rxnArrowsList: Array<number> = [];
const rxnPlusesList: Array<number> = [];
const simpleObjectsList: Array<number> = [];
const textsList: Array<number> = [];
restruct.rxnArrows.forEach((item, id) => {
const referencePoints = item.getReferencePoints();
const referencePointInPolygon = referencePoints.find((point) =>
isPointInPolygon(r, point),
);
if (referencePointInPolygon) {
rxnArrowsList.push(id);
}
});
restruct.rxnPluses.forEach((item, id) => {
if (isPointInPolygon(r, item.item.pp)) {
rxnPlusesList.push(id);
}
});
restruct.simpleObjects.forEach((item, id) => {
const referencePoints = item.getReferencePoints(true);
const referencePointInPolygon = referencePoints.find((point) =>
isPointInPolygon(r, point),
);
if (referencePointInPolygon) {
simpleObjectsList.push(id);
}
});
restruct.texts.forEach((item, id) => {
const referencePoints = item.getReferencePoints();
const referencePointInPolygon = referencePoints.find((point) =>
isPointInPolygon(r, point),
);
if (referencePointInPolygon) {
textsList.push(id);
}
});
const enhancedFlagList: Array<number> = [];
// ReEnhancedFlag doesn't have pp item according to types but somehow it works
restruct.enhancedFlags.forEach((item: any, id) => {
if (item.pp && isPointInPolygon(r, item.pp)) {
enhancedFlagList.push(id);
}
});
const sgroupDataList: Array<number> = [];
restruct.sgroupData.forEach((item, id) => {
if (isPointInPolygon(r, item.sgroup.pp)) {
sgroupDataList.push(id);
}
});
const rgroupAttachmentPointList: number[] = [];
restruct.visibleRGroupAttachmentPoints.forEach((item, id) => {
if (isPointInPolygon(r, item.middlePoint)) {
rgroupAttachmentPointList.push(id);
}
});
const reImages = Array.from(restruct.images.entries()).reduce(
(acc: Array<number>, [id, item]) => {
const isPointInside = Object.values(
item.image.getReferencePositions(),
).some((point) => isPointInPolygon(r, point));
return isPointInside ? acc.concat(id) : acc;
},
[],
);
const reMultitailArrows = Array.from(
restruct.multitailArrows.entries(),
).reduce((acc: Array<number>, [id, item]) => {
const isPointInside = item.multitailArrow
.getReferencePositionsArray()
.some((point) => isPointInPolygon(r, point));
return isPointInside ? acc.concat(id) : acc;
}, []);
return {
atoms: atomList,
bonds: bondList,
rxnArrows: rxnArrowsList,
rxnPluses: rxnPlusesList,
enhancedFlags: enhancedFlagList,
sgroupData: sgroupDataList,
simpleObjects: simpleObjectsList,
texts: textsList,
rgroupAttachmentPoints: rgroupAttachmentPointList,
[IMAGE_KEY]: reImages,
[MULTITAIL_ARROW_KEY]: reMultitailArrows,
};
}