// ------------------------------------------------------------- void Graph::drawLines(int x0, int y0, ViewPainter *p) const { float DX_, DY_; float x1, x2, y1, y2; auto Scale = p->Scale; auto Painter = p->Painter; auto pp = begin(); if(pp->Scr < 0) pp++; DX_ = p->DX + float(x0)*Scale; DY_ = p->DY + float(y0)*Scale; while(!pp->isGraphEnd()) { if(pp->Scr >= 0) { x1 = DX_ + (pp)->Scr*Scale; y1 = DY_ - (pp+1)->Scr*Scale; Painter->drawPoint(QPointF(x1, y1)); } while(!pp->isBranchEnd()) { x1 = DX_ + (pp)->Scr*Scale; y1 = DY_ - (pp+1)->Scr*Scale; pp += 2; while(!pp->isStrokeEnd()) { x2 = DX_ + (pp)->Scr*Scale; y2 = DY_ - (pp+1)->Scr*Scale; Painter->drawLine(QLineF(x1, y1, x2, y2)); pp += 2; if(pp->isStrokeEnd()) break; x1 = DX_ + pp->Scr*Scale; y1 = DY_ - (pp+1)->Scr*Scale; Painter->drawLine(QLineF(x2, y2, x1, y1)); pp += 2; } if(pp->isBranchEnd()) break; pp++; } pp++; } }
int Graph::getSelectedP(int x, int y) { float f1,f2,f3,f4; float xn,yn; float d1,b1; auto pp = ScrPoints.begin(); if(pp == ScrPoints.end()) return -1; if(pp->isStrokeEnd()) pp++; while(!pp->isGraphEnd()) { if(!pp->isBranchEnd()) { f1 = pp->getScrX(); f2 = (pp++)->getScrY(); f3 = pp->getScrX(); f4 = (pp++)->getScrY(); if((f1 > f3 - 5) && (f1 < f3 + 5)) { xn = f1; yn = y; } else { if((f2 > f4 - 5) && (f2 < f4 + 5)) { xn = x; yn = f2; } else { d1 = (f4 - f2) / (f3 - f1); b1 = f4 - d1 * f3 ; xn = (float(y) - b1) / d1; yn = d1 * float(x) + b1; } } if(((f1 >= f3) && (xn >= f3) && (xn <= f1)) || ((f3 >= f1) && (xn >= f1) && (xn <= f3))) if(((f2 >= f4) && (yn >= f4) && (yn <= f2)) || ((f4 >= f2) && (yn >= f2) && (yn <= f4))) if((y >= int(yn) - 5) && (y <= int(yn) + 5) && (x >= int(xn) - 5) && (x <= int(xn) + 5)) return 1; } else pp++; } return -1; }
/*! * Checks if the coordinates x/y point to the graph. returns the number of the * branch of the graph, -1 upon a miss. * * x/y are relative to diagram cx/cy. 5 is the precision the user must point * onto the graph. * * FIXME: should return reference to hit sample point or some context. */ int Graph::getSelected(int x, int y) { auto pp = ScrPoints.begin(); if(pp == ScrPoints.end()) return -1; int A, z=0; int dx, dx2, x1; int dy, dy2, y1; int countX = cPointsX.at(0)->count; if(pp->isStrokeEnd()) { if(pp->isBranchEnd()) z++; pp++; if(pp->isBranchEnd()) { if(pp->isGraphEnd()) return -1; // not even one point ? z++; pp++; if(pp->isGraphEnd()) return -1; // not even one point ? } } if(Style >= GRAPHSTYLE_STAR || gy!=NULL) { // for graph symbols while(!pp->isGraphEnd()) { if(!pp->isStrokeEnd()) { dx = x - int((pp)->getScrX()); dy = y - int((pp++)->getScrY()); if(dx < -5) continue; if(dx > 5) continue; if(dy < -5) continue; if(dy > 5) continue; return z*countX; // points on graph symbol } else { z++; // next branch pp++; } } return -1; } // for graph lines while(!pp->isGraphEnd()) { while(!pp->isBranchEnd()) { x1 = int(pp->getScrX()); y1 = int((pp++)->getScrY()); dx = x - x1; dy = y - y1; if(pp->isPt()){ dx2 = int(pp->getScrX()); }else if(pp->isBranchEnd()) { break; }else if(pp->isStrokeEnd()) { pp++; dx2 = int(pp->getScrX()); // go on as graph can also be selected between strokes if(pp->isBranchEnd()) break; } if(dx < -5) { if(x < dx2-5) continue; } // point between x coordinates ? else { if(x > 5) if(x > dx2+5) continue; } dy2 = int(pp->getScrY()); if(dy < -5) { if(y < dy2-5) continue; } // point between y coordinates ? else { if(y > 5) if(y > dy2+5) continue; } dx2 -= x1; dy2 -= y1; A = dx2*dy - dx*dy2; // calculate the rectangle area spanned A *= A; // avoid the need for square root A -= 25*(dx2*dx2 + dy2*dy2); // substract selectable area if(A <= 0) return z*countX; // lies x/y onto the graph line ? } pp++; z++; } return -1; }
/*! * draw a (line) graph from screen coord pairs */ void Graph::drawLines(int x0, int y0, QPainter *p) const { float DX_, DY_; float x1, y1; auto Scale = 1; /// \todo p->Scale; auto Painter = p; QVector<qreal> dashes; double Stroke=10., Space=0.; switch(Style) { case GRAPHSTYLE_DASH: Stroke = 10.; Space = 6.; break; case GRAPHSTYLE_DOT: Stroke = 2.; Space = 4.; break; case GRAPHSTYLE_LONGDASH: Stroke = 24.; Space = 8.; break; default: break; } QPen pen = Painter->pen(); switch(Style) { case GRAPHSTYLE_DASH: case GRAPHSTYLE_DOT: case GRAPHSTYLE_LONGDASH: dashes << Stroke << Space; pen.setDashPattern(dashes); Painter->setPen(pen); break; default: pen.setStyle(Qt::SolidLine); break; } Painter->setPen(pen); auto pp = begin(); if(!pp->isPt()) pp++; /// \todo DX DY DX_ = /*p->DX*/ + float(x0)*Scale; DY_ = /*p->DY*/ + float(y0)*Scale; while(!pp->isGraphEnd()) { if(pp->isStrokeEnd()) ++pp; // ?? QPainterPath path; if(pp->isPt()) { x1 = DX_ + pp->getScrX()*Scale; y1 = DY_ - pp->getScrY()*Scale; path.moveTo(x1,y1); ++pp; }else{ break; } while(!pp->isStrokeEnd()) { x1 = DX_ + pp->getScrX()*Scale; y1 = DY_ - pp->getScrY()*Scale; path.lineTo(x1,y1); ++pp; } Painter->drawPath(path); } }