Camera::Camera(QVector3D position, QVector3D center, float width, float height, float fovy, float zNear, float zFar) { m_world.lookAt(position, center, LocalUp); mWidth = width; mHeight = height; mFOVy = fovy; mZNear = zNear; mZFar = zFar; mCameraPosition = position; mLookAtPosition = center; mUpVector = QVector3D(0,1,0); setModelMatrix(QVector3D(1,0,0),0,QVector3D(0,0,0),QVector3D(1,1,1)); setProjectionMatrix(mWidth, mHeight); setViewMatrix(mCameraPosition, mLookAtPosition, mUpVector); totalZoom = position.distanceToPoint(center); }
inline void OpenGLWidget::drawBonds() { for (Bond *bond : m_molecule->bonds()) { QVector3D fromPos = bond->fromAtom()->position(); QVector3D toPos = bond->toAtom()->position(); short order = bond->order(); // Following variables are used to calculate positions between bonds. QVector3D tot = fromPos + toPos; QVector3D diff = fromPos - toPos; QVector3D cross1 = QVector3D::crossProduct(fromPos , toPos).normalized() / 4; QVector3D cross2 = QVector3D::crossProduct(cross1 , diff).normalized() / 4; double sqrt3_2 = sqrt(3) / 2; for (int i = 0; i < order; ++i) { QMatrix4x4 model; model.rotate(m_rotation); switch (order) { case 1: { model.translate((tot) / 2.0); break; } case 2: { if (i == 0) model.translate((tot + cross2) / 2.0); else if (i == 1) model.translate((tot - cross2) / 2.0); break; } case 3: { if (i == 0) model.translate((tot + cross1) / 2.0); if (i == 1) model.translate((tot + (-cross1 / 2) + cross2 * sqrt3_2) / 2.0); if (i == 2) model.translate((tot + (-cross1 / 2) - cross2 * sqrt3_2) / 2.0); break; } case 4: { if (i == 0) model.translate((tot + cross1 + cross2) / 2.0); else if (i == 1) model.translate((tot - cross1 - cross2) / 2.0); else if (i == 2) model.translate((tot + cross1 - cross2) / 2.0); else if (i == 3) model.translate((tot - cross1 + cross2) / 2.0); } } /** * Bond angle calculation code is based on a pseudo code * from http://www.thjsmith.com/40 */ // This is the default direction for the cylinder QVector3D y = QVector3D(0,1,0); // Get diff between two points you want cylinder along QVector3D p = (fromPos - toPos); // Get CROSS product (the axis of rotation) QVector3D t = QVector3D::crossProduct(y , p); // Get angle. LENGTH is magnitude of the vector double angle = 180 / M_PI * acos(QVector3D::dotProduct(y, p) / p.length()); // Rotate to align with two atoms model.rotate(angle, t); // Scale to fill up the distace between two atoms float length = fromPos.distanceToPoint(toPos) / 2.0; model.scale(0.04, length, 0.04); m_program.setUniformValue(m_modelLocation, model); m_program.setUniformValue(m_colorLocation, QVector3D(0.564706f, 0.564706f, 0.564706f)); // Draw cylinder geometry m_bondMesh.render(); } } }
bool Tools::isInRange(QVector3D x, QVector3D y, float dist) { if (x.distanceToPoint(y) < dist) return true ; }