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:

    1. base object (this object will be stored in the list as "0. iteration")
    2. list of transformation matrices (every matrix can be composed by more basic matrices of scaling, rotation and translation)
    3. iteration number

    Now algorithm should be following:

    1. 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
    2. loop through all matrices
    3. map current matrix to base object
    4. store transformed object in the list
    5. after end of the loop the list of new objects become current iteration.
    6. goto 1. until required iteration number is achieved

    Let's take for example the Koch curve - the first three iterations:

    enter image description here

    parameters:

    1. base object = line
    2. 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
    3. 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:

    enter image description here

    Help me please, I'm little bit desperate :-(.

    Thank you very very much.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.