forked from enviPath/enviPy
Current Dev State
This commit is contained in:
124
static/js/ketcher2/script/render/restruct/reloop.js
Normal file
124
static/js/ketcher2/script/render/restruct/reloop.js
Normal file
@ -0,0 +1,124 @@
|
||||
/****************************************************************************
|
||||
* Copyright 2017 EPAM Systems
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
***************************************************************************/
|
||||
|
||||
var Vec2 = require('../../util/vec2');
|
||||
var Visel = require('./visel');
|
||||
var ReObject = require('./reobject');
|
||||
var scale = require('../../util/scale');
|
||||
var util = require('../util');
|
||||
var Struct = require('../../chem/struct');
|
||||
|
||||
var tfx = util.tfx;
|
||||
|
||||
function ReLoop(loop) {
|
||||
this.loop = loop;
|
||||
this.visel = new Visel('loop');
|
||||
this.centre = new Vec2();
|
||||
this.radius = new Vec2();
|
||||
}
|
||||
ReLoop.prototype = new ReObject();
|
||||
ReLoop.isSelectable = function () {
|
||||
return false;
|
||||
};
|
||||
|
||||
ReLoop.prototype.show = function (restruct, rlid, options) { // eslint-disable-line max-statements
|
||||
var render = restruct.render;
|
||||
var paper = render.paper;
|
||||
var molecule = restruct.molecule;
|
||||
var loop = this.loop;
|
||||
this.centre = new Vec2();
|
||||
loop.hbs.forEach(function (hbid) {
|
||||
var hb = molecule.halfBonds.get(hbid);
|
||||
var bond = restruct.bonds.get(hb.bid);
|
||||
var apos = scale.obj2scaled(restruct.atoms.get(hb.begin).a.pp, options);
|
||||
if (bond.b.type !== Struct.Bond.PATTERN.TYPE.AROMATIC)
|
||||
loop.aromatic = false;
|
||||
this.centre.add_(apos); // eslint-disable-line no-underscore-dangle
|
||||
}, this);
|
||||
loop.convex = true;
|
||||
for (var k = 0; k < this.loop.hbs.length; ++k) {
|
||||
var hba = molecule.halfBonds.get(loop.hbs[k]);
|
||||
var hbb = molecule.halfBonds.get(loop.hbs[(k + 1) % loop.hbs.length]);
|
||||
var angle = Math.atan2(
|
||||
Vec2.cross(hba.dir, hbb.dir),
|
||||
Vec2.dot(hba.dir, hbb.dir));
|
||||
if (angle > 0)
|
||||
loop.convex = false;
|
||||
}
|
||||
|
||||
this.centre = this.centre.scaled(1.0 / loop.hbs.length);
|
||||
this.radius = -1;
|
||||
loop.hbs.forEach(function (hbid) {
|
||||
var hb = molecule.halfBonds.get(hbid);
|
||||
var apos = scale.obj2scaled(restruct.atoms.get(hb.begin).a.pp, options);
|
||||
var bpos = scale.obj2scaled(restruct.atoms.get(hb.end).a.pp, options);
|
||||
var n = Vec2.diff(bpos, apos).rotateSC(1, 0).normalized();
|
||||
var dist = Vec2.dot(Vec2.diff(apos, this.centre), n);
|
||||
this.radius = (this.radius < 0) ? dist : Math.min(this.radius, dist);
|
||||
}, this);
|
||||
this.radius *= 0.7;
|
||||
if (!loop.aromatic)
|
||||
return;
|
||||
var path = null;
|
||||
if (loop.convex && options.aromaticCircle) {
|
||||
path = paper.circle(this.centre.x, this.centre.y, this.radius)
|
||||
.attr({
|
||||
'stroke': '#000',
|
||||
'stroke-width': options.lineattr['stroke-width']
|
||||
});
|
||||
} else {
|
||||
var pathStr = '';
|
||||
for (k = 0; k < loop.hbs.length; ++k) {
|
||||
hba = molecule.halfBonds.get(loop.hbs[k]);
|
||||
hbb = molecule.halfBonds.get(loop.hbs[(k + 1) % loop.hbs.length]);
|
||||
angle = Math.atan2(
|
||||
Vec2.cross(hba.dir, hbb.dir),
|
||||
Vec2.dot(hba.dir, hbb.dir));
|
||||
var halfAngle = (Math.PI - angle) / 2;
|
||||
var dir = hbb.dir.rotate(halfAngle);
|
||||
var pi = scale.obj2scaled(restruct.atoms.get(hbb.begin).a.pp, options);
|
||||
var sin = Math.sin(halfAngle);
|
||||
var minSin = 0.1;
|
||||
if (Math.abs(sin) < minSin)
|
||||
sin = sin * minSin / Math.abs(sin);
|
||||
var offset = options.bondSpace / sin;
|
||||
var qi = pi.addScaled(dir, -offset);
|
||||
pathStr += (k === 0 ? 'M' : 'L');
|
||||
pathStr += tfx(qi.x) + ',' + tfx(qi.y);
|
||||
}
|
||||
pathStr += 'Z';
|
||||
path = paper.path(pathStr)
|
||||
.attr({
|
||||
'stroke': '#000',
|
||||
'stroke-width': options.lineattr['stroke-width'],
|
||||
'stroke-dasharray': '- '
|
||||
});
|
||||
}
|
||||
restruct.addReObjectPath('data', this.visel, path, null, true);
|
||||
};
|
||||
|
||||
ReLoop.prototype.isValid = function (struct, rlid) {
|
||||
var halfBonds = struct.halfBonds;
|
||||
var loop = this.loop;
|
||||
var bad = false;
|
||||
loop.hbs.forEach(function (hbid) {
|
||||
if (!halfBonds.has(hbid) || halfBonds.get(hbid).loop !== rlid)
|
||||
bad = true;
|
||||
}, this);
|
||||
return !bad;
|
||||
};
|
||||
|
||||
module.exports = ReLoop;
|
||||
Reference in New Issue
Block a user