float MoleculeLayoutMacrocycles::depictionCircle()

in core/indigo-core/layout/src/molecule_layout_macrocycles.cpp [1253:1494]


float MoleculeLayoutMacrocycles::depictionCircle()
{

    int cisCount = 0;
    for (int i = 0; i < length; i++)
        if (_edge_stereo[i] == MoleculeCisTrans::CIS)
            cisCount++;

    int zero_edge_stereo_count = 0;
    for (int i = 0; i < length; i++)
        if (_edge_stereo[i] == 0)
            zero_edge_stereo_count++;
    if (zero_edge_stereo_count == 0)
        return 1000000;

    QS_DEF(Array<bool>, up);
    QS_DEF(Array<bool>, only_up);
    up.clear_resize(length + 1);
    only_up.clear_resize(length + 1);
    up.zerofill();
    only_up.zerofill();

    for (int i = 0; i < length; i++)
        if (_edge_stereo[i] == MoleculeCisTrans::CIS && _edge_stereo[(i + length - 1) % length] == MoleculeCisTrans::CIS)
        {
            only_up[(i + 1) % length] = 1;
            only_up[i] = 1;
            only_up[(i + length - 1) % length] = 1;
        }

    for (int i = 0; i < length; i++)
        up[i] = only_up[i];

    QS_DEF(Array<int>, free);
    free.clear_resize(length);

    bool exist_precalc = false;
    for (int i = 0; i < length; i++)
        exist_precalc |= only_up[i];

    if (exist_precalc)
    {
        int index_start = 0;
        int index_end = 0;
        // int start = 0;
        for (int i = 0; i < length; i++)
            if (!only_up[i] && only_up[(i + length - 1) % length])
            {
                index_start = i;
                index_end = index_start;
                while (!only_up[index_end])
                    index_end = (index_end + 1) % length;

                for (int j = index_start; j != index_end; j = (j + 1) % length)
                    if (_edge_stereo[(j - 1 + length) % length] == MoleculeCisTrans::CIS)
                        up[j] = up[(j - 1 + length) % length];
                    else
                        up[j] = !up[(j - 1 + length) % length];

                if (up[(index_end - 1 + length) % length])
                {

                    int index_flip = -1;
                    for (int j = index_start; j != index_end; j = (j + 1) % length)
                        if (_edge_stereo[j] != MoleculeCisTrans::CIS && _edge_stereo[(j + length - 1) % length] != MoleculeCisTrans::CIS)
                            index_flip = j;
                    if (index_flip == -1)
                    {
                        free.zerofill();
                        int index_free = 0;
                        for (int j = index_start; j != index_end; j = (j + 1) % length)
                            if (_edge_stereo[(j - 1 + length) % length] == 0 || _edge_stereo[j] == 0)
                                free[index_free++] = j;
                        if (index_free > 0)
                            index_flip = free[index_free / 2];
                        else
                            index_flip = index_start;
                    }

                    for (int j = index_flip; j != index_end; j = (j + 1) % length)
                        up[j] = !up[j];
                }
            }
    }
    else
    {
        for (int i = 0; i < length; i++)
        {
            if (_edge_stereo[i] == MoleculeCisTrans::CIS)
                up[i + 1] = up[i];
            else
                up[i + 1] = !up[i];
        }

        if ((cisCount + length) % 2 == 0)
        {
            // if first and last points on the same level
            int upCisCount = 0;
            int downCisCount = 0;

            for (int i = 0; i < length; i++)
            {
                if (_edge_stereo[i] == MoleculeCisTrans::CIS && up[i])
                    upCisCount++;
                if (_edge_stereo[i] == MoleculeCisTrans::CIS && !up[i])
                    downCisCount++;
            }
            if (downCisCount > upCisCount)
            {
                for (int i = 0; i <= length; i++)
                    up[i] = !up[i];
            }
        }
        else
        {
            // if first and last points on the different levels
            if (cisCount == 0)
            {
                int index = 0;
                if (_edge_stereo[0] != 0 || _edge_stereo[length - 1] != 0 || _vertex_stereo[0] == 0)
                {
                    for (int i = 1; i < length; i++)
                        if (_edge_stereo[i] != 0 || _edge_stereo[i - 1] != 0 || _vertex_stereo[i] == 1)
                            index = i;
                }
                for (int i = index; i <= length; i++)
                    up[i] = !up[i];
                if (!up[index])
                    for (int i = 0; i <= length; i++)
                        up[i] = !up[i];
            }
            else
            {
                int bestIndex = 0;
                int bestDiff = -1;
                for (int i = 0; i < length; i++)
                    if (_edge_stereo[i] == MoleculeCisTrans::CIS || _edge_stereo[(i - 2 + length) % length] == MoleculeCisTrans::CIS)
                    {
                        int diff = 0;
                        for (int j = 0; j < length; j++)
                        {
                            if (_edge_stereo[i] == MoleculeCisTrans::CIS && ((up[i] && j < i) || (!up[i] && j >= i)))
                                diff++;
                            if (_edge_stereo[i] == MoleculeCisTrans::CIS && !((up[i] && j < i) || (!up[i] && j >= i)))
                                diff--;
                        }
                        if (up[i])
                            diff = -diff;
                        if (diff > bestDiff)
                        {
                            bestDiff = diff;
                            bestIndex = i;
                        }
                    }

                for (int i = bestIndex; i <= length; i++)
                    up[i] = !up[i];

                if (!up[bestIndex])
                {
                    for (int i = 0; i <= length; i++)
                        up[i] = !up[i];
                }
            }
        }
    }

    int diff = 0;
    for (int i = 0; i < length; i++)
    {
        if ((!up[i] && (up[(i + 1) % length] || up[(i + length - 1) % length])) && _vertex_weight[i] > 0)
            diff += _vertex_weight[i];
        if (!(!up[i] && (up[(i + 1) % length] || up[(i + length - 1) % length])) && _vertex_weight[i] < 0)
            diff -= _vertex_weight[i];
    }

    //   for (int i = 0; i < length; i++)
    //    diff += (up[i] && up[(i + 1) % length]) || (!up[i] && !up[(i + 1) % length] && (up[(i - 1 + length) % length] == up[(i + 2) % length]));

    float r = _2FLOAT(length * sqrt(3.0) / 2. / (2. * M_PI));

    QS_DEF(Array<Vec2f>, p);
    p.clear_resize(length + 1);

    for (int i = 0; i <= length; i++)
    {
        float rr = r;
        if (up[i])
            rr += 0.25;
        else
            rr -= 0.25;

        p[i] = Vec2f(rr, 0);
        p[i].rotate(_2FLOAT(2. * M_PI / length * i));
    }

    QS_DEF(Array<int>, rotateAngle);
    rotateAngle.clear_resize(length);

    for (int i = 0; i < length; i++)
        rotateAngle[i] = -1;
    int i = 0;
    while (_edge_stereo[(i - 1 + length) % length] != 0 && _edge_stereo[i] != 0)
        i++;
    for (; rotateAngle[i] == -1; i = (i + 1) % length)
        if (_edge_stereo[(i - 1 + length) % length] == MoleculeCisTrans::CIS)
            rotateAngle[i] = rotateAngle[(i - 1 + length) % length];
        else if (_edge_stereo[(i - 1 + length) % length] == MoleculeCisTrans::TRANS)
            rotateAngle[i] = -rotateAngle[(i - 1 + length) % length];
        else
            rotateAngle[i] = up[i] ? 1 : (up[(i + 1) % length] || up[(i + length - 1) % length]) ? -1 : 1;

    QS_DEF(Array<int>, edgeLength);
    edgeLength.clear_resize(length);
    for (i = 0; i < length; i++)
        edgeLength[i] = 1;

    QS_DEF(Array<int>, vertexNumber);
    vertexNumber.clear_resize(length);
    for (i = 0; i < length; i++)
        vertexNumber[i] = i;

    /*float angle = M_PI * 2 * rand() / RAND_MAX;
    float sn = sin(angle);
    float cs = cos(angle);
    for (int i = 0; i < molSize; i++) {
       float xx = cs * x[i] - sn * y[i];
       float yy = sn * x[i] + cs * y[i];
       x[i] = xx;
       y[i] = yy;
    }*/

    //   smoothing(length, length, rotateAngle.ptr(), edgeLength.ptr(), vertexNumber.ptr(), p.ptr(), false);
    smoothing2(length, length, rotateAngle.ptr(), edgeLength.ptr(), vertexNumber.ptr(), p.ptr());

    for (i = 0; i < length; i++)
    {
        _positions[i] = p[i];
    }

    return badness(length, length, rotateAngle.ptr(), edgeLength.ptr(), vertexNumber.ptr(), p.ptr(), diff);
}