tags:

views:

55

answers:

2

I have a problem due to my terrible math abilities, that I cannot figure out how to scale a graph based on the maximum and minimum values so that the whole graph will fit onto the graph-area (400x420) without parts of it being off the screen (based on a given equation by user).

Let's say I have this code, and it automatically draws squares and then the line graph based on these values. What is the formula (what do I multiply) to scale it so that it fits into the small graphing area?

vector<int> m_x;
vector<int> m_y; // gets automatically filled by user equation or values

int HeightInPixels = 420;// Graphing area size!!
int WidthInPixels = 400;
int best_max_y = GetMaxOfVector(m_y);
int best_min_y = GetMinOfVector(m_y);
m_row = 0;
m_col = 0;

y_magnitude = (HeightInPixels/(best_max_y+best_min_y)); // probably won't work
x_magnitude = (WidthInPixels/(int)m_x.size());
m_col = m_row = best_max_y; // number of vertical/horizontal lines to draw

////x_magnitude = (WidthInPixels/(int)m_x.size())/2; Doesn't work well
////y_magnitude = (HeightInPixels/(int)m_y.size())/2; Doesn't work well

ready = true; // we have values, graph it
Invalidate(); // uses WM_PAINT

////////////////////////////////////////////
/// Construction of Graph layout on WM_PAINT, before painting line graph
///////////////////////////////////////////
CPen pSilver(PS_SOLID, 1, RGB(150, 150, 150) ); // silver
    CPen pDarkSilver(PS_SOLID, 2, RGB(120, 120, 120) ); // dark silver
    dc.SelectObject( pSilver ); // silver color
    CPoint pt( 620, 620 ); // origin
    int left_side = 310;
    int top_side = 30;
    int bottom_side = 450;
    int right_side = 710; // create a rectangle border
    dc.Rectangle(left_side,top_side,right_side,bottom_side);
    int origin = 310;
    int xshift = 30;
    int yshift = 30;
    // draw scaled rows and columns
    for(int r = 1; r <= colrow; r++){ // draw rows
        pt.x = left_side;
        pt.y = (ymagnitude)*r+top_side;
        dc.MoveTo( pt );
        pt.x = right_side;
        dc.LineTo( pt );
        for(int c = 1; c <= colrow; c++){
            pt.x = left_side+c*(magnitude);
            pt.y = top_side;
            dc.MoveTo(pt);
            pt.y = bottom_side;
            dc.LineTo(pt);
        } // draw columns
    }
    // grab the center of the graph on x and y dimension
    int top_center = ((right_side-left_side)/2)+left_side;
    int bottom_center = ((bottom_side-top_side)/2)+top_side;
A: 

What I did was to determine how many points I had going in the x and y directions, and then divide that by the x and y dimensions, then divide that by 3, as I wanted each minimum point to be three pixels, so it could be seen.

The trick then is that you have to aggregate the data so that you are showing several points with one point, so it may be the average of them, but that depends on what you are displaying.

Without knowing more about what you are doing it is hard to make a suggestion.

For this part, subtract, don't add: best_max_y+best_min_y as you want the difference.

The only other thing would be to divide y_magnitude and x_magnitude by 3. That was an arbitrary number I came up with, just so the users could see the points, you may find some other number to work better.

James Black
I'm doing a simple a*x^2 + b*x + c equation graph. Only a,b,c can be changed by user. I set x to be 20 data points from -10 to 10.I also allow user to enter manual data points.For me y_magnitude determines the number of pixels between rows. for(int r = 1; r <= colrow; r++){ // draw rows pt.x = left_side; pt.y = (ymagnitude)*r+top_side; dc.MoveTo( pt ); pt.x = right_side; dc.LineTo( pt );((("colrow" is just equal to m_col and m_row. And your suggestion of #points/height/3 doesnt work. It comes out to a fraction number, 20/420/3)))
Dexter
You may want to add this info as an update to your question, it may be very useful. I am getting ready for work, if there isn't a better answer today I will see about answering tonight.
James Black
A: 

You are using a*x^2 + b*x + c (quadratic equation). You will get list of (X,Y) values inserted by user.
Let us say 5 points you get are
(1,1) (2,4) (4,1) (5,6) (6,7)

So, here your best_max_y will be 7 and best_min_y will be 1.
Now you have total graph area is
Dx = right_side - left_side //here, 400 (710 - 310)
Dy = bottom_side - top_side //here, 420 (450 - 30)

So, you can calculate x_magnitude and y_magnitude using following equation :

x_magnitude = WidthInPixels / Dx;
y_magnitude = HeightInPixels / Dy;

Himadri