void RefinementState::calcEnergy () { int i, j; float r; Vec2f d; energy = 0; for (i = _graph.vertexBegin(); i < _graph.vertexEnd(); i = _graph.vertexNext(i)) for (j = _graph.vertexBegin(); j < _graph.vertexEnd(); j = _graph.vertexNext(j)) { if (i == j) continue; d.diff(layout[i], layout[j]); r = d.lengthSqr(); if (r < 0.0001f) r = 5000000.f; else r = 1 / r; energy += r; } energy /= 2; }
// Flip all verices from branch around (v1,v2) void RefinementState::flipBranch (const Filter &branch, const RefinementState &state, int v1_idx, int v2_idx) { int i; float r, t; const Vec2f &v1 = state.layout[v1_idx]; const Vec2f &v2 = state.layout[v2_idx]; Vec2f d; d.diff(v2, v1); r = d.lengthSqr(); if (r < 0.000000001f) throw Error("too small edge"); layout.clear_resize(state.layout.size()); for (i = _graph.vertexBegin(); i < _graph.vertexEnd(); i = _graph.vertexNext(i)) { if (!branch.valid(i)) { const Vec2f &vi = state.layout[i]; t = ((vi.x - v1.x) * d.x + (vi.y - v1.y) * d.y) / r; layout[i].set(2 * d.x * t + 2 * v1.x - vi.x, 2 * d.y * t + 2 * v1.y - vi.y); } else layout[i] = state.layout[i]; } }
bool Vec2f::normalization (const Vec2f &v) { float l = v.lengthSqr(); if (l < EPSILON * EPSILON) return false; l = (float)sqrt(l); x = v.x / l; y = v.y / l; return true; }
RefinementState::RefinementState (MoleculeLayoutGraph &graph) : dist(0.f), energy(0), height(0.f), CP_INIT, TL_CP_GET(layout), _graph(graph) { } void RefinementState::calcDistance (int v1, int v2) { Vec2f d; d.diff(layout[v1], layout[v2]); dist = d.lengthSqr(); }
void MoleculeCleaner2d::_calcCoef(int to, int from0, int from1) { Vec2f A0 = plane(_mol.getAtomXyz(from0)); Vec2f A1 = plane(_mol.getAtomXyz(from1)); Vec2f A2 = plane(_mol.getAtomXyz(to)); Vec2f vec = A1 - A0; float dist2 = vec.lengthSqr(); float cross = Vec2f::cross(A1 - A0, A2 - A0); // c1 float dot = Vec2f::dot(A1 - A0, A2 - A0); // c2 Vec2f _coef = Vec2f(dot, cross) / dist2; int len = std::max(coef[from0].size(), coef[from1].size()); _addCoef(from0, len - 1, ZERO); _addCoef(from1, len - 1, ZERO); for (int i = 0; i < len; i++) { _addCoef(to, i, mult(_coef, coef[from1][i])); Vec2f one_minus_coef = ONE - _coef; _addCoef(to, i, mult(one_minus_coef, coef[from0][i])); } }
MoleculeLayoutSmoothingSegment::MoleculeLayoutSmoothingSegment(MoleculeLayoutGraphSmart& mol, Vec2f& start, Vec2f& finish) : _graph(mol), _start(start), _finish(finish) { _center.zero(); Vec2f diameter = (_finish - _start); _length = diameter.length(); Vec2f rotate_vector = diameter / diameter.lengthSqr(); rotate_vector.y *= -1; _pos.clear_resize(_graph.vertexEnd()); bool is_line = false; for (int v : _graph.vertices()) if (_graph.getVertex(v).degree() == 1) is_line = true; if (!is_line) { for (int v : _graph.vertices()) { _pos[v].copy(_graph.getPos(v)); _pos[v] -= _start; _pos[v].rotate(rotate_vector); } } else { // this is straight line QS_DEF(Array<int>, vert); vert.clear(); // list or vertices in order of connection for (int v : _graph.vertices()) if (_graph.getVertex(v).degree() == 1) { vert.push(v); break; } vert.push(_graph.getVertex(vert[0]).neiVertex(_graph.getVertex(vert[0]).neiBegin())); while (vert.size() < _graph.vertexCount()) { for (int n = _graph.getVertex(vert.top()).neiBegin(); n != _graph.getVertex(vert.top()).neiEnd(); n = _graph.getVertex(vert.top()).neiNext(n)) if (_graph.getVertex(vert.top()).neiVertex(n) != vert[vert.size() - 2]) { vert.push(_graph.getVertex(vert.top()).neiVertex(n)); } } for (int i = 0; i < vert.size(); i++) _pos[vert[i]].set(i * 1. / (vert.size() - 1), 0); } // double ternary search of center of component float MLx = 0, Ly = 0, MRx = 0, Ry = 0, Lx, Rx; for (int v : _graph.vertices()) { MLx = __min(MLx, _pos[v].x); MRx = __max(MRx, _pos[v].x); Ly = __min(Ly, _pos[v].y); Ry = __max(Ry, _pos[v].y); } while (Ry - Ly > EPSILON) { float dy = (Ry - Ly) / 3; float ry[2]; float My = Ly + dy; for (int i = 0; i < 2; i++) { Lx = MLx, Rx = MRx; float rx[2]; while (Rx - Lx > EPSILON) { float dx = (Rx - Lx) / 3; float Mx = Lx + dx; for (int j = 0; j < 2; j++) { rx[j] = calc_radius(Vec2f(Mx, My)); Mx += dx; } if (rx[0] > rx[1]) Lx += dx; else Rx -= dx; } ry[i] = calc_radius(Vec2f(Rx, My)); My += dy; } if (ry[0] > ry[1]) Ly += dy; else Ry -= dy; } _center = Vec2f(Rx, Ry); _radius = calc_radius(_center); /* _radius = 0; Vec2f center(0.5, 0); for (int v : _graph.vertices()) { float dist = (center - _pos[v]).length(); if (dist > _radius) _radius = dist; } _center = center;*/ _square = 0; }