Example #1
0
bool Slider::onMouseMove(int x, int y)
{
    if (dragging) {
        float val = xToValue(x - left - dragOffsetX);
        if (val != value) {
            value = val;
            draw();
        }
        return true;
    }

    bool in = isInRect(x, y, left, top, width, height);
    if (in) {
        int sliderX = valueToX(value);
        bool hl = isInRect(x, y, left + sliderX, top, height, height);
        if (hl != highlight) {
            highlight = hl;
            draw();
        }
    } else if (highlight) {
        highlight = false;
        draw();
    }
    return in;
}
Example #2
0
void Slider::draw()
{
    if (! background)
        createBackground();
    screen.draw(left, top, background);
    screen.addRegionToUpdate(left, top, width, height);
    int posX = valueToX(value);
    SDL_Surface *s = highlight ? activeSlider : slider;
    screen.draw(left + posX, top, s);
}
void BifurcationPlot::drawMdacLine(wxDC* dc) {
    /**
    *   Draws the line for the MDAC on the graph so the user can see where
    *   they are on the bifurcation diagram.
    */
    //Use red pen
    wxPen redPen(*wxRED, 1); // red pen of width 1
    
    dc->SetPen(redPen);
    int x = valueToX(device_mdac_value);
    dc->DrawLine(x, top_gutter_size, x, graph_height+ top_gutter_size);
}
Example #4
0
bool Slider::onMouseButtonDown(int button, int x, int y)
{
    bool in = isInRect(x, y, left, top, width, height);
    if (in) {
        int sliderX = valueToX(value);
        bool hl = isInRect(x, y, left + sliderX, top, height, height);
        if (hl) {
            dragging = true;
            dragOffsetX = x - left - sliderX;
        }
    }
    return in;
}
void BifurcationPlot::drawPlot() {
    /**
    *   Main drawing function for the plot classes.
    *
    *   The bifurcation plot is stored in a wxBitmap object so that we don't
    *   have to recalculate and draw every point every time we refresh the
    *   screen.  Since all of the ChaosPlots are buffered, this means that
    *   the Bifurcation drawing functions actually go through two buffers.
    *   This is not the most efficient way to do this, but it does allow us
    *   to use the functionality of the ChaosPlot subclass.
    *
    *   Steps for drawing:
    *
    *   Calculate X & Y axis values and size.
    *
    *   Store our current size.
    *
    *   Calls startDraw() to initalize the drawing DC. (Updates size)
    *
    *   Compare old size with current size to determine if it needs to redraw everything.
    *
    *   If so, draw axis on BufferedDC and copy them over to the MemoryDC,
    *   then redraw all points.
    *
    *   If not, collect points for up to 2 MDAC values and only draw 
    *   the new points on the MemoryDC.
    *
    *   Draw the MDAC reference line on the graph.
    *
    *   Finally, copy the MemoryDC over to the BufferedDC and draw it to the DC.
    *
    */
    float x_min, x_max;
    float y_min, y_max;
    wxString xaxis_title;
    wxMemoryDC bifMemDC;
    
    // Get information for the X axis
    if(ChaosSettings::BifXAxis == ChaosSettings::MDAC_VALUES) {
        xaxis_title = wxString(wxT("Mdac values"));
    } else {
        xaxis_title = wxString(wxT("Resistance (Ohms)"));
    }

    // Get scaling/label information for the Y axis
    if(ChaosSettings::YAxisLabels == ChaosSettings::Y_AXIS_VGND) {
        graph_subtitle = wxString::Format(wxT("Peaks (V) vs. %s"), xaxis_title.c_str());
        y_min = smallest_y_value*3.3/1024;
        y_max = largest_y_value*3.3/1024;
        x_min = smallest_x_value*3.3/1024;
        x_max = largest_x_value*3.3/1024;
    } else if(ChaosSettings::YAxisLabels == ChaosSettings::Y_AXIS_VBIAS) {
        graph_subtitle = wxString::Format(wxT("Peaks (V) vs. %s"), xaxis_title.c_str());
        y_min = smallest_y_value*3.3/1024 - 1.2;
        y_max = largest_y_value*3.3/1024 - 1.2;
        x_min = smallest_x_value*3.3/1024 - 1.2;
        x_max = largest_x_value*3.3/1024 - 1.2;
    } else {
        graph_subtitle = wxString::Format(wxT("Peaks (ADC) vs. %s"), xaxis_title.c_str());
        y_min = smallest_y_value;
        y_max = largest_y_value;
        x_min = smallest_x_value;
        x_max = largest_x_value;
    }
    
    // Store old size information for future comparison
    int old_width = width;
    int old_height = height;
    
    // Update size and draw background & titles
    startDraw();
    
    // Check and see if the size of the graph has changed
    // If it has, we need to redraw our cached image
    if(old_width != width || old_height != height) {
        ChaosSettings::BifRedraw = true;
    }
    
    // Do we need to redraw everything that we have cached?
    if(ChaosSettings::BifRedraw == true) {
        // Draw the Y axis on the buffered DC
        drawYAxis(y_min, y_max, (y_max-y_min)/4.0);
        
        // Draw the X axis on the buffered DC
        if(ChaosSettings::BifXAxis == ChaosSettings::MDAC_VALUES) { 
            drawXAxis(float(largest_x_value),
                  float(smallest_x_value),
                  -1*((largest_x_value-smallest_x_value)/4));
        } else {
            float min = libchaos_mdacToResistance(largest_x_value);
            float max = libchaos_mdacToResistance(smallest_x_value);
            drawXAxis(min, max, ((max-min)/4));
        }
        
        // If we aren't connected, then we're done
        if(device_connected == false) {
            endDraw();
            return;
        }

        // if we already have a cached image, delete it
        if(bifBmp)
            delete bifBmp;
            
        // Create a bitmap to cache our bifurcation drawing to
        bifBmp = new wxBitmap(width, height);
        
        // Select the bitmap to a memory DC so we can draw on it and initialize it with a background
        bifMemDC.SelectObject(*bifBmp);
        bifMemDC.SetBrush(dc->GetBackground());
        bifMemDC.SetPen(*wxTRANSPARENT_PEN);
        bifMemDC.DrawRectangle(0,0,width,height);
        
        // Copy what we have on the buffer so far (title, axis, labels) to the cache
        bifMemDC.Blit(0, 0, width, height, buffer, 0, 0);
    } else {
        // No need to redraw everything, just select the cache so we can draw more onto it
        bifMemDC.SelectObject(*bifBmp);
    }

    //Use blue pen
    wxPen bluePen(*wxBLUE, 1); // blue pen of width 1
    wxBrush blueBrush(*wxBLUE_BRUSH);
    bifMemDC.SetPen(bluePen);
    bifMemDC.SetBrush(blueBrush);

    int* peaks;
    int new_points;
    int step = (int)(float(graph_width) / float(ChaosSettings::BifStepsPerWindow));
    
    if(step == 0) step = 1;
    
    // If we are paused, don't collect new data points
    if(paused || ChaosSettings::Paused) {
        new_points = 0;
    } else {
        new_points = 2;
        libchaos_disableFFT();
    }


    // Draw points, collecting new data if necessary.
    int miss_mdac = -1;
    for(int i = 1; i < graph_width; i+=step) {
        int mdac_value = xToMdac(i);
        
        /* Since the user can technically zoom into areas slightly beyond
        our mdac limits, we have to ensure we have a correct value. */
        if (mdac_value > 4095) {
            mdac_value = 4095;
        } else if (mdac_value < 0) {
            mdac_value = 0;
        }
        
        bool cacheHit = libchaos_peaksCacheHit(mdac_value);

        if(!cacheHit) new_points--;
        if((ChaosSettings::BifRedraw && cacheHit) || (!cacheHit && new_points > 0)) {

            peaks = libchaos_getPeaks(mdac_value);
            if(cacheHit == false) {
                miss_mdac = mdac_value;
            }
            
            bifMemDC.SetPen(bluePen);
            for(int j = 0; j < ChaosSettings::PeaksPerMdac; j++) {
                int y = valueToY(peaks[j]);
                if(y < graph_height + top_gutter_size && y > top_gutter_size) {
                    drawPoint(&bifMemDC, valueToX(mdac_value), y);
                }
            }
        }
        
    }
    
    if( new_points > 0 ) libchaos_enableFFT();
    
    if(miss_mdac != -1) {
        device_mdac_value = miss_mdac;
    }
    
    // We're finished redrawing everything, so don't do it again unless we need to
    if(ChaosSettings::BifRedraw == true) {
        ChaosSettings::BifRedraw = false;
    }

    // Copy our cache onto the buffered DC
    // (It is redundant to use a MemoryDC and a BufferedDC, it may be more efficient
    // to not use the BufferedDC for the bifurcation)
    buffer->Blit(0,0, width, height, &bifMemDC, 0, 0);
    
    // Draw the line for the MDAC
    drawMdacLine(buffer);
    
    // Flush the buffer and output to the screen.
    endDraw();

}
void Rotating3dPlot::drawPlot() {
    /**
    *   Main drawing function for the ChaosPlot classes.
    *
    *   Draws a rotating 3d plot by graphing xdot vs the formula:
    *       x*cos(a*n) + x''*sin(a*n)
    *
    *   In order to get this to look like it is rotating around it's axis
    *   instead of around the outside of a merry-go-round, we must subtract
    *   the bias from our ADC values before we calculate the rotation.
    *   bias = 2V/5V*1024 = 409
    */
    const float a = 2*3.14159/25;
    const int bias = 409;
    int x1,x2,x1_old,x2_old,x3;
    
    startDraw();
    float y_min, y_max;
    if(ChaosSettings::YAxisLabels == ChaosSettings::Y_AXIS_VGND) {
        graph_subtitle = wxT("-X' (V) vs. X (V)");
        y_min = smallest_y_value*3.3/1024;
        y_max = largest_y_value*3.3/1024;
    } else if(ChaosSettings::YAxisLabels == ChaosSettings::Y_AXIS_VBIAS) {
        graph_subtitle = wxT("-X' (V) vs. X (V)");
        y_min = smallest_y_value*3.3/1024 - 1.2;
        y_max = largest_y_value*3.3/1024 - 1.2;
    } else {
        graph_subtitle = wxT("-X' (ADC) vs. X (ADC)");
        y_min = smallest_y_value;
        y_max = largest_y_value;
    }

    drawYAxis(y_min, y_max, (y_max-y_min)/4.0);

    if(device_connected == false) {
        endDraw();
        return;
    }
    
    //Use red pen
    wxPen pen(*wxRED, 1); // red pen of width 1
    buffer->SetPen(pen);
    
    // Get first plot point
    libchaos_getPlotPoint(&x1,&x2,&x3, 0);
    
    // x1 = x*cos(a*n)+x3*sin(a*n), but we have to subtract the bias from it
    // so that it rotates around the origin, we then add bias so it is visible
    x1 = valueToX(int((x1 - bias)*cos(a*timer_ticks) + (x3-bias)*sin(a*timer_ticks))+bias);
    x2 = valueToY(x2);
    x1_old = x1;
    x2_old = x2;
    
    // Repeat the above math for all the other points and graph them.
    for(int i = 1; i < libchaos_getNumPlotPoints(); i++) {
        libchaos_getPlotPoint(&x1,&x2,&x3, i);
        x1 = valueToX(int((x1 - bias)*cos(a*timer_ticks) + (x3-bias)*sin(a*timer_ticks))+bias);
        x2 = valueToY(x2);
        if(x1 > side_gutter_size && 
           x2 < (graph_height + top_gutter_size) && x2 > top_gutter_size && 
           x1_old > side_gutter_size && 
           x2_old < (graph_height + top_gutter_size) && x2_old > top_gutter_size) {
            buffer->DrawLine(x1_old,x2_old,x1,x2);
        }
        x1_old = x1;
        x2_old = x2;
    }
    
    // Display buffer
    endDraw();
}
Example #7
0
void XYPlot::drawPlot() {
    /**
    *   Main drawing function for the XYPlot class.
    *
    *   Calculates the units for the axis and then draws them
    *   Draws an XY phase portrait by graphing -X' vs. X
    *
    *   All size & plotting related functions should be handled using
    *   the 'smallest/largest_x/y_value' variables. These variables control
    *   the zooming on the graph.
    */
    int x1,x2,x1_old,x2_old,x3;
    
    startDraw();
    float x_min, x_max;
    float y_min, y_max;
    if(ChaosSettings::YAxisLabels == ChaosSettings::Y_AXIS_VGND) {
        graph_subtitle = wxT("-X' (V) vs. X (V)");
        y_min = smallest_y_value*3.3/1024;
        y_max = largest_y_value*3.3/1024;
        x_min = smallest_x_value*3.3/1024;
        x_max = largest_x_value*3.3/1024;
    } else if(ChaosSettings::YAxisLabels == ChaosSettings::Y_AXIS_VBIAS) {
        graph_subtitle = wxT("-X' (V) vs. X (V)");
        y_min = smallest_y_value*3.3/1024 - 1.2;
        y_max = largest_y_value*3.3/1024 - 1.2;
        x_min = smallest_x_value*3.3/1024 - 1.2;
        x_max = largest_x_value*3.3/1024 - 1.2;
    } else {
        graph_subtitle = wxT("-X' (ADC) vs. X (ADC)");
        y_min = smallest_y_value;
        y_max = largest_y_value;
        x_min = smallest_x_value;
        x_max = largest_x_value;
    }
    
    drawYAxis(y_min, y_max, (y_max-y_min)/6.0);
              
    drawXAxis(x_min, x_max, (x_max-x_min)/6.0);

    if(device_connected == false) {
        endDraw();
        return;
    }
    
    //Use red pen
    wxPen pen(*wxRED, 1); // red pen of width 1
    buffer->SetPen(pen);
    
    // Get first plot point
    libchaos_getPlotPoint(&x1,&x2,&x3, 0);
    x1 = valueToX(x1);
    x2 = valueToY(x2);
    x1_old = x1;
    x2_old = x2;
    
    for(int i = 1; i < libchaos_getNumPlotPoints(); i++) {
        libchaos_getPlotPoint(&x1,&x2,&x3, i);
        x1 = valueToX(x1);
        x2 = valueToY(x2);
        if(x1 > side_gutter_size && 
           x2 < (graph_height+top_gutter_size) && x2 > top_gutter_size &&
           x1_old > side_gutter_size && 
           x2_old < (graph_height+top_gutter_size) && x2_old > top_gutter_size) {
            buffer->DrawLine(x1_old,x2_old,x1,x2);
        }
        x1_old = x1;
        x2_old = x2;
    }
    
    // Display buffer
    endDraw();
}