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:
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?
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 tmp
as 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
?