Как выделить вектор из N (неконстантных переменных) пар и инициализировать их? - PullRequest
0 голосов
/ 07 ноября 2018

Я делаю функцию, которая принимает четыре целых числа (координаты строки), а затем возвращает указатель на вектор пар (координаты пикселей), у меня возникают проблемы с выделением вектора и инициализацией пар в ноль.

компилятор не принимает выражение в векторном распределении: expected a type, got '(X1 - Xo)'

Если кто-то может объяснить мне, как работает new, создает ли он на самом деле вектор и в нем есть неинициализированный объект пар или он просто резервирует размер упомянутого объекта?

мой код функции:

vector<pair<int, int>>* draw_line_DDM(int Xo, int Yo, int X1, int Y1)
{
    double m;

    if((X1-Xo) == 0 && (Y1-Yo) == 0)
    {
        vector<pair<int, int>> *point = new vector<pair<int, int>>(1, make_pair(X1, Xo));
        //return a vector of one pair only

        return(point);  
    }


    if((X1-Xo) == 0 && (Y1-Yo) != 0)
    {
        m = 1000000000.0;
    }


    if((X1-Xo) != 0 && ((Y1-Yo) == 0 || (Y1-Yo) != 0))
    {
        double m = (Y1-Yo)/(X1-Xo);
    }


    if(abs(m)<=1)
    {
        vector<pair<int, int>> *pixels_x = new vector<pair<int, int>>(sizeof(vector<(X1-Xo),pair<0, 0>>));

        double y = Yo;

        for(int counter_x = Xo; counter_x <= X1 ; counter_x++)
        {
            pixels_x->at(counter_x).first = counter_x;
            y += m;
            pixels_x->at(counter_x).second = round(y);

        }
        //create a vector of x pairs

        return(pixels_x);
    }

    if(abs(m)>1)
    {
        double x = Xo;
        vector<pair<int, int>> *pixels_y = new vector<pair<int, int>>(sizeof(vector<(Y1-Yo),pair<0, 0>>));
        for(int counter_y = Yo; counter_y <= Y1 ; counter_y++)
        {
            pixels_y->at(counter_y).second = counter_y;
            x += (1/m);
            pixels_y->at(counter_y).first = round(x);   
        }

        return(pixels_y);
    }

}

Ответы [ 2 ]

0 голосов
/ 08 ноября 2018

Я сделал несколько ошибок в коде, размещенном в вопросе:

  1. Во-первых, при инициализации vectorOfPairs.
  2. Затем в диапазоне цикла for при попытке доступа к последнему элементу произошел сбой программа, лучше с итераторами.
  3. Также при присваивании выражения целых чисел двойному (всегда делается наклон = ноль).

Я согласен с @ user463035818 в отношении утечек памяти, передавая отмену выделения пользователю функции. но это был не мой вопрос.

возврат объектов приводит к замедлению копирования программы.

Вот исправление кода в моем вопросе:

vector<pair<int, int>>* draw_line_DDM(int Xo, int Yo, int X1, int Y1)
{
    static double m;

    if((X1-Xo) == 0 && (Y1-Yo) == 0)
    {
        vector<pair<int, int>> *point = new vector<pair<int, int>>(1, make_pair(X1, Xo));
        //return a vector of one pair only

        return(point);  
    }


    else if((X1-Xo) == 0 && (Y1-Yo) != 0)
    {
        m = 1000000000.0;
    }


    else
    {
        m = (double)(Y1-Yo)/(X1-Xo);
    }


    if(abs(m)<=1)
    {
        vector<pair<int, int>> *pixels_x = new vector<pair<int, int>>(abs(X1-Xo),make_pair(0, 0));

        double y = (double)Yo;
        double x = (double)Xo;

        //for(int counter_x = 0; counter_x <(X1-Xo) ; counter_x++)
        for(vector<pair<int, int>>::iterator it = pixels_x->begin(); it != pixels_x->end(); ++it)
        {
            it->first = x;
            if(Xo>X1)
                x--;
            if(Xo<X1)
                x++;
            it->second = round(y);
            y += m;

        }
        //create a vector of x pairs

        return(pixels_x);
    }

    if(abs(m)>1)
    {
        double y = (double)Yo;
        double x = (double)Xo;
        vector<pair<int, int>> *pixels_y = new vector<pair<int, int>>(abs(Y1-Yo),make_pair(0, 0));
        //for(int counter_y = 0; counter_y <(Y1-Yo) ; counter_y++)
        for(vector<pair<int, int>>::iterator it = pixels_y->begin(); it != pixels_y->end(); ++it)
        {
            it->second = y;
            if(Yo>Y1)
                y--;
            if(Yo<Y1)
                y++;
            it->first = round(x);   
            x += 1/m;
        }

        return(pixels_y);
    }

};
0 голосов
/ 07 ноября 2018

В вашем коде много проблем, не уверен, что может охватить все. Наиболее важная проблема заключается в том, что нет причин возвращать необработанный указатель. Вместо этого верните вектор. Чтобы инициализировать вектор, вам просто нужно вызвать конструктор , который принимает количество элементов в качестве первого параметра (и обратите внимание, что std::pair имеет конструктор по умолчанию ):

#include <utility>
#include <vector>

using pair_vector = std::vector<std::pair<int,int>>;
pair_vector foo() {
    pair_vector result(20);
    return result;
}

Чтобы вернуть вектор одной пары, вы можете написать

pair_vector get_vector_with_single_pair() {
    return { {1 ,1} };
}

И если вы хотите заполнить вектор в цикле, вы можете сделать

pair_vector get_vector(int n) {
    pair_vector result;
    result.reserve( n );
    for (int i=0;i<n;++i){
        result.emplace_back( i,i );
    }
    return result;
}

(не) связанные проблемы

Здесь

if((X1-Xo) != 0 && ((Y1-Yo) == 0 || (Y1-Yo) != 0))
{
    double m = (Y1-Yo)/(X1-Xo);
}

m локально для тела if. Скорее всего, вместо этого вы захотите использовать m, объявленный в области функций. Как только вы исправите это, следующее, что нужно обнаружить, - целочисленная арифметика. Поскольку все задействованные переменные равны int s, часть (Y1-Yo)/(X1-Xo) будет использовать целочисленную арифметику, где, например, 5 / 6 == 0. Я полагаю, это не то, что вы хотите, поэтому вам нужно привести к double, прежде чем вы получите результат, например

double dy = Y1-Y0;
double dx = X1-X0;
m = dy / dx;

Более того, в некоторых случаях вы хотите вернуть вектор, содержащий Y1-Y0 элементов. Обратите внимание, что это не соответствует вашим счетчикам циклов:

for(int counter_y = Yo; counter_y <= Y1 ; counter_y++)

этот цикл имеет Y1-Y0+1 итераций, так что вы будете отключены на одну. Вы можете исправить это любым способом, но я настоятельно рекомендую вам использовать полуоткрытые интервалы, так как это то, что используют все стандартные алгоритмы. Значение, измените ваш цикл на

for(int counter_y = Y0; counter_y < Y1 ; ++counter_y)
                               // ^----------------------- Y1 is excluded

и настройте параметры, которые вы передаете соответственно.

И последнее, но не менее важное: выбирайте лучшие имена переменных. Ваш код будет намного легче читать, если, например, m будет называться slope. Для других я понятия не имею, что они есть.

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