0

I want to draw line segments between points contained in a vector and display them in a window.

Currently, this is what I have:

case WM_PAINT:
    hdc = BeginPaint(hWnd, &ps);
  //Draw lines to screen.
    using std::vector;
    using std::iterator;
    extern vector<int> euler_time;
    extern vector<int> euler_soln;
    hPen = CreatePen(PS_SOLID, 1, RGB(255, 25, 5));
    SelectObject(hdc, hPen);
    for(std::vector<int>::size_type i = 0; i != euler_time.size(); i++){
    MoveToEx(hdc,euler_time[i],euler_soln[i],NULL);
    LineTo(hdc,euler_time[i],euler_soln[i]);
    }
    EndPaint(hWnd, &ps);

This is contained in a larger .CPP source file generated as when creating a standard Win32 Application.

As you can see, my idea was to iterate through my vector using a for loop and then use LineTo and MoveToEx to go to the next point and draw a line form the previous one.

Currently I get a completely blank window with no errors. Suggestions?

EDIT:

So I'm guessing the break point message mentioned in the comments below was caused by my loading the external vector. The vector is an output of a for loop in another .CPP file.

    using std::vector;
    using std::iterator;
    extern vector<int> euler_time;
    extern vector<int> euler_soln;

And the loop in the other .CPP file:

for (double t = a; t < b; t += h )
{
    std::cout << std::fixed << std::setprecision(3) << t << " " << y << "\n";
    euler_time.insert (euler_time.begin(),t); // Insert the values of t and y into the respective vectors.
    euler_soln.insert (euler_soln.begin(),y);
    y += h * f(t, y);
}

EDIT 2:

So I started with the Polyline API. I created an array of type const POINT* called Pt and attempted to assign the values t and y_n to it. I then called Polyline and told it to draw from the array.

I end up with no errors and a blank window again.

From the Window CPP file:

    extern const POINT* Pt;
  //Draw lines to screen.
    hPen = CreatePen(PS_SOLID, 1, RGB(255, 25, 5));
    SelectObject(hdc, hPen);
    Polyline(hdc,Pt,10);

From the other CPP file:

const POINT * Pt;
void euler(F f, int y0, int a, int b, int h ) // defines a class of type     "void" (returns nothing); gives it parameters: function F, doubles: y0, a, b, h
{
int y_n = y0;
int t = a;
for (int t = a; t < b; t += h ) // creates a for loop beginning with time t = a and ending with t ~= b with stepsize h.
{
    std::cout << std::fixed << std::setprecision(3) << t << " " << y_n << "\n"; // Calls the standard output from std, with floating-point numbers with precision 3; assigns the variable t, then a space, then variable y, then a new line.
    LONG x = t;
    LONG y = y_n;
    y_n += h * f(t, y_n); // y increases by h * f(t,y) where f is the derivative y' until the condition is met y ~= b.
}
std::cout << "done\n"; // Print "done"
}

EDIT 3:

I'm now trying to use vector<POINT> to create a vector with the point values. However, my attempt results in the following error:

6   IntelliSense: no instance of overloaded function "std::vector<_Ty, _Alloc>::insert [with _Ty=POINT, _Alloc=std::allocator<POINT>]" matches the argument list
        argument types are: (std::_Vector_iterator<std::_Vector_val<std::_Simple_types<POINT>>>, double)
        object type is: std::vector<POINT, std::allocator<POINT>>   c:\Users\ahlroth\Documents\Visual Studio 2012\Projects\Euler\Euler\eulerclass.cpp   22

My code is below:

using std::vector;
vector<POINT> Pt;
POINT euler(F f, double y0, double a, double b, double h, vector<POINT> Pt) // defines a class of type "void" (returns nothing); gives it parameters: function F, doubles: y0, a, b, h
{
    double y_n = y0;
    double t = a;
    for (double t = a; t < b; t += h ) // creates a for loop beginning with time t = a and ending with t ~= b with stepsize h.
{
    std::cout << std::fixed << std::setprecision(3) << t << " " << y_n << "\n"; // Calls the standard output from std, with floating-point numbers with precision 3; assigns the variable t, then a space, then variable y, then a new line.
    Pt.insert(Pt.begin(),t);
    y_n += h * f(t, y_n); // y increases by h * f(t,y) where f is the derivative y' until the condition is met y ~= b.
}
return Pt;
std::cout << "done\n"; // Print "done"

}

The error is for this line: Pt.insert(Pt.begin(),t);

EDIT: See this post for an answer.

Community
  • 1
  • 1
Robbie Capps
  • 417
  • 1
  • 5
  • 16
  • What are the values of `t`? `a`? `b`? `h`? Second, you should be using integers, not floating point values for loop counters. If any of those values in the the `for` are `< 1.0` or is not an exact integer, that loop has a good chance of iterating a differing number of times, depending on optimizations and compiler settings. – PaulMcKenzie Feb 05 '15 at 19:57
  • `void euler(F f, double y0, double a, double b, double h ) ` It's an euler integration class. – Robbie Capps Feb 05 '15 at 20:07
  • Well, be aware that your program may run differently in `release` mode as opposed to `debug`. Floating point calculations are not exact, so be prepared for extra or missing iterations within the loop when you compare debug and release versions of your application. If you do see an issue, make sure you search SO for explanations for the differences w.r.t. floating point. – PaulMcKenzie Feb 05 '15 at 20:26

1 Answers1

2

This is because you are drawing line segments of length zero.

Only do a MoveTo on the first point, then do LineTo on the rest.

  • Thanks, but still no cigar. I end up with the same result. I tried changing to: `MoveToEx(hdc,euler_time[0],euler_soln[0],NULL);` `LineTo(hdc,euler_time[i],euler_soln[i]);` – Robbie Capps Feb 05 '15 at 19:41
  • 1
    And did you get rid of the move calls within the loop also? – 500 - Internal Server Error Feb 05 '15 at 19:43
  • Ah, so I just moved the MoveToEx() to outside the loop. Now I get: `'DrawTest.exe' (Win32): Loaded 'C:\Windows\SysWOW64\oleaut32.dll'. Cannot find or open the PDB file. Second Chance Assertion Failed: File c:\program files (x86)\microsoft visual studio 11.0\vc\include\vector, Line 1140 DrawTest.exe has triggered a breakpoint. Second Chance Assertion Failed: File c:\program files (x86)\microsoft visual studio 11.0\vc\include\vector, Line 1141 DrawTest.exe has triggered a breakpoint. Microsoft Visual Studio C Runtime Library has detected a fatal error in DrawTest.exe.` – Robbie Capps Feb 05 '15 at 19:45
  • 1
    @RobbieCapps So what is being asserted? The Visual Studio debugger should have taken you to the line that failed the assertion. – PaulMcKenzie Feb 05 '15 at 19:55
  • I'm sorry... I'm a complete novice. When I click `break`, it takes me to a line in `dbghook.c`: `void __cdecl _CRT_DEBUGGER_HOOK(int _Reserved) { /* assign 0 to _debugger_hook_dummy so that the function is not folded in retail */ (_Reserved); _debugger_hook_dummy = 0; }` – Robbie Capps Feb 05 '15 at 19:59
  • 2
    @RobbieCapps Go to the call stack and see what function *you* wrote that led to this code. It isn't the code you posted that is an error. – PaulMcKenzie Feb 05 '15 at 20:00
  • It's the vector subscript (out of range) for the MoveToEx call. – Robbie Capps Feb 05 '15 at 20:05
  • 2
    Ah. You need a `<` check instead of the `!=` check - the index is zero-based, so the last index is one less the length. – 500 - Internal Server Error Feb 05 '15 at 20:13
  • Once you get the bugs sorted out consider using the Polyline API instead of the moveto/lineto loop. Faster and easier. – ScottMcP-MVP Feb 05 '15 at 20:47
  • Ok, now I get a new break: unsigned integer position. – Robbie Capps Feb 06 '15 at 01:25
  • @ScottMcP-MVP I'm now trying to use the Polyline API; how can I assign values in a POINT array for the Polyline? – Robbie Capps Feb 06 '15 at 01:59
  • 1
    You could use a vector and replace your euler_time and euler_soln vectors with the x and y members of each POINT. – ScottMcP-MVP Feb 06 '15 at 03:06
  • @ScottMcP-MVP Could you please check EDIT 3 in my answer above? I think I'm close, but I must be missing something crucial when dealing with a vector. – Robbie Capps Feb 06 '15 at 16:51
  • 1
    The second parameter to insert needs to be a POINT. Put a POINT variable in your loop. Set its .x and .y members. Then insert the POINT. Loop again. – ScottMcP-MVP Feb 06 '15 at 18:45
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/70423/discussion-between-robbie-capps-and-scottmcp-mvp). – Robbie Capps Feb 06 '15 at 20:21