// creates a polygon from a given vector RegularData1D * data void RegularData1DWidget::createPlot() { // no data => no polygon if (data_ == 0 || data_->size() == 0) { return; } // find the data min and max float min = (*data_)[0]; float max = (*data_)[0]; float dif_min = min; float old = min; //last point if (dif_min == 0) dif_min = 1; for (int i=0; i<(int)data_->size(); i++) { if ((*data_)[i] >= max) max = (*data_)[i]; if ((*data_)[i] <= min) min = (*data_)[i]; float dif = (*data_)[i] - old; if ( (dif > 1e-3) && (dif < dif_min) ) { dif_min = dif; } old = (*data_)[i]; } int height_ = (int)ceil(((max-min) / dif_min) * 5); if (height_ > 1000) { // the resulting picture would be much too large height_ = 1000; dif_min = (max - min)/200.; } // resize the canvas to fit the data canvas_.resize(5*(data_->size()+2), height_+10); int x_new; int y_new; int x_old = 5; int y_old = height_+5 - (int)((((*data_)[0]-min)/dif_min)*5); Q3CanvasLine *ql; try { for (int i=0; i<(int)data_->size(); i++) { x_new = 5*(i+1); y_new = height_+5 - (int)(((data_->getData(i)-min)/dif_min)*5); ql = new Q3CanvasLine(&canvas_); ql->setPen(diagram_color_); ql->show(); ql->setPoints(x_old, y_old, x_new, y_new); objects_.push_back(dynamic_cast<Q3CanvasItem*> (ql)); x_old = x_new; y_old = y_new; } } catch(...) { setStatusbarText("Error: Point in dataset out of grid!"); Log.error() << "Error: Point in dataset out of grid!" << std::endl; return; } //add the x-axis ql = new Q3CanvasLine(&canvas_); int startx = 1; int starty = height_+5 - (int)/*round*/(((startx-min)/dif_min)*5); int endx = data_->size()*5; ql->setPoints(startx, starty, endx, starty); ql->setPen(axis_color_); ql->show(); objects_.push_back(dynamic_cast<Q3CanvasItem*> (ql)); //add the y-axis ql = new Q3CanvasLine(&canvas_); startx = 4; starty = 0; int endy = height_+5 - (int)/*round*/((((*data_)[endx]-min)/dif_min)*5); ql->setPoints(startx, starty, startx, endy); ql->setPen(QColor(Qt::red)); ql->show(); objects_.push_back(dynamic_cast<Q3CanvasItem*> (ql)); }
void ScanForAxes::scanXAxis(const QImage& img, Q3CanvasLine& scanLine, Q3CanvasLine& bestXLine, int& xAxisRow, int& xAxisColMin, int& xAxisColMax) { ASSERT_ENGAUGE(img.height() > 2); // x axis scan starts at bottom and goes up bestXLine.setPoints(0, img.height() - 1, img.width() - 1, img.height() - 1); bestXLine.show(); // weight starts off at max value of 1 at bottom, and tapers off to 0 at top double weight = 1.0; double dWeight = 1.0 / img.height(); xAxisRow = 0; double highestCorrelation = 0.0; int row, col; bool scanEffect = DefaultSettings::instance().getScanForAxesScanEffect(); Discretize discretize; for (row = img.height() - 1; row >= 0; row--) { scanLine.setPoints(0, row, img.width() - 1, row); double correlation = 0.0; for (col = 0; col < img.width(); col++) if (row + 1 < img.height()) { // perform one-dimensional convolution with finite step function. only two-pixel // wide step function convolution kernel is needed since it will pick up axes of any width, // plus its small value reduces number of computations int pixelHigh = (discretize.processedPixelIsOn(img, col, row + 1) ? PIXEL_DARK : PIXEL_LIGHT); // should be dark at edge of axis int pixelLow = (discretize.processedPixelIsOn(img, col, row) ? PIXEL_DARK : PIXEL_LIGHT); // should be light at edge of axis correlation += pixelHigh - pixelLow; } if (weight * correlation > highestCorrelation) { xAxisRow = row + 1; // we want the row with the black values highestCorrelation = correlation; bestXLine.setPoints(0, xAxisRow, img.width() - 1, xAxisRow); updateView(img); // update so user can see newest axis candidate } if (scanEffect) updateView(img); // update so user sees nice scanning effect as scanLine moves weight -= dWeight; } // get endpoints AxisSlice rowSlice(img.width()); for (col = 0; col < img.width(); col++) rowSlice [col] = (img.pixel(col, xAxisRow) == QColor(Qt::black).rgb()); scanAxisForLowEndpoint(rowSlice, xAxisColMin); scanAxisForHighEndpoint(rowSlice, xAxisColMax); // shrink line down to the actual axis bestXLine.setPoints(xAxisColMin, xAxisRow, xAxisColMax, xAxisRow); updateView(img); }
QRect CEdge::drawTree( Q3Canvas* canvas, int left, int depth, StringToString* filter ) { int X_PADDING = 10; int Y_SPACING = 30; // int X_MARGIN = 10; unused variable 'X_Margin' int Y_MARGIN = 10; //================================================ Q3CanvasItem* edge = new Q3CanvasText( LHS(), canvas ), * leaf = NULL; Q3CanvasLine* line; m_CanvasItems.clear(); m_CanvasItems.append( edge ); int myLeft = left, myTop = ( depth * Y_SPACING ) + Y_MARGIN, myCenterX, myBottom, childCenterX, childLeft, childTop, shiftAmount; Q3ValueList<QRect> daughterBoundingRectangles; Q3ValueList<QRect>::iterator it; QRect myBoundingRect, rectangle; myBoundingRect.setTop( myTop ); myBoundingRect.setLeft( myLeft ); myBoundingRect.setBottom( myTop + edge->boundingRect().height() - 1 ); myBoundingRect.setRight( myLeft + edge->boundingRect().width() - 1 ); int count = 0; // bool first = TRUE; unused variable 'first' CEdge* daughter; for( daughter = m_Daughters.first(); daughter; daughter = m_Daughters.next() ) { daughterBoundingRectangles.append( rectangle ); daughterBoundingRectangles[count] = daughter->drawTree( canvas, left, depth + 1, filter ); // Adjust left position based on bounding rectangle of last daughter left = daughterBoundingRectangles[count].right() + X_PADDING; count++; } if( m_Daughters.isEmpty() ) { // Create leaf node childLeft = myLeft; childTop = ( ( depth + 1 ) * Y_SPACING ) + Y_MARGIN; leaf = new Q3CanvasText( Filter( filter, RHS() ), canvas ); m_CanvasItems.append( leaf ); leaf->move( childLeft, childTop ); leaf->show(); // Adjust my bounding rect if( leaf->boundingRect().right() > myBoundingRect.right() ) myBoundingRect.setRight( leaf->boundingRect().right() ); myBoundingRect.setBottom( leaf->boundingRect().bottom() ); } else { for( it = daughterBoundingRectangles.begin(); it != daughterBoundingRectangles.end(); ++it ) { // Adjust my bounding rect if( (*it).right() > myBoundingRect.right() ) myBoundingRect.setRight( (*it).right() ); if( (*it).bottom() > myBoundingRect.bottom() ) myBoundingRect.setBottom( (*it).bottom() ); } } if( myBoundingRect.width() == edge->boundingRect().width() ) { // Shift all children to the right if( m_Daughters.isEmpty() ) { shiftAmount = int (( myBoundingRect.width() - leaf->boundingRect().width() ) / 2.0); leaf->move( leaf->boundingRect().left() + shiftAmount, leaf->boundingRect().top() ); leaf->show(); } else { shiftAmount = int (( myBoundingRect.width() - ( daughterBoundingRectangles.last().right() - daughterBoundingRectangles.first().left() ) ) / 2.0); for( daughter = m_Daughters.first(); daughter; daughter = m_Daughters.next() ) { daughter->shiftTree( canvas, shiftAmount, 0 ); } for( it = daughterBoundingRectangles.begin(); it != daughterBoundingRectangles.end(); ++it ) { // Adjust the bounding rect position (*it).setLeft( (*it).left() + shiftAmount ); (*it).setRight( (*it).right() + shiftAmount ); } } } else myLeft = ( myBoundingRect.right() - ( myBoundingRect.width() / 2 ) ) - ( edge->boundingRect().width() / 2 ); if( myLeft < myBoundingRect.left() ) myLeft = myBoundingRect.left(); edge->move( myLeft, myTop ); // Draw lines to daughter nodes if( m_Daughters.isEmpty() ) { myCenterX = edge->boundingRect().center().x(); myBottom = edge->boundingRect().bottom(); childCenterX = leaf->boundingRect().center().x(); childTop = leaf->boundingRect().top(); if( myCenterX - childCenterX == 1 || myCenterX - childCenterX == -1 ) myCenterX = childCenterX; line = new Q3CanvasLine( canvas ); line->setPoints( myCenterX, myBottom, childCenterX, childTop ); line->show(); m_CanvasItems.append( line ); } else { Q3ValueList<QRect>::iterator it; for( it = daughterBoundingRectangles.begin(); it != daughterBoundingRectangles.end(); ++it ) { myCenterX = edge->boundingRect().center().x(); myBottom = edge->boundingRect().bottom(); childCenterX = (*it).center().x(); childTop = (*it).top(); if( myCenterX - childCenterX == 1 || myCenterX - childCenterX == -1 ) myCenterX = childCenterX; line = new Q3CanvasLine( canvas ); line->setPoints( myCenterX, myBottom, childCenterX, childTop ); line->show(); m_CanvasItems.append( line ); } } edge->show(); canvas->update(); return myBoundingRect; }