Example #1
0
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);
}
Example #2
0
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 ;
}