Создание замкнутой кривой B-сплайна с интерполяцией - PullRequest
0 голосов
/ 31 января 2020

У меня точно такая же ситуация с этим.

Как сделать замкнутый интерполирующий B-сплайн сглаженным в точке соединения

Я реализован метод интерполяции, чтобы получить открытую кривую B-сплайна.

и теперь хочу сделать ее закрытой.

сначала я просто добавляю контрольные точки в конце открытой и делаю единообразный узел для periodi c,

, но первая попытка не дает фактической «кривой интерполяции».

все точки интерполяции не находятся на кривой.

next, Я попытался добавить точку интерполяции, но понял, что это дает только удлиненную версию открытой кривой.

void Bspline::interpolate(const std::vector<Vector3d>& dataPoints)
    {
        std::vector<Vector3d> points = dataPoints;
        //need at least degree+1 points to render a curve
        if (points.size() <= degree_) 
        {
            do 
            {
                degree_ -= 1;
            } while (points.size() <= degree_);
        }

        std::vector<double> chordLength = chordLength_(points);
        knots_ = averaging_(chordLength);
        cv::Mat basisMatrix = cv::Mat::zeros(size, CV_64F);
        std::vector<double> N(degree_ + 1);
        for (uint32_t i = 0; i <= points.size() - 1; ++i)
        {
            int span = findSpan_(chordLength[i]);
           //Find the span of a B-Spline knot vector at a parametric point
           //Algorithm A2.1 from 'The NURBS BOOK' pg68

            basisFunc_(span, chordLength[i], N);
           //Basis function for B-Spline
           //Algorithm A2.2 from 'The NURBS BOOK' pg70.
            for (int j = span - degree_; j <= span; ++j)
            {
                basisMatrix.at<double>(i, j) = N[j - (span - degree_)];
            }
        }

        cv::Mat pointMat((int)points.size(), 3, CV_64F);

        for (int i = 0; i < points.size(); ++i)
        {
            pointMat.at<double>(i, 0) = points[i].X;
            pointMat.at<double>(i, 1) = points[i].Y;
            pointMat.at<double>(i, 2) = points[i].Z;
        }

        cv::Mat ctlPoints = cv::Mat(basisMatrix.inv() * pointMat);

        controlPoints_.clear();
        for (int i = 0; i != points.size(); ++i)
        {
            controlPoints_.push_back(Vector3d(ctlPoints.at<double>(i, 0), 
                                              ctlPoints.at<double>(i, 1), 
                                              ctlPoints.at<double>(i, 2)));
        }       
    }

выше дает правильную открытую равномерную кривую интерполяции открытая кривая вот моя первая попытка присоединить некоторую линию к конец верхнего кода.

if( isClosed() )
{
    for (size_t i = 0; i < degree(); i++)
    {
        controlPoints_.push_back(controlPoints()[i]);
    }
    toPeriodic_();//make element of knots_ has increasing value with same interval.
}

первая попытка синие точки - набор данных.

это результат второй попытки, я избавился от кода первой попытки и добавить это во главе fuction

        if (isClosed())
        {
            for (size_t i = 0; i < degree(); i++)
            {
                points.push_back(points[i]);
            }
        }

секунда try

Как я могу взять и непрерывность в первой точке, и фактическую интерполяцию одновременно? Я полностью истощен ㅠㅠ

Я уже прочитал и следую процедуре по первой ссылке, но мне не удалось.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...