Plotting Euler Integration using Polyline(), C++

2019-06-09 02:05发布

So I'm trying to plot the output of this Euler integration function:

typedef double F(double,double);
using std::vector;

void euler(F f, double y0, double a, double b, double h,vector<POINT> Points)
{

POINT Pt;
double y_n = y0;
double t = a;
for (double t = a; t != b; t += h )

{
    y_n += h * f(t, y_n); 

    Pt.x = t; // assign the x value of the point to t.
    Pt.y = y_n; // assign the y value of the point to y_n.
    Points.push_back(Pt);

}


}


// Example: Newton's cooling law
double newtonCoolingLaw(double, double t) 
{
    return t; // return statement ends the function; here, it gives the time derivative y' = -0.07 * (t - 20)
}

I'm trying to use the Polyline() function in a Win32 application, so I do this under the case WM_PAINT:

case WM_PAINT:
    {

    hdc = BeginPaint(hWnd, &ps);

  //Draw lines to screen.

    hPen = CreatePen(PS_SOLID, 1, RGB(255, 25, 5));
    SelectObject(hdc, hPen);


    using std::vector;
    vector<POINT> Points(0);

    euler(newtonCoolingLaw, 1, 0, 20, 1,Points);

    POINT tmp = Points.at(0);
    const POINT* elementPoints[1] = { &tmp };

    int numberpoints = (int) Points.size() - 1 ;


    Polyline(hdc,elementPoints[1],numberpoints);

When I reroute my I/O to console, here are the outputs for the variables:

enter image description here

I'm able to draw the expected lines to the screen using MovetoEx(hdc,0,0,NULL) and LineTo(hdc,20,20), but for some reason none of these functions will work with my vector<POINT> Points. Any suggestions?

1条回答
时光不老,我们不散
2楼-- · 2019-06-09 02:48

There are multiple things that seem erroneous to me:

1) You should pass the vector by reference or as a return value:

void euler(/*...*/,vector<POINT>& Points)

Currently you are only passing a copy into the function, so the original vector will not be modified.

2) Don't compare doubles for (in-)equality in your for-loop header. Doubles have a limited precision, so if b is much bigger than h, your loop might never terminate, as t might never exactly match b. Compare for "smaller" instead:

for (double t = a; t < b; t += h )

3) Why are you declaring elementPoints as an array of pointers of size 1? Wouldn't a simple pointer do:

const POINT* elementPoints =  &tmp ; //EDIT: see point 5)

4) You have an of-by-one error when calling Polyline. If you want to stick with the array at all use.

Polyline(hdc,elementPoints[0],numberpoints);

EDIT: Sorry, I forgot an important one:

5) In your code, elementPoints[0] points to a single double (tmp) and not to the array inside of the vector. This would probably work, if you declared tmpas a reference:

POINT& tmp = Points.at(0); //I'm wondering why this doesn't throw an exception, as the vector should actually be empty here

However, I think what you actually want to do is to get rid of tmp and elementPoints altogether and write in the last line:

Polyline(hdc,&Points[0],(int) Points.size()-1);
//Or probably rather:
Polyline(hdc,&Points[0],(int) Points.size());

Btw.: What is the purpose of the -1?

查看更多
登录 后发表回答