I want to rotate the curve to be close to both points, the rotate axis is vector( 0, 0, 1 ) which is Z-axis in VTK’s world coordinate system.

We can use the summary of distance squares to indicate the match level, the value is bigger means the curve is further from both points. Let’s guess a value for rotating angle and rotate the curve, if the squares summary become bigger, the curve need to be rotated on the opposite direction. Maybe rotating operation get weird results, squares summary become bigger, smaller, bigger, smaller, and bigger… It’s time to make the rotating angle smaller. Just jump out from the calculating loop if there are same squares summary all the time.

void LearnToRotateZSCurve()
{
    const double floatErrorLimit = 1e-7;
    int iteractionTimes = 300;
    double lastDisSum[2] = { VTK_DOUBLE_MAX, VTK_DOUBLE_MAX };
    double angle = 2;
    double dis2Sum = GetDistance2SumForPtsToSCurve( backPoints[0], backPoints[1] );
    std::vector<double> dis2SumVec;
    while( dis2Sum > floatErrorLimit && iteractionTimes > 0 )
    {
        if( dis2SumVec.size() == 0 || fabs(dis2SumVec[dis2SumVec.size()-1] - dis2Sum) < floatErrorLimit )
        {
            dis2SumVec.push_back( dis2Sum );

            // We get many same dis2 results, jump out.
            if( dis2SumVec.size() >= 10 )
            {
                bool allSame = true;
                for( int i = dis2SumVec.size() - 2; i >= dis2SumVec.size() - 10 ; --i )
                {
                    if( fabs( dis2SumVec[i] - dis2SumVec[i+1] ) > floatErrorLimit )
                    {
                        allSame = false;
                        break;
                    }
                }
                if( allSame )
                {
                    printf( "allSame jump out: %d \n", dis2SumVec.size() );
                    break;
                }
            }
        }
        // dis2SumVec.size() > 0 && dis2SumVec[dis2SumVec.size()-1] != dis2Sum
        else
        {
            dis2SumVec.clear();
            dis2SumVec.push_back( dis2Sum );
        }

        // we get wave motion in value increasing, then adjust parameter `angle` to smaller.
        if( (lastDisSum[1] - lastDisSum[0]) * (dis2Sum - lastDisSum[1]) < 0 )
        {
            angle = angle * 0.9;
        }

        // we get same distance, maybe it need a smaller angle to find a reasonable distance.
        if( fabs( lastDisSum[1] - lastDisSum[0] ) < floatErrorLimit && fabs(dis2Sum - lastDisSum[1]) < floatErrorLimit )
        {
            angle = angle * 0.9;
            angle = -angle;
        }
        // The distance become larger.
        else if( dis2Sum > lastDisSum[1] )
        {
            angle = -angle;
        }

        RotateSCurveAroundZAxis( angle );
        iteractionTimes--;
        lastDisSum[0] = lastDisSum[1];
        lastDisSum[1] = dis2Sum;
        dis2Sum = GetDistance2SumForPtsToSCurve( backPoints[0], backPoints[1] );
    }
    printf( "LearnToRotateZSCurve dis2Sum: %lf\n", dis2Sum );
}
Categories: VTK

0 Comments

Leave a Reply

Your email address will not be published. Required fields are marked *

You cannot copy content of this page