0

Hello I am a relatively new programmer with C++. I had a question about my code

I have a point 2d class that has a double x and y.

I am trying the following nested loop:

Point2D Dec(float t)
{
    Point2D Temp;
    vector<Point2D>Bcopy=H->B;
    for(int p=0;p<Bcopy.size()-1;p++){
       for(int l=p;l<Bcopy.size();l++){
           Temp=(1-t)*Bcopy.at[p][l-1]+t*Bcopy.at[p+1][l-1];
       }
    }
    return Temp;
}

So essentially there is another class that has a vector with point 2d B and H is the pointer to it. These are storing the points from mouse interaction etc and drawing them. So i just created a copy of it and then did the above nested loop and then I use the points to draw them too.

I keep getting the following two errors:

std::vector<Point2D,std::allocator<-Ty>>::at':function call missing argument list;use'&std::vector<Point2D,std::allocator<_Ty>>:at' to create a pointer to member

and

subscript requires array or pointer.

Both these errors are for the line

Temp=(1-t)*Bcopy.at[p][l-1]+t*Bcopy.at[p+1][l-1]

in the code

I have tried many different things and I either keep getting more errors or just these two. I tried to google and understand the errors but couldn't really. Any help would be much appreciated

Thank you

EDIT After much playing around

I did the following:

vector<2D>NewBcopy; 
 double Rx=0 ,Ry=0; 
 for(int p=0;p<Bcopy.size()-1;p++){ 
 for(int l=p;l<Bcopy.size();l++){ 
 if(l==p)
 {Newcopy.at(l)=Bcopy.at(l); 
 }
 else 
 {Rx=(1-t)*Bcopy.at(p).x+t*Bcopy.at(p+1).x; 
 Ry=(1-t)*Bcopy.at(p).y+t*Bcopy.at(p+1]).y:
 }
 Temp.x=Rx;
 Temp.y=Ry;
 }
 }
 return Temp;
 }
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
  • 4
    BTW, the error message is telling you that `at` wants round parentheses, not square brackets. – Fabio Somenzi Feb 23 '17 at 16:10
  • Also both your `for` loops are missing the closing parentheses (after the increments) – UnholySheep Feb 23 '17 at 16:18
  • Sorry for not posting it on stackoverflow. I didn't realize matchexchange and stackoverflow were different. Sorry about that. – PurCoutinho Feb 23 '17 at 16:32
  • @UnholySheep I do have the closing parenthesis. I just didn't copy it here by mistake. My bad again – PurCoutinho Feb 23 '17 at 16:32
  • 1
    lol... we have a Mathematica user on C++ xD – The Quantum Physicist Feb 23 '17 at 16:35
  • @FabioSomenzi When I do that it gives me the error saying term does not evaluate to a function taking 1 arguement and call of an object of a class type without appropriate operator() or conversion functions to pointer to function type. It might because I am not calling classes properly. thank you again – PurCoutinho Feb 23 '17 at 16:37
  • Also if a `Point2D` only has `x` and `y` values then what is `[l-1]` supposed to access? – UnholySheep Feb 23 '17 at 16:41
  • @UnholySheep makes a good point. You are also probably right about not being familiar enough with the class you are using. – Fabio Somenzi Feb 23 '17 at 16:46
  • @UnholySheep I am trying to implement the decasteljau algorithm or linera interpolation using recurrence – PurCoutinho Feb 23 '17 at 16:46
  • @FabioSomenzi Essentially I get points by the user and I think they are being stored in vector B. These points have x and y coordinates. I then tried to make a copy of it and then interpolate on these points to get new points. – PurCoutinho Feb 23 '17 at 16:50
  • So your `Point2D` class overloads `operator[]` and `operator=`? I believe at this point the class definition is becoming highly relevant to this question and should be included – UnholySheep Feb 23 '17 at 16:51
  • IMO, the `Point2D` class should represent one pair of coordinates, and not be a container. Thus `operator[]` is, IMO, not necessary. – Thomas Matthews Feb 23 '17 at 16:53
  • @UnholySheep its just a simple class Point2D { Public: double x,y;}; – PurCoutinho Feb 23 '17 at 16:55
  • @ThomasMatthews can't change that class. Gotta be that and use it if possible – PurCoutinho Feb 23 '17 at 16:56
  • Got another struct curveature { vector<2Dpoint>B} – PurCoutinho Feb 23 '17 at 16:59
  • As @FabioSomenzi indicates, vector::at is a function (as in [vector Class](https://msdn.microsoft.com/en-us/library/9xd04bzs.aspx#vector__at)) therefore you want Bcopy.at() but since you have two pairs of square brackets I am not sure what it should be. – Sam Hobbs Feb 23 '17 at 17:44
  • If all your class has is two members of type `double` then the line `Temp=(1-t)*Bcopy.at[p][l-1]+t*Bcopy.at[p+1][l-1];` simply doesn't make any sense - there is no way this can be correct at all. – UnholySheep Feb 23 '17 at 18:27
  • You are only returning the last computed value of Temp. You are ignoring most of the calculation that you are doing. Are you supposed to be adding to Temp each time through the loops? – stark Feb 23 '17 at 18:41
  • @UnholySheep you are right. I played around a bit and got a differentloop @stark Yah supposed to add to the loop. I changed the code around a bit.I created another `vector<2D>NewBcopy; double Rx=0 ,Ry=0; for(int p=0;p – PurCoutinho Feb 23 '17 at 19:03
  • and then I said 'Temp.x=Rx;Temp.Y=Ry; outside the else brackets and then return Temp. After doing this I don't get any error but my screen shows up white instead of giving a black screen where I can draw ( I am using opengl). After the exe is kept open for a while the debugger says Temp isn't initialized. – PurCoutinho Feb 23 '17 at 19:10
  • It's not a good idea to put relevant code into comments, as people looking at the question will miss it (and it's also not formatted nicely) - please edit it into the actual question. – UnholySheep Feb 23 '17 at 19:13
  • @UnholySheep Done – PurCoutinho Feb 23 '17 at 19:30

2 Answers2

1

You should first start learning C++ before you start difficult algorithms. Your (non-working) code should look more like this.

#include <vector>
using std::vector;

struct Point2D
{
    double x, y;
};

Point2D Dec(double t)
{
    Point2D Temp;
    vector<Point2D> Bcopy = H->B; // Fails: what is H?
    for (auto p = 0; p < Bcopy.size() - 1; p++)
    {
        for (auto l = p; l < Bcopy.size(); l++)
        {
            // Fails: Bcopy is not 2-dimensional
            Temp = (1 - t) * Bcopy[p][l - 1] + t * Bcopy[p + 1][l - 1];
        }
    }
    vector<Point2D> NewBcopy;
    double Rx = 0, Ry = 0;
    for (auto p = 0; p < Bcopy.size() - 1; p++)
    {
        for (auto l = p; l < Bcopy.size(); l++)
        {
            if (l == p)
            {
                NewBcopy[l] = Bcopy[l];
            }
            else
            {
                Rx = (1 - t)*Bcopy[p].x + t*Bcopy[p + 1].x;
                Ry = (1 - t)*Bcopy[p].y + t*Bcopy[p + 1].y;
            }
            Temp.x = Rx;
            Temp.y = Ry;
        }
    }
    return Temp;
}
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
JHBonarius
  • 10,824
  • 3
  • 22
  • 41
  • H is a pointer to vector B which is storing all the points from the user. And yes , I plan on learning C++ properly this weekend but the algorithm is from another subject I am learning – PurCoutinho Feb 23 '17 at 20:37
  • @PurCoutinho C++ is definitely not a language you can learn in a weekend (no programming language really is) - it's actually probably one of the harder languages to learn (I've been learning and using C++ for years and I'd still only consider myself to be intermediate at it) – UnholySheep Feb 23 '17 at 20:46
  • @UnholySheep Haha yah i meant to say starting this weekend. I have been learning it for a while too but not with full focus. I have always used Matlab for everything . But there are many resources online for C++ so I should utilize it. – PurCoutinho Feb 23 '17 at 21:01
1

You can expand your class representing a 2D point by adding some functions that perform mathematical operations between points and scalars. A minimal example is something like this:

class Point2D
{
public:
    double x, y;

    Point2D(double xx = 0.0, double yy = 0.0) : x{xx}, y{yy} {}
};

Point2D operator*(const Point2D &p, double s)
{
    return Point2D{p.x * s, p.y *s};
}

Point2D operator+(const Point2D &a, const Point2D &b)
{
    return Point2D{a.x + b.x, a.y + b.y};
}

After that, implementing algorithms like the De Castleljau is a bit more easy. The following is a possible (unoptimized) implementation:

Point2D De_Casteljau(std::vector<Point2D> B, double t)
{
    for ( int i = 0; i < B.size() - 1; ++i )
    {
        for ( int j = 0; j < B.size() - 1 - i ; ++j )
        {
            B[j] = B[j] * (1.0 - t) + B[j + 1] * t;
        }
    }
    return B[0];
}

I tested it with this simple program:

#include <iostream>
#include <vector>
#include <iomanip>

//... include here the preceding snippets... 

int main()
{
    using std::setw;
    std::vector<Point2D> B {
        {0,0}, {0,1}, {2,1}, {2,2}
    };

    std::cout << "   t      x       y\n";
    for ( double i = 0; i <= 1.0; i += 0.1 )
    {
        auto p = De_Casteljau(B, i);
        std::cout << std::fixed << std::setprecision(2) << setw(6) << i
                  << std::setprecision(4) << setw(8) << p.x
                  << setw(8) << p.y << '\n';
    }
    return 0;
}

which gave the following results:

   t      x       y
  0.00  0.0000  0.0000
  0.10  0.0560  0.2720
  0.20  0.2080  0.4960
  0.30  0.4320  0.6840
  0.40  0.7040  0.8480
  0.50  1.0000  1.0000
  0.60  1.2960  1.1520
  0.70  1.5680  1.3160
  0.80  1.7920  1.5040
  0.90  1.9440  1.7280
  1.00  2.0000  2.0000
Bob__
  • 12,361
  • 3
  • 28
  • 42
  • I like this solution, but unfortunately OP mentioned in the comments that the class `Point2D` should not be modified (so it should only contain the members `x` and `y`) – UnholySheep Feb 23 '17 at 20:43
  • 1
    @UnholySheep Well, I've implemented `operator*` and `operator+` as free functions... It may be enough ;) – Bob__ Feb 23 '17 at 20:46
  • @Bob__ I like this solution too but there are other functions and things involved. Plus I have to implement for n number of points. Thank you though. I learned a few things from this code – PurCoutinho Feb 23 '17 at 21:06
  • `++i` in for statements is no longer required with current compilers... They know what you mean. – JHBonarius Feb 24 '17 at 08:28
  • 1
    @J.H.Bonarius Are you referring to the use of the prefixed version of operator++ instead of the postfixed one? Well, for POD types it has always been a matter of style, rather then a performance concern... – Bob__ Feb 24 '17 at 09:25
  • Well no, to my understanding before compilers optimized this, it would be like this http://stackoverflow.com/a/25657/6717178 http://stackoverflow.com/a/4445969/6717178. So postfix would use more operations. However, nowadays compilers know this, and you should just focus on writing maintainable code. – JHBonarius Feb 24 '17 at 11:07