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);
}