|
@@ -81,6 +81,7 @@ void ctkCoordinatesWidget::setDimension(int dim)
|
|
|
{
|
|
|
newPos[i] = 0.;
|
|
|
this->addSpinBox();
|
|
|
+ this->LastUserEditedCoordinates.push_back(i);
|
|
|
}
|
|
|
}
|
|
|
else
|
|
@@ -92,6 +93,7 @@ void ctkCoordinatesWidget::setDimension(int dim)
|
|
|
QWidget* widget = item ? item->widget() : 0;
|
|
|
delete item;
|
|
|
delete widget;
|
|
|
+ this->LastUserEditedCoordinates.pop_back();
|
|
|
}
|
|
|
}
|
|
|
delete [] this->Coordinates;
|
|
@@ -272,7 +274,11 @@ void ctkCoordinatesWidget::setCoordinates(double* coordinates)
|
|
|
item ? dynamic_cast<QDoubleSpinBox*>(item->widget()) : 0;
|
|
|
if (spinBox)
|
|
|
{
|
|
|
+ // we don't want updateCoordinate() to be called.
|
|
|
+ // it could mess with the LastUserEditedCoordinates list.
|
|
|
+ bool spinBoxSignalWasBlocked = spinBox->blockSignals(true);
|
|
|
spinBox->setValue(this->Coordinates[i]);
|
|
|
+ spinBox->blockSignals(spinBoxSignalWasBlocked);
|
|
|
}
|
|
|
}
|
|
|
this->blockSignals(blocked);
|
|
@@ -316,7 +322,6 @@ double const * ctkCoordinatesWidget::coordinates()const
|
|
|
//------------------------------------------------------------------------------
|
|
|
void ctkCoordinatesWidget::updateCoordinate(double coordinate)
|
|
|
{
|
|
|
- double den = 0.;
|
|
|
int element = -1;
|
|
|
for (int i = 0; i < this->Dimension; ++i)
|
|
|
{
|
|
@@ -328,38 +333,82 @@ void ctkCoordinatesWidget::updateCoordinate(double coordinate)
|
|
|
this->Coordinates[i] = coordinate;
|
|
|
element = i;
|
|
|
}
|
|
|
- else
|
|
|
+ }
|
|
|
+ Q_ASSERT(element != -1);
|
|
|
+ // Update the last edited history by push first the element.
|
|
|
+ for (int i = this->Dimension -1; i > 0; --i)
|
|
|
+ {
|
|
|
+ if (this->LastUserEditedCoordinates[i] == element)
|
|
|
{
|
|
|
- den += this->Coordinates[i]*this->Coordinates[i];
|
|
|
+ this->LastUserEditedCoordinates.swap(i,i-1);
|
|
|
}
|
|
|
}
|
|
|
- Q_ASSERT(element != -1);
|
|
|
+ // What is the oldest coordinate to be edited
|
|
|
+ int oldestElement = this->LastUserEditedCoordinates.last();
|
|
|
+
|
|
|
if (this->isNormalized())
|
|
|
{
|
|
|
+ // We have to ensure the coordinates are normalized.
|
|
|
+ double den = 0.;
|
|
|
+ double squaredNorm = this->squaredNorm();
|
|
|
// Old Values xx + yy + zz = 1
|
|
|
// New values: x'x' + y'y' + z'z' = 1
|
|
|
// Say we are changing y into y':
|
|
|
// x'x' + z'z' = 1 - y'y'
|
|
|
- // Let's pose a the coef to multiply x into x' that keeps the norm to 1:
|
|
|
- // axax + azaz = 1 - y'y'
|
|
|
- // aa(xx + zz) = 1 - y'y'
|
|
|
- // a = sqrt( (1 - y'y') / (xx + zz) )
|
|
|
- bool mult = true;
|
|
|
- if (den != 0.0)
|
|
|
+ if (oldestElement != -1 &&
|
|
|
+ this->Coordinates[oldestElement] != 0.0 &&
|
|
|
+ squaredNorm != 0.0)
|
|
|
{
|
|
|
- mult = true;
|
|
|
- den = sqrt( (1. - coordinate * coordinate) / den);
|
|
|
+ // 1) Normalize only with the oldest user edited value
|
|
|
+ // The oldest element is z, that means we try to have
|
|
|
+ // x = x' (so that the user doesn't loose the edit he just made on the
|
|
|
+ // element (x) he edited before this one (y).
|
|
|
+ // Let's pose a the coef to multiply z into z' that keeps the norm to 1
|
|
|
+ // xx + z'z' = 1 - y'y' (because x = x')
|
|
|
+ // xx + azaz = 1 - y'y' (because z' = az)
|
|
|
+ // aa*zz = 1 - y'y' - xx
|
|
|
+ // a = sqrt( (1 - y'y' - xx) / zz )
|
|
|
+ den = (1. - (squaredNorm -
|
|
|
+ this->Coordinates[oldestElement] *
|
|
|
+ this->Coordinates[oldestElement])) /
|
|
|
+ (this->Coordinates[oldestElement] *
|
|
|
+ this->Coordinates[oldestElement]);
|
|
|
+ if (den > 0.)
|
|
|
+ {
|
|
|
+ den = sqrt(den);
|
|
|
+ }
|
|
|
}
|
|
|
- else if (this->Dimension > 1)
|
|
|
+ // Maybe 1) failed, then give 2) a chance.
|
|
|
+ if (den <= 0)
|
|
|
{
|
|
|
- mult = false;
|
|
|
- den = sqrt((1. - coordinate*coordinate) / (this->Dimension - 1));
|
|
|
+ oldestElement = -1;
|
|
|
+ }
|
|
|
+ bool mult = true;
|
|
|
+ if (oldestElement == -1)
|
|
|
+ {
|
|
|
+ // 2) Normalize with all the coordinates
|
|
|
+ // Let's pose a the coef to multiply x into x' and z into z' that keeps
|
|
|
+ // the norm to 1:
|
|
|
+ // axax + azaz = 1 - y'y'
|
|
|
+ // aa(xx + zz) = 1 - y'y'
|
|
|
+ // a = sqrt( (1 - y'y') / (xx + zz) )
|
|
|
+ squaredNorm -= coordinate * coordinate;
|
|
|
+ if (squaredNorm != 0.0)
|
|
|
+ {
|
|
|
+ den = sqrt( (1. - coordinate * coordinate) / squaredNorm);
|
|
|
+ }
|
|
|
+ else if (this->Dimension > 1)
|
|
|
+ {
|
|
|
+ mult = false;
|
|
|
+ den = sqrt((1. - coordinate*coordinate) / (this->Dimension - 1));
|
|
|
+ }
|
|
|
}
|
|
|
// Normalize coordinates
|
|
|
double* normalizedCoordinates = new double[this->Dimension];
|
|
|
for (int i = 0; i < this->Dimension; ++i)
|
|
|
{
|
|
|
- if (i != element)
|
|
|
+ if ((i != element && oldestElement == -1) ||
|
|
|
+ (i == oldestElement && oldestElement != -1))
|
|
|
{
|
|
|
normalizedCoordinates[i] = mult ? this->Coordinates[i] * den : den;
|
|
|
}
|