Drawing Curvilinear Figures

The program of this section demonstrates the drawing of curvilinear figures. The output of the program is shown below.

Theoretically, all drawing to a device context may be achieved through use of the functions:

However, the overhead of making a function call for each pixel is prohibitive. A device context has capabilities of drawing figures for this reason. This example makes use of the function draw_lines to draw a sine curve by estimating it with 1000 points. Many curves can be drawn by approximating with a series of points. This method hints of calculus.

The window data structure for the client declares the width and height of the client as variables and also declares an array of 1000 points as a variable, as shown below.

struct window_data
    int width_of_client,

    ipoint point_array[number_of_points];

These variables are initialized upon receiving a size notification as shown below.

   case message::size:
        window_data* data = (window_data*)get_window_pointer(window_handle, 0);

        data->width_of_client = low_part(parameter2);
        data->height_of_client = high_part(parameter2);

        for (int i = 0; i < number_of_points; i++)
            data->point_array[i](0) = i * data->width_of_client / number_of_points;
            data->point_array[i](1) = (int)(data->height_of_client / 2 * (1 - sin(two_pi * i / number_of_points)));

The C runtime function sin is used to initialize the points to approximate the outline of a sine curve. The amplitude of the sine curve is half the height of the client, whilst its period is the width of the client window. Later in the paint function, these points are rendered to the device context in a single call to draw_lines - as shown below.

    case message::paint:
        window_data* data = (window_data*)get_window_pointer(window_handle, 0);

        paint paint_structure;
        handle device_context = begin_paint(window_handle, &paint_structure);

        move_to(device_context, 0, data->height_of_client / 2);
        draw_line_to(device_context, data->width_of_client, data->height_of_client / 2);

        draw_lines(device_context, data->point_array, number_of_points);
        end_paint(device_context, &paint_structure);

Using draw_lines to draw the 1000 points approximating a sine curve is much quicker than making 1000 individual calls to the graphics subsystem. Many mathematical functions may be approximated in this fashion.