QTransform: How to iteratively map composition of transformation matrices to object?
-
I've tried almost everything, but I still have no idea how to map composition of three transformation matrices to a line iteratively, to get first two iterations of the Koch curve.
Let me explain my problem. I've got three input parameters:
- base object (this object will be stored in the list as "0. iteration")
- list of transformation matrices (every matrix can be composed by more basic matrices of scaling, rotation and translation)
- iteration number
Now algorithm should be following:
- initialize empty list of new objects - the size of list will be the count of transformation matrices multiplied by the count of the list of objects from the previous iteration
- loop through all matrices
- map current matrix to base object
- store transformed object in the list
- after end of the loop the list of new objects become current iteration.
- goto 1. until required iteration number is achieved
Let's take for example the Koch curve - the first three iterations:
parameters:
- base object = line
- matrices = 1: scale to one third; 2: scale to one third, rotate 60 degrees, move to one third; 3: scale to one third, rotate 120 degrees, move to two thirds; 4: scale to one third, move to 1
- iteration number = 2
And now my code. I've tried a several changes of my code, but nothing worked :-(. Now I have following:
Let's assume, that:
-
this->currentIterationNumber = 1
IFSFractal::Iteration* IFSFractal::nextIteration() { // if following iteration is already computed, return it if ((this->currentIterationNumber + 1) < this->iterations.size()) { return this->iterations.at(++this->currentIterationNumber); } // compute following iteration else { IFSFractal::Iteration *nextIteration = new IFSFractal::Iteration(); IFSFractal::Iteration *currentIteration = this->iterations.at(this->currentIterationNumber); QList<QTransform> newIterationMatrices; // there will be so much new shapes as the count of matrices qint32 i = 0; QListIterator<QPolygonF*> iterator(currentIteration->iteration); while (iterator.hasNext()) { QPolygonF currentShape = *iterator.next(); QPointF currentPosition = currentShape.at(0); // last computed matrix (here is stored last rotation, scale, ...) QTransform lastMatrix = this->lastIterationMatrices.at(i++); // move current shape into the origin of the coordinate system QTransform toOrigin; toOrigin.translate(-currentPosition.x(), -currentPosition.y()); currentShape = toOrigin.map(currentShape); // go through all matrices QListIterator<QTransform> matrixIterator(this->matrices); while (matrixIterator.hasNext()) { QTransform currentMatrix = lastMatrix * matrixIterator.next(); newIterationMatrices.append(currentMatrix); // map transformation QPolygonF newShape = currentMatrix.map(currentShape); // returns new shape back into correct position QTransform toPosition; toPosition.translate(currentPosition.x(), currentPosition.y()); newShape = toPosition.map(newShape); // save transformed shape as pointer QPolygonF *p_newShape = new QPolygonF(newShape); nextIteration->iteration.append(p_newShape); } } this->lastIterationMatrices = newIterationMatrices; this->currentIterationNumber++; this->iterations.append(nextIteration); return nextIteration; } }
and here are my QTransforms:
// line segment QPolygonF *line = new QPolygonF(); line->append(QPointF(0, 0.75)); line->append(QPointF(1, 0.75)); // 0. iteration IFSFractal::Iteration *zero = new IFSFractal::Iteration(); zero->iteration.append(line); // save 0. iteration this->iterations.append(zero); // transform matrices // scaling to one third QTransform transform1; transform1.scale(1.0 / 3, 1.0 / 3); this->addMatrix(1, transform1); // scaling to 1/3, translation and rotation about 60 deg QTransform transform2; transform2.scale(1.0 / 3, 1.0 / 3) .translate(1, 0) .rotate(-60); this->addMatrix(2, transform2); // scaling to 1/3, translation and rotation about 120 deg QTransform transform3; transform3.scale(1.0 / 3, 1.0 / 3) .translate(2, 0) .rotate(-120); this->addMatrix(3, transform3); // scaling to 1/3 and translation to the right QTransform transform4; transform4.scale(1.0 / 3, 1.0 / 3) .translate(2, 0); this->addMatrix(4, transform4);
But it works only for the first iteration and I have no idea how to write it correct.
My result:
Help me please, I'm little bit desperate :-(.
Thank you very very much.