in packages/ketcher-react/src/script/editor/tool/helper/locate.ts [27:234]
function getElementsInRectangle(restruct: ReStruct, p0, p1) {
const bondList: Array<number> = [];
const atomList: Array<number> = [];
const sGroups = restruct.sgroups;
const functionalGroups = restruct.molecule.functionalGroups;
const struct: Struct = restruct.molecule;
const x0 = Math.min(p0.x, p1.x);
const x1 = Math.max(p0.x, p1.x);
const y0 = Math.min(p0.y, p1.y);
const y1 = Math.max(p0.y, p1.y);
const topLeftPosition = new Vec2(x0, y0);
const topRightPosition = new Vec2(x1, y0);
const bottomRightPosition = new Vec2(x1, y1);
const bottomLeftPosition = new Vec2(x0, y1);
const polygon = [
topLeftPosition,
topRightPosition,
bottomRightPosition,
bottomLeftPosition,
];
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 (center.x > x0 && center.x < x1 && center.y > y0 && center.y < y1) {
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 &&
sGroup.pp.x > x0 &&
sGroup.pp.x < x1 &&
sGroup.pp.y > y0 &&
sGroup.pp.y < y1
) {
atomList.push(aid);
}
} else {
if (
atom.a.pp.x > x0 &&
atom.a.pp.x < x1 &&
atom.a.pp.y > y0 &&
atom.a.pp.y < y1 &&
(!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> = [];
// ReRxnArrow item doesn't have center method according to types but somehow it works
restruct.rxnArrows.forEach((item: any, id) => {
if (
item.item.center().x > x0 &&
item.item.center().x < x1 &&
item.item.center().y > y0 &&
item.item.center().y < y1
) {
rxnArrowsList.push(id);
}
});
restruct.rxnPluses.forEach((item, id) => {
if (
item.item.pp.x > x0 &&
item.item.pp.x < x1 &&
item.item.pp.y > y0 &&
item.item.pp.y < y1
) {
rxnPlusesList.push(id);
}
});
restruct.simpleObjects.forEach((item, id) => {
const referencePoints = item.getReferencePoints(true);
const referencePointInRectangle = referencePoints.find(
(point) => point.x > x0 && point.x < x1 && point.y > y0 && point.y < y1,
);
if (referencePointInRectangle) {
simpleObjectsList.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) return;
if (item.pp.x > x0 && item.pp.x < x1 && item.pp.y > y0 && item.pp.y < y1) {
enhancedFlagList.push(id);
}
});
const sgroupDataList: Array<number> = [];
restruct.sgroupData.forEach((item, id) => {
if (
item.sgroup.pp.x > x0 &&
item.sgroup.pp.x < x1 &&
item.sgroup.pp.y > y0 &&
item.sgroup.pp.y < y1
) {
sgroupDataList.push(id);
}
});
const textsList: Array<number> = [];
restruct.texts.forEach((item, id) => {
const referencePoints = item.getReferencePoints();
const referencePointInRectangle = referencePoints.find((point) => {
return point.x > x0 && point.x < x1 && point.y > y0 && point.y < y1;
});
if (referencePointInRectangle) {
textsList.push(id);
}
});
const rgroupAttachmentPointList: number[] = [];
restruct.visibleRGroupAttachmentPoints.forEach((item, id) => {
if (
item.middlePoint.x > x0 &&
item.middlePoint.x < x1 &&
item.middlePoint.y > y0 &&
item.middlePoint.y < y1
) {
rgroupAttachmentPointList.push(id);
}
});
const reImages = Array.from(restruct.images.entries()).reduce(
(acc: Array<number>, [id, item]): Array<number> => {
const isPointInside = Object.values(
item.image.getReferencePositions(),
).some((point) => point.isInsidePolygon(polygon));
return isPointInside ? acc.concat(id) : acc;
},
[],
);
const reMultitailArrows = Array.from(
restruct.multitailArrows.entries(),
).reduce((acc: Array<number>, [id, item]): Array<number> => {
const isPointInside = item.multitailArrow
.getReferencePositionsArray()
.some((point) => point.isInsidePolygon(polygon));
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,
};
}