void UBEditableGraphicsLineItem::forcePointPosition(const QPointF& pos, PointPosition pointPosition, int amplitude) { QLineF line; int angles[] = {0, 45, 90, 135, 180, 225, 270, 315}; int size = sizeof(angles) / sizeof(int); if(pointPosition == Start) { line.setP1(pos); line.setP2(path().elementAt(1)); } else { line.setP1(path().elementAt(0)); line.setP2(pos); } int angle = line.angle(); const float PI_2 = 4*atan(1.f)*2; //for each angle we compute the left and right angle //then compute the distance between both for(int i = 0; i < size; i++) { //use the modulo operator to force the angle to stay in [0, 360] int leftAmplitude = (angles[i] + amplitude) % 360; int rightAmplitude = (angles[i] - amplitude + 360) % 360; int leftDist = (leftAmplitude - angle + 360) % 360; int rightDist = (angle - rightAmplitude + 360) % 360; if(leftDist <= amplitude || rightDist <= amplitude) { if(pointPosition == End) { line.setAngle(angles[i]); } else { //compute the position of p1 by hand float angleInRadians = angles[i]*PI_2/360; qreal l = line.length(); const qreal dx = -cos(angleInRadians)*l; const qreal dy = sin(angleInRadians)*l; line.setP1(QPointF(dx + line.p2().x(), dy + line.p2().y())); } break; } } QPainterPath p; p.moveTo(line.p1()); p.lineTo(line.p2()); setPath(p); mHandles.at(0)->setPos(line.p1().x(), line.p1().y()); mHandles.at(1)->setPos(line.p2().x(), line.p2().y()); }
QList<QPointF> QLogicCircuitShapeConnector::defaultConnector() const { QList<QPointF> points; QList<QPointF> sections; QLineF line(startPos(), endPos()); QLineF lineEnd; QLineF lineStart; line = QLineF(startPos(), endPos()); lineStart.setP1(startPos()); lineEnd.setP1(endPos()); switch(orientationAtStart()){ case QDiagramToolkit::East: if (line.dx() < 20){ lineStart.setP2(startPos() + QPointF(20, 0)); lineEnd.setP2(lineEnd.p1() - QPointF(20, 0)); sections << QPointF(lineStart.p2().x(), lineStart.p1().y() + line.dy() / 2) << QPointF(lineEnd.p2().x(), lineEnd.p2().y() - line.dy() / 2); } else { lineStart.setP2(lineStart.p1() + QPointF(line.dx() / 2 , 0)); lineEnd.setP2(QPointF(lineStart.p2().x(), lineEnd.p1().y())); } break; case QDiagramToolkit::West: if (line.dx() > -20){ lineStart.setP2(startPos() - QPointF(20, 0)); lineEnd.setP2(lineEnd.p1() + QPointF(20, 0)); sections << QPointF(lineStart.p2().x(), lineStart.p1().y() + line.dy() / 2) << QPointF(lineEnd.p2().x(), lineEnd.p2().y() - line.dy() / 2); } else { lineStart.setP2(lineStart.p1() + QPointF(line.dx() / 2 , 0)); lineEnd.setP2(QPointF(lineStart.p2().x(), lineEnd.p1().y())); } break; default: break; } points.append(lineStart.p1()); points.append(lineStart.p2()); QListIterator<QPointF> it(sections); while(it.hasNext()){ points.append(it.next()); } points.append(lineEnd.p2()); points.append(lineEnd.p1()); return points; }
void PSV_ChartItem::updateCurrentMes(const QPointF &point) { QLineF vLine = m_vLineItem->line(); vLine.setP1(QPointF(point.x(),vLine.y1())); vLine.setP2(QPointF(point.x(),vLine.y2())); m_vLineItem->setLine(vLine); QLineF hLine = m_hLineItem->line(); hLine.setP1(QPointF(hLine.x1(),point.y())); hLine.setP2(QPointF(hLine.x2(),point.y())); m_hLineItem->setLine(hLine); m_currentMesItem->setHtml(getCurrentHtmMes(point.x())); m_currentMesItem->setPos(point.x(),point.y()+10); }
QLineF CurveTracker::curveLineAt( const QwtPlotCurve *curve, double x ) const { QLineF line; if ( curve->dataSize() >= 2 ) { const QRectF br = curve->boundingRect(); if ( ( br.width() > 0 ) && ( x >= br.left() ) && ( x <= br.right() ) ) { int index = qwtUpperSampleIndex<QPointF>( *curve->data(), x, compareX() ); if ( index == -1 && x == curve->sample( curve->dataSize() - 1 ).x() ) { // the last sample is excluded from qwtUpperSampleIndex index = curve->dataSize() - 1; } if ( index > 0 ) { line.setP1( curve->sample( index - 1 ) ); line.setP2( curve->sample( index ) ); } } } return line; }
void MainWindow::drawLine(double rangle, int i,int n,int x2, int y2, double length, double angle, QGraphicsScene *scene) { //base case, we recurse back out once this condition reached if (i == n) return; else{ //create new line, based on previously drawn line QLineF q2; q2.setP1(QPointF(x2,y2)); q2.setLength(length*.95); q2.setAngle(angle +rangle); scene->addLine(q2); QLineF q3; q3.setP1(QPointF(x2,y2)); q3.setLength(length*.95); q3.setAngle(angle -rangle); scene->addLine(q3); QLineF q; q.setP1(QPointF(x2,y2)); q.setLength(length*.95); q.setAngle(angle); scene->addLine(q); ui->graphicsView->setScene(scene); x2 = q.x2(); y2 = q.y2(); i = i+1; //call drawLine again, using new values drawLine(rangle, i,n,x2,y2,q.length(),q.angle(), scene); } }
void MazePainter::paint(MazeModel *pModel, QPainter &painter) { if (!pModel->hasMaze()) return; QRect rSize = painter.viewport(); int nMazeWidth = pModel->width(); int nMazeHeight = pModel->height(); float nCellSize = std::min((float)rSize.width()/nMazeWidth, (float)rSize.height()/nMazeHeight); //draw the big left and top walls of the maze QLineF wall; wall.setP1(QPointF(0, 0)); wall.setP2(QPointF(nCellSize, 0)); for (int col = 0; col < nMazeWidth; col++) { if (pModel->cellWalls(col, 0) & MazeModel::UP) painter.drawLine(wall); wall.translate(nCellSize, 0); } wall.setP1(QPointF(0, 0)); wall.setP2(QPointF(0, nCellSize)); for (int row = 0; row < nMazeHeight; row++) { if (pModel->cellWalls(0, row) & MazeModel::LEFT) painter.drawLine(wall); wall.translate(0, nCellSize); } //draw the rest of the maze's walls for (int row = 0; row < nMazeHeight; row++) { QLineF wallDown(0, (row+1)*nCellSize, nCellSize, (row+1)*nCellSize); QLineF wallRight(nCellSize, row*nCellSize, nCellSize, (row+1)*nCellSize); for (int col = 0; col < nMazeWidth; col++) { int walls = pModel->cellWalls(col, row); if (walls & MazeModel::RIGHT) painter.drawLine(wallRight); if (walls & MazeModel::DOWN) painter.drawLine(wallDown); wallDown.translate(nCellSize, 0); wallRight.translate(nCellSize, 0); } } }
/** * This method aligns both the \b "start" and \b "end" symbols to * the current angles of the \b "first" and the \b "last" line * segment respectively. */ void AssociationLine::alignSymbols() { const int sz = m_points.size(); if (sz < 2) { // cannot align if there is no line (one line = 2 points) return; } QList<QPolygonF> polygons = path().toSubpathPolygons(); if (m_startSymbol) { QPolygonF firstLine = polygons.first(); QLineF segment(firstLine.at(1), firstLine.at(0)); m_startSymbol->alignTo(segment); } if (m_endSymbol) { QPolygonF lastLine = polygons.last(); int maxIndex = lastLine.size(); QLineF segment(lastLine.at(maxIndex-2), lastLine.at(maxIndex-1)); m_endSymbol->alignTo(segment); } if (m_subsetSymbol) { QPointF p1 = path().pointAtPercent(0.4); QPointF p2 = path().pointAtPercent(0.5); QLineF segment(p1, p2); m_subsetSymbol->alignTo(segment); } if (m_collaborationLineItem) { const qreal distance = 10; const int midSegmentIndex = (sz - 1) / 2; const QPointF a = m_points.at(midSegmentIndex); const QPointF b = m_points.at(midSegmentIndex + 1); if (a == b) return; const QPointF p1 = (a + b) / 2.0; const QPointF p2 = (p1 + b) / 2.0; // Reversed line as we want normal in opposite direction. QLineF segment(p2, p1); QLineF normal = segment.normalVector().unitVector(); normal.setLength(distance); QLineF actualLine; actualLine.setP2(normal.p2()); normal.translate(p1 - p2); actualLine.setP1(normal.p2()); m_collaborationLineItem->setLine(actualLine); m_collaborationLineHead->alignTo(actualLine); } }
QLineF MouseMovementManager::newLine() { QLineF line; if (mPath.back().size() > 1) { line.setP1(mPath.back().at(mPath.back().size() - 2)); line.setP2(mPath.back().back()); } return line; }
virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event){ QGraphicsEllipseItem::mouseMoveEvent(event); if(connector_){ QLineF line; line.setP1(scenePos()); line.setP2(event->scenePos()); connector_->setLine(line); } }
void advance() { QPointF unit = (end - start)/sqrt(QPointF::dotProduct(end - start, end - start)); currentPos += 4.*unit; QLineF l = line->line(); l.setP1(currentPos + QPoint(GameScene::tile_width/2, GameScene::tile_height/2)); line->setLine(l); if ((currentPos - end).manhattanLength() < 4.) { finished = true; } }
void tst_QLine::testSet() { { QLine l; l.setP1(QPoint(1, 2)); l.setP2(QPoint(3, 4)); QCOMPARE(l.x1(), 1); QCOMPARE(l.y1(), 2); QCOMPARE(l.x2(), 3); QCOMPARE(l.y2(), 4); l.setPoints(QPoint(5, 6), QPoint(7, 8)); QCOMPARE(l.x1(), 5); QCOMPARE(l.y1(), 6); QCOMPARE(l.x2(), 7); QCOMPARE(l.y2(), 8); l.setLine(9, 10, 11, 12); QCOMPARE(l.x1(), 9); QCOMPARE(l.y1(), 10); QCOMPARE(l.x2(), 11); QCOMPARE(l.y2(), 12); } { QLineF l; l.setP1(QPointF(1, 2)); l.setP2(QPointF(3, 4)); QCOMPARE(l.x1(), 1.0); QCOMPARE(l.y1(), 2.0); QCOMPARE(l.x2(), 3.0); QCOMPARE(l.y2(), 4.0); l.setPoints(QPointF(5, 6), QPointF(7, 8)); QCOMPARE(l.x1(), 5.0); QCOMPARE(l.y1(), 6.0); QCOMPARE(l.x2(), 7.0); QCOMPARE(l.y2(), 8.0); l.setLine(9.0, 10.0, 11.0, 12.0); QCOMPARE(l.x1(), 9.0); QCOMPARE(l.y1(), 10.0); QCOMPARE(l.x2(), 11.0); QCOMPARE(l.y2(), 12.0); } }
void updatePos(){ QPointF c1 = start_->pos() + QPoint(kPeopleNodeRadius, kPeopleNodeRadius); QPointF c2 = end_->pos() + QPoint(kPeopleNodeRadius, kPeopleNodeRadius); QPointF delta = c2-c1; qreal deltaLength = QLineF(c1, c2).length(); qreal ratio = (kPeopleNodeRadius + kConnectorGap) / deltaLength; QPointF p1 = c1 + delta * ratio; QPointF p2 = c2 - delta * ratio; QLineF line; line.setP1(p1); line.setP2(p2); setLine(line); QPointF d = p1-p2; { static const qreal sinv = sin(kArrowAngle); static const qreal cosv = cos(kArrowAngle); QPointF vec; vec.setX(d.x() * cosv - d.y() * sinv); vec.setY(d.x() * sinv + d.y() * cosv); qreal ratio = qSqrt(vec.x() * vec.x() + vec.y() * vec.y())/kArrowLength; vec /= ratio; arrow[0]->setLine(QLineF(p2, p2 + vec)); vec.setX(d.x() * cosv + d.y() * sinv); vec.setY(-d.x() * sinv + d.y() * cosv); vec /= ratio; arrow[1]->setLine(QLineF(p2, p2 + vec)); } label_->setPos((c1+c2)/2); }
QPolygonF GraphicalRobotElement::calculateArrowHeadPosition (QLineF aLine) { int arrowSize = 10; QPolygonF polyF; QLineF Line; Line.setP1 (aLine.p2() ); Line.setP2 (aLine.p1() ); double angle = ::acos (Line.dx() / Line.length() ); if (Line.dy() >= 0) { angle = (Pi * 2) - angle; } QPointF arrowP1 = Line.p1() + QPointF (sin (angle + Pi / 3) * arrowSize, cos (angle + Pi / 3) * arrowSize); QPointF arrowP2 = Line.p1() + QPointF (sin (angle + Pi - Pi / 3) * arrowSize, cos (angle + Pi - Pi / 3) * arrowSize); polyF.clear(); polyF << Line.p1() << arrowP1 << arrowP2; return polyF; }
QVector<QPointF> RoundedRectItem::calculatePoints(QPointF start_pnt, double start_angle, double end_angle) { QVector<QPointF> points; QLineF lin; double inc=(start_angle > end_angle ? -10 : 10), ang=start_angle; bool end=false; while(!end) { lin.setP1(start_pnt); lin.setLength(radius); lin.setAngle(ang); points.append(lin.p2()); ang+=inc; end=((inc > 0 && ang > end_angle) || (inc < 0 && ang < end_angle)); } return(points); }
void Storage::paintEvent(QPaintEvent *anEvent) { QLabel::paintEvent(anEvent); QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing); //painter.setRenderHint(QPainter::SmoothPixmapTransform); QPen pen; if (NoTool != tool_) { pen.setWidth(5); pen.setColor(QColor(Qt::white)); pen.setStyle(Qt::DashLine); painter.setPen(pen); if (BoundingBoxTool == tool_) { /* с учётом масштаба */ QRect bbox = rect.getCoordinates(); QPoint bboxTopLeft = bbox.topLeft() * scale_; QPoint bboxBottomRight = bbox.bottomRight() * scale_; bbox.setTopLeft(bboxTopLeft); bbox.setBottomRight(bboxBottomRight); painter.drawRect(bbox); } else if (EllipseTool == tool_) { /* с учётом масштаба */ QRect elli = ell.getCoordinates().normalized(); QPoint ellTopLeft = elli.topLeft() * scale_; QPoint ellBottomRight = elli.bottomRight() * scale_; elli.setTopLeft(ellTopLeft); elli.setBottomRight(ellBottomRight); if(1 < elli.height() && 1 < elli.width() ) { painter.drawEllipse(elli); } // painter.drawRect(ell); } else if (ArrowTool == tool_) { /* с учётом масштаба */ QLineF line = arrow.getCoordinates(); QPointF p1 = line.p1() * scale_; QPointF p2 = line.p2() * scale_; line.setP1(p1); line.setP2(p2); if(1 < line.length()) { double angle = ::acos(line.dx() / line.length()); qreal Pi = atan(1)*4; if (line.dy() >= 0) angle = (Pi * 2) - angle; QPointF arrowP1 = line.p1() + QPointF(sin(angle + Pi / 3) * arrow_size_, cos(angle + Pi / 3) * arrow_size_); QPointF arrowP2 = line.p1() + QPointF(sin(angle + Pi - Pi / 3) * arrow_size_, cos(angle + Pi - Pi / 3) * arrow_size_); QPolygonF arrowTop; arrowTop.clear(); arrowTop << line.p1() << arrowP1 << arrowP2; painter.drawLine(line); painter.drawPolygon(arrowTop);///111 qDebug() << "arrowTop" << arrowTop; arrow_top_ = arrowTop; } } else if (PolygonTool == tool_) { /* с учётом масштаба */ QPoint point; QPolygon pol = poly.getCoordinates(); for (int i = 0; i < pol.size(); i++) { point.setX(pol.at(i).x()); point.setY(pol.at(i).y()); point *= scale_; pol.remove(i); pol.insert(i, point); } painter.drawPolygon(pol); } } /* рисуем фигуры */ drawBoundingBoxes(&painter, &pen); drawPolygons(&painter, &pen); drawEllipses(&painter, &pen); drawArrows(&painter, &pen); }
bool PSV_ChartItem::addCurveItem(PSV_CurveInfo &curveInfo) { if(curveInfo.m_isHidden) { return true; } setCurrentAxisType(curveInfo.m_axisType); PSV::CURVETYPE curveType = curveInfo.m_curveType; QMap<double, double> curve_data = curveInfo.m_curveDataMap; QPen pen(curveInfo.m_lineColor); pen.setWidth(curveInfo.m_lineWidth); QMapIterator<double, double> iter(curve_data); QLineF lineF; QLineF lineF_V; QLineF lineF_H; bool is_first = true; QMap<double, QGraphicsLineItem *> line_item_map; QMap<double, QGraphicsLineItem *> line_V_item_map; QMap<double, QGraphicsLineItem *> line_H_item_map; while(iter.hasNext()) { iter.next(); double x = getAxisX(iter.key());//不调整 double y = getAxisY(iter.value());//不调整 QPointF point(x,y); if(is_first) { is_first = false; if(curveType == PSV::E_CURVE_PARELLEL) { lineF_H.setP1(point); } else { lineF.setP1(point); } } else { if(curveType == PSV::E_CURVE_PARELLEL) { QGraphicsLineItem *line_item_H = new QGraphicsLineItem(this); line_item_H->setZValue(m_curveZValue); lineF_H.setP2(QPointF(x,lineF_H.p1().y())); line_item_H->setLine(lineF_H); line_item_H->setPen(pen); line_H_item_map.insert(iter.key(),line_item_H); lineF_V.setP1(QPointF(x,lineF_H.p1().y())); lineF_V.setP2(point); QGraphicsLineItem *line_item_V = new QGraphicsLineItem(this); line_item_V->setZValue(m_curveZValue); line_item_V->setLine(lineF_V); line_item_V->setPen(pen); line_V_item_map.insert(iter.key(),line_item_V); lineF_H.setP1(point); } else { QGraphicsLineItem *line_item; line_item = new QGraphicsLineItem(this); line_item->setZValue(m_curveZValue); lineF.setP2(point); line_item->setLine(lineF); line_item->setPen(pen); line_item_map.insert(iter.key(),line_item); lineF.setP1(lineF.p2()); } } } m_curveZValue++; return true; }
//----------------------------------------------------------- void OGRelacionamento::mousePressEvent(QGraphicsSceneMouseEvent *evento) { /* O relacionamento em sim não pode ser movimentado pelo usuário, porém pode ser selecionado. Mas para que isso aconteça é necessário marcar a flag QGraphicsItem::ItemIsMovable, selecionar o relacionamento e depois desmarcar a flag. */ this->setFlag(QGraphicsItem::ItemIsMovable); //Executa o mousePressEvent da classe base para selecionar o relacionamento ObjetoGrafico::mousePressEvent(evento); //Desmarca a flag QGraphicsItem::ItemIsMovable para que o relacionamento não seja movido pelo usuário this->setFlag(QGraphicsItem::ItemIsMovable, false); //Caso o relacionamento não esteja protegido if(!this->obterObjetoOrigem()->objetoProtegido()) { RelacionamentoBase *rel_base=this->obterObjetoOrigem(); //Reseta a posição dos rótulos caso o botão do meio esteja pressionado if(evento->buttons()==Qt::MidButton) { for(unsigned i=0; i < 3; i++) rel_base->definirDistanciaRotulo(i, QPointF(NAN,NAN)); this->configurarRotulos(); } //Caso o usuário esteja com o SHIFT pressionado else if(evento->modifiers()==Qt::ShiftModifier) { QLineF lin; QPointF p; QRectF ret; unsigned i, qtd; bool pnt_rem=false; vector<QPointF> pontos=rel_base->obterPontos(); if(!rel_base->autoRelacionamento()) { /* Clicando com botão esquerdo sobre um ponto na linha de um relacionamento o mesmo será removido da linha */ if(evento->buttons()==Qt::LeftButton) { emit s_relacionamentoModificado(rel_base); qtd=pontos_graf.size(); for(i=0; i < qtd; i++) { //Obtém a dimensão do ponto gráfico ret.setTopLeft(pontos_graf[i]->pos()); ret.setSize(pontos_graf[i]->boundingRect().size()); //Caso a posição do mouse esteja dentro do ponto efetua a remoção if(ret.contains(evento->pos())) { pontos.erase(pontos.begin()+i); rel_base->definirPontos(pontos); this->configurarLinha(); pnt_rem=true; break; } } /* Clicando com botão esquerdo sobre a linha de um relacionamento um novo ponto será criado na linha */ qtd=linhas.size(); for(i=0; i < qtd && !pnt_rem; i++) { /* Cria uma linha com base na posição do cursor. Esta linha será usada para calcular o ponto exato (intersecção) onde o novo ponto deve ser inserido na linha */ if(linhas[i]->line().angle()>=179 || linhas[i]->line().angle()>=359) { lin.setP1(QPointF(evento->pos().x(), evento->pos().y()-50)); lin.setP2(QPointF(evento->pos().x(), evento->pos().y()+50)); } else { lin.setP1(QPointF(evento->pos().x()-50, evento->pos().y())); lin.setP2(QPointF(evento->pos().x()+50, evento->pos().y())); } //Caso a linha criada acima intercepta uma linha do relacionamento if(linhas[i]->line().intersect(lin,&p)==QLineF::BoundedIntersection) { //Insere o ponto na linha if(i >= pontos.size()) pontos.push_back( evento->pos()); else pontos.insert(pontos.begin() + i, evento->pos()); rel_base->definirPontos(pontos); //Reconfigura a linha this->configurarLinha(); break; } } } } } /* Caso o usuário clique com o esquerdo sem nenhum modificado do teclado pressionado. Será verificado se algum objeto filho pode ser selecionado na posição do cursor */ else if(evento->button()==Qt::LeftButton) { QRectF ret; unsigned qtd, i; //Verifica se algum ponto está selecionado sob o cursor qtd=pontos_graf.size(); for(i=0; i < qtd && !objeto_sel; i++) { ret.setTopLeft(pontos_graf[i]->pos()); ret.setSize(pontos_graf[i]->boundingRect().size()); /* Caso o retangulo do objeto contenha o ponto, seleciona o mesmo */ if(ret.contains(evento->pos())) { objeto_sel=pontos_graf[i]; idx_objeto_sel=i; } } //Verifica se algum rótulo está selecionado sob o cursor for(i=0; i < 3 && !objeto_sel; i++) { if(rotulos[i]) { ret.setTopLeft(rotulos[i]->pos()); ret.setSize(rotulos[i]->boundingRect().size()); /* Caso o retangulo do objeto contenha o ponto, seleciona o mesmo */ if(ret.contains(evento->pos())) { objeto_sel=rotulos[i]; idx_objeto_sel=i; } } } } } }
void RelationshipView::mousePressEvent(QGraphicsSceneMouseEvent *event) { //Marks the flag ItemIsMovable in order to permit the relationship to be selected this->setFlag(QGraphicsItem::ItemIsMovable); BaseObjectView::mousePressEvent(event); this->setFlag(QGraphicsItem::ItemIsMovable, false); if(!this->getSourceObject()->isProtected()) { BaseRelationship *base_rel=this->getSourceObject(); //Resets the labels position when mid-button is pressed if(event->buttons()==Qt::MidButton) { for(unsigned i=0; i < 3; i++) base_rel->setLabelDistance(i, QPointF(NAN,NAN)); this->configureLabels(); } else if(event->modifiers()==Qt::ShiftModifier) { QLineF lin; QPointF p; QRectF rect; unsigned i, count; bool pnt_rem=false; vector<QPointF> pontos=base_rel->getPoints(); if(!base_rel->isSelfRelationship()) { //When the user press SHIFT and clicks on a point this is removed if(event->buttons()==Qt::LeftButton) { emit s_relationshipModified(base_rel); count=graph_points.size(); for(i=0; i < count; i++) { //Calculating the graphical point rect rect.setTopLeft(graph_points[i]->pos()); rect.setSize(graph_points[i]->boundingRect().size()); //Case the mouse pos is inside the point rect if(rect.contains(event->pos())) { pontos.erase(pontos.begin()+i); base_rel->setPoints(pontos); this->configureLine(); pnt_rem=true; break; } } //Create a point when the user press SHIFT and clicks the line count=lines.size(); for(i=0; i < count && !pnt_rem; i++) { /* Creates a auxiliary line based upon the cursor position. This line is used to calculate the exact point (intersection) where the new one must be inserted */ lin.setP1(QPointF(event->pos().x()-50, event->pos().y()-50)); lin.setP2(QPointF(event->pos().x()+50, event->pos().y()+50)); //Case the auxiliary line intercepts one relationship line if(lines[i]->line().intersect(lin,&p)==QLineF::BoundedIntersection) { //Inserts the point to the line if(i >= pontos.size()) pontos.push_back( event->pos()); else pontos.insert(pontos.begin() + i, event->pos()); base_rel->setPoints(pontos); this->configureLine(); break; } } } } } //Clicking only with the left button, checks if some child object can be selected else if(event->button()==Qt::LeftButton) { QRectF rect; unsigned count, i; //Checks if there is some point selected count=graph_points.size(); for(i=0; i < count && !sel_object; i++) { rect.setTopLeft(graph_points[i]->pos()); rect.setSize(graph_points[i]->boundingRect().size()); if(rect.contains(event->pos())) { sel_object=graph_points[i]; sel_object_idx=i; } } //Checks if there is some label selected for(i=0; i < 3 && !sel_object; i++) { if(labels[i]) { rect.setTopLeft(labels[i]->pos()); rect.setSize(labels[i]->boundingRect().size()); if(rect.contains(event->pos())) { sel_object=labels[i]; sel_object_idx=i; } } } } } }
QPalette CMYKChoose::sliderPix(int farbe) { RGBColor rgb; CMYKColor cmyk; QImage image0 = QImage(255, 10, QImage::Format_ARGB32); QPainter p; p.begin(&image0); p.setPen(Qt::NoPen); int r, g, b, c, m, y, k; QColor tmp; for (int x = 0; x < 255; x += 5) { if (Farbe.getColorModel() == colorModelCMYK) { ScColorEngine::getCMYKValues(Farbe, m_doc, cmyk); cmyk.getValues(c, m, y, k); if (dynamic) { switch (farbe) { case 180: tmp = ScColorEngine::getDisplayColorGC(ScColor(x, m, y, k), m_doc); break; case 300: tmp = ScColorEngine::getDisplayColorGC(ScColor(c, x, y, k), m_doc); break; case 60: tmp = ScColorEngine::getDisplayColorGC(ScColor(c, m, x, k), m_doc); break; } p.setBrush(tmp); } else { switch (farbe) { case 180: tmp = ScColorEngine::getDisplayColorGC(ScColor(x, 0, 0, 0), m_doc); break; case 300: tmp = ScColorEngine::getDisplayColorGC(ScColor(0, x, 0, 0), m_doc); break; case 60: tmp = ScColorEngine::getDisplayColorGC(ScColor(0, 0, x, 0), m_doc); break; } p.setBrush(tmp); } } else if (Farbe.getColorModel() == colorModelRGB) { ScColorEngine::getRGBValues(Farbe, m_doc, rgb); rgb.getValues(r, g, b); if (dynamic) { switch (farbe) { case 0: tmp = ScColorEngine::getDisplayColorGC(ScColor(x, g, b), m_doc); break; case 120: tmp = ScColorEngine::getDisplayColorGC(ScColor(r, x, b), m_doc); break; case 240: tmp = ScColorEngine::getDisplayColorGC(ScColor(r, g, x), m_doc); break; } p.setBrush(tmp); } else { switch (farbe) { case 0: tmp = ScColorEngine::getDisplayColorGC(ScColor(x, 0, 0), m_doc); break; case 120: tmp = ScColorEngine::getDisplayColorGC(ScColor(0, x, 0), m_doc); break; case 240: tmp = ScColorEngine::getDisplayColorGC(ScColor(0, 0, x), m_doc); break; } p.setBrush(tmp); } } else if (Farbe.getColorModel() == colorModelLab) { double L, a, b; double val = static_cast<double>(x) / 255.0; Farbe.getLab(&L, &a, &b); if (isHLC) { QLineF lin; lin.setP1(QPointF(0.0, 0.0)); lin.setP2(QPointF(a, b)); double H = lin.angle(); double C = lin.length(); double tmpA, tmpB; if (dynamic) { switch (farbe) { case 0: lin = QLineF::fromPolar(C, -360 * val); tmpA = lin.p2().x(); tmpB = lin.p2().y(); tmp = ScColorEngine::getDisplayColorGC(ScColor(L, tmpA, tmpB), m_doc); break; case 120: tmp = ScColorEngine::getDisplayColorGC(ScColor(100 * val, a, b), m_doc); break; case 240: lin = QLineF::fromPolar(128 * val, H); tmpA = lin.p2().x(); tmpB = lin.p2().y(); tmp = ScColorEngine::getDisplayColorGC(ScColor(L, tmpA, tmpB), m_doc); break; } p.setBrush(tmp); } else { switch (farbe) { case 0: lin = QLineF::fromPolar(128, -360 * val); tmpA = lin.p2().x(); tmpB = lin.p2().y(); tmp = ScColorEngine::getDisplayColorGC(ScColor(100.0, tmpA, tmpB), m_doc); break; case 120: tmp = ScColorEngine::getDisplayColorGC(ScColor(100 * val, 0.0, 0.0), m_doc); break; case 240: lin = QLineF::fromPolar(128 * val, 0); tmpA = lin.p2().x(); tmpB = lin.p2().y(); tmp = ScColorEngine::getDisplayColorGC(ScColor(100.0, tmpA, tmpB), m_doc); break; } p.setBrush(tmp); } } else { if (dynamic) { switch (farbe) { case 0: tmp = ScColorEngine::getDisplayColorGC(ScColor(100 * val, a, b), m_doc); break; case 120: tmp = ScColorEngine::getDisplayColorGC(ScColor(L, 256 * val - 128.0, b), m_doc); break; case 240: tmp = ScColorEngine::getDisplayColorGC(ScColor(L, a, 256 * val - 128.0), m_doc); break; } p.setBrush(tmp); } else { switch (farbe) { case 0: tmp = ScColorEngine::getDisplayColorGC(ScColor(100 * val, 0.0, 0.0), m_doc); break; case 120: tmp = ScColorEngine::getDisplayColorGC(ScColor(100.0, 256 * val - 128.0, 0.0), m_doc); break; case 240: tmp = ScColorEngine::getDisplayColorGC(ScColor(100.0, 0.0, 256 * val - 128.0), m_doc); break; } } p.setBrush(tmp); } } p.drawRect(x, 0, 5, 10); } p.end(); QPalette pal; pal.setBrush(QPalette::Window, QBrush(image0)); return pal; }
void CMYKChoose::setValues() { CyanSp->blockSignals(true); CyanSL->blockSignals(true); MagentaSp->blockSignals(true); MagentaSL->blockSignals(true); YellowSp->blockSignals(true); YellowSL->blockSignals(true); BlackSp->blockSignals(true); BlackSL->blockSignals(true); if (Farbe.getColorModel() == colorModelCMYK) { CMYKColor cmyk; int cc, cm, cy, ck; ScColorEngine::getCMYKValues(Farbe, m_doc, cmyk); cmyk.getValues(cc, cm, cy, ck); CyanSp->setValue(cc / 2.55); CyanSL->setValue(qRound(cc / 2.55) * 1000.0); MagentaSp->setValue(cm / 2.55); MagentaSL->setValue(qRound(cm / 2.55) * 1000.0); YellowSp->setValue(cy / 2.55); YellowSL->setValue(qRound(cy / 2.55) * 1000.0); BlackSp->setValue(ck / 2.55); BlackSL->setValue(qRound(ck / 2.55) * 1000.0); if (dynamic) { CyanSL->setPalette(sliderPix(180)); MagentaSL->setPalette(sliderPix(300)); YellowSL->setPalette(sliderPix(60)); BlackSL->setPalette(sliderBlack()); } } else if (Farbe.getColorModel() == colorModelRGB) { RGBColor rgb; int r, g, b; ScColorEngine::getRGBValues(Farbe, m_doc, rgb); rgb.getValues(r, g, b); CyanSp->setValue(static_cast<double>(r)); CyanSL->setValue(r * 1000.0); MagentaSp->setValue(static_cast<double>(g)); MagentaSL->setValue(g * 1000.0); YellowSp->setValue(static_cast<double>(b)); YellowSL->setValue(b * 1000.0); int h, s, v; ScColorEngine::getRGBColor(Farbe, m_doc).getHsv(&h, &s, &v); BlackComp = 255 - v; if (dynamic) { CyanSL->setPalette(sliderPix(0)); MagentaSL->setPalette(sliderPix(120)); YellowSL->setPalette(sliderPix(240)); } } else if (Farbe.getColorModel() == colorModelLab) { double L, a, b; Farbe.getLab(&L, &a, &b); if (isHLC) { MagentaSp->setValue(L); MagentaSL->setValue(L * 1000.0); QLineF lin; lin.setP1(QPointF(0.0, 0.0)); lin.setP2(QPointF(a, b)); CyanSp->setValue(360 - lin.angle()); CyanSL->setValue(360 - lin.angle() * 1000.0); YellowSp->setValue(lin.length()); YellowSL->setValue(lin.length() * 1000.0); } else { CyanSp->setValue(L); CyanSL->setValue(L * 1000.0); MagentaSp->setValue(a); MagentaSL->setValue(a * 1000.0); YellowSp->setValue(b); YellowSL->setValue(b * 1000.0); } if (dynamic) { CyanSL->setPalette(sliderPix(0)); MagentaSL->setPalette(sliderPix(120)); YellowSL->setPalette(sliderPix(240)); } } CyanSp->blockSignals(false); CyanSL->blockSignals(false); MagentaSp->blockSignals(false); MagentaSL->blockSignals(false); YellowSp->blockSignals(false); YellowSL->blockSignals(false); BlackSp->blockSignals(false); BlackSL->blockSignals(false); }
void Arrow::readGraphicAttributes(const QXmlStreamAttributes &attributes) { // Check for legacy arrow type auto legacyArrowType = attributes.value("type").toString(); // if not legacy type, read arrow tip type and return if ("ReactionArrow" != legacyArrowType // TODO make these names constants (see MolScene::produceChild()) && "MechanismArrow" != legacyArrowType) { d->arrowType = (ArrowType) (attributes.value("arrowType").toString().toInt()) ; d->spline = ! (attributes.value("splineDisabled").toString().toInt()); return; } // Code for legacy version if ("ReactionArrow" == legacyArrowType) { enum LegacyReactionArrowType { SingleArrow = 0, DoubleArrow, Equilibrium, EqRightShifted, EqLeftShifted }; // Arrow tip auto legacyReactionArrowType = (LegacyReactionArrowType) (attributes.value("arrowType").toString().toInt()); switch(legacyReactionArrowType) { case SingleArrow: setArrowType(UpperBackward | LowerBackward); break; case DoubleArrow: setArrowType(LowerForward | UpperForward | LowerBackward | UpperBackward); break; case Equilibrium: case EqRightShifted: case EqLeftShifted: setArrowType(UpperBackward); break; default: setArrowType(NoArrow); } // Coordinates QPointF origin(attributes.value("posx").toString().toDouble(), attributes.value("posy").toString().toDouble()); QLineF arrowLine(origin, origin + QPointF(attributes.value("endx").toString().toDouble(), attributes.value("endy").toString().toDouble())); setCoordinates(QPolygonF() << arrowLine.p1() << arrowLine.p2()); if (!scene()) return; // Fix equilibrium arrows: if (Equilibrium == legacyReactionArrowType || EqLeftShifted == legacyReactionArrowType || EqRightShifted == legacyReactionArrowType) { // shift both arrows in equilibrium QLineF normalVector = arrowLine.normalVector().unitVector(); QLineF unitVector = arrowLine.unitVector(); QPointF normalTranslation = 2*(normalVector.p2() - normalVector.p1()); QPointF unitTranslation = 15*(unitVector.p2() - unitVector.p1()); QLineF reverseArrowLine = arrowLine; arrowLine.translate(normalTranslation); reverseArrowLine.translate(-normalTranslation); if (EqRightShifted == legacyReactionArrowType) { reverseArrowLine.setP1(reverseArrowLine.p1() + unitTranslation); reverseArrowLine.setP2(reverseArrowLine.p2() - unitTranslation); } if (EqLeftShifted == legacyReactionArrowType) { arrowLine.setP1(arrowLine.p1() + unitTranslation); arrowLine.setP2(arrowLine.p2() - unitTranslation); } auto reverseArrow = new Arrow; reverseArrow->setParentItem(parentItem()); scene()->addItem(reverseArrow); reverseArrow->setCoordinates(QPolygonF() << reverseArrowLine.p1() << reverseArrowLine.p2()); reverseArrow->setArrowType(LowerForward); setCoordinates(QPolygonF() << arrowLine.p1() << arrowLine.p2()); } } if ("MechanismArrow" == legacyArrowType) { enum LegacyMechanismArrowType { SingleArrowRight = 0, SingleArrowLeft, DoubleMechanismArrow, SingleHookRight, SingleHookLeft, DoubleHook }; // Arrow tip auto legacyMechanismArrowType = (LegacyMechanismArrowType) (attributes.value("arrowType").toString().toInt()); switch(legacyMechanismArrowType) { case SingleArrowRight: setArrowType(UpperBackward | LowerBackward); break; case SingleArrowLeft: setArrowType(UpperForward | LowerForward); break; case DoubleMechanismArrow: setArrowType(LowerForward | UpperForward | LowerBackward | UpperBackward); break; case SingleHookRight: setArrowType(UpperBackward); break; case SingleHookLeft: setArrowType(UpperForward); break; case DoubleHook: setArrowType(UpperForward | UpperBackward); break; default: setArrowType(NoArrow); } // Setting coordinates QPolygonF points; for (int i = 0 ; i < 4 ; ++i) points << QPointF(attributes.value("p" + QString::number(i+1) + "x").toString().toDouble(), attributes.value("p" + QString::number(i+1) + "y").toString().toDouble()); points.translate(attributes.value("posx").toString().toDouble(), attributes.value("posy").toString().toDouble()); setCoordinates(points); } }
void EdgeItem::paint( QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { if ( option->levelOfDetail < 0.1) return; /** Do not draw edges when adjacent nodes intersect */ QPolygonF pred_rect = mapFromItem( pred()->item(), pred()->item()->boundingRect()); QPolygonF succ_rect = mapFromItem( succ()->item(), succ()->item()->boundingRect()); if ( !succ_rect.intersected( pred_rect).isEmpty()) return; static const qreal spline_detail_level = 0.4; static const qreal draw_arrow_detail_level = 0.3; QPointF curr_point; QLineF line = QLineF(); curr_point = srcP; QPointF nextToDst = srcP; qreal opacity = min<qreal>( edge()->pred()->item()->opacityLevel(), edge()->succ()->item()->opacityLevel()); line.setP1( nextToDst); line.setP2( dstP); QPainterPath path( srcP); QPainterPathStroker stroker; stroker.setWidth( 0); if ( edge()->isSelf()) { path = selfEdgePath(); } else if ( option->levelOfDetail >= spline_detail_level) { path.cubicTo( cp1, cp2, dstP); } //path = stroker.createStroke(path); if ( nextToDst == dstP) return; //Set opacity if ( edge()->graph()->view()->isContext()) painter->setOpacity( opacity); QPen pen( option->palette.foreground().color(), 1, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin); if ( isNotNullP( edge()->style())) { pen = edge()->style()->pen(); } // Draw the line itself if ( option->levelOfDetail >= spline_detail_level) { if ( option->state & QStyle::State_Selected) { pen.setWidthF( pen.widthF() + 1); } } else { pen = QPen( pen.color(),1); } painter->setPen( pen); //Draw edge if ( edge()->isSelf() || option->levelOfDetail >= spline_detail_level) { painter->drawPath( path); } else { painter->drawLine( line); } // Draw the arrows if there's enough room and level of detail is appropriate if ( option->levelOfDetail >= draw_arrow_detail_level) { double angle = ::acos(line.dx() / line.length()); if ( line.dy() >= 0) angle = TwoPi - angle; QPointF destArrowP1; QPointF destArrowP2; /* NOTE: Qt::black can be replaced by option->palette.foreground().color() */ if ( isNotNullP( edge()->style())) { painter->setBrush( edge()->style()->pen().color()); } else { painter->setBrush(option->palette.foreground().color()); } if ( edge()->isSelf()) { angle = -2* Pi/3; } destArrowP1 = dstP + QPointF( sin(angle - Pi / 3) * arrowSize, cos(angle - Pi / 3) * arrowSize); destArrowP2 = dstP + QPointF( sin(angle - Pi + Pi / 3) * arrowSize, cos(angle - Pi + Pi / 3) * arrowSize); pen.setStyle( Qt::SolidLine); painter->setPen( pen); if ( succ()->isSimple()) { QPainterPath arrow_path; arrow_path.addPolygon( QPolygonF() << dstP << destArrowP1 << destArrowP2 << dstP); //path = path.united( arrow_path); painter->drawPolygon(QPolygonF() << dstP << destArrowP1 << destArrowP2); } } painter->setOpacity( 1); #ifdef SHOW_CONTROL_POINTS /** For illustrative purposes */ painter->setPen(QPen(Qt::gray, 1, Qt::DashLine, Qt::RoundCap, Qt::RoundJoin)); if ( !edge()->isSelf()) { painter->drawLine( srcP, dstP); painter->drawLine( srcP, cp1); painter->drawLine( cp2, dstP); } painter->setPen(QPen(Qt::red, 2, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin)); painter->drawPoint( srcP); painter->setPen(QPen(Qt::blue, 2, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin)); painter->drawPoint( dstP); painter->setPen(QPen(Qt::green, 2, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin)); painter->drawPoint( cp1); #endif }
QLineF Branch::moveBranchToEdgeOfRect(QPointF currPoint, QLineF newBranch, float posOnParent) { QLineF tempLine = QLineF(branchLine.p1(), lv.getMaxPoint()); tempLine.setLength(tempLine.length() * posOnParent); currPoint = tempLine.p2(); QPointF differenceVec = newBranch.p1() - currPoint; newBranch.setP1(currPoint); newBranch.setP2(newBranch.p2() - differenceVec); QLineF tempNewBranch = newBranch; tempNewBranch.setLength(1000); QLineF sideLine1 = QLineF(maxRect[0], maxRect[3]); QLineF sideLine1Temp = sideLine1; sideLine1Temp.setLength(1000); sideLine1Temp = QLineF(sideLine1Temp.p2(), sideLine1Temp.p1()); sideLine1Temp.setLength(1000); QLineF sideLine2 = QLineF(maxRect[1], maxRect[2]); QLineF topLine = QLineF(maxRect[2], maxRect[3]); QLineF finalLine; if (posOnParent < 0.95) { bool isSide1 = doLineSegmentsIntersect(sideLine1Temp, tempNewBranch); // find relative position of point on branchLine //float fullDistance = findDistance(branchLine.p1(), branchLine.p2()); //float segDistance = findDistance(branchLine.p1(), currPoint); //float posOnParent = segDistance / fullDistance; // transpose to relative position on intersected rectangle line float outerRectLength; if (isSide1) outerRectLength = sideLine1.length(); else outerRectLength = sideLine2.length(); outerRectLength *= posOnParent; QPointF newStartPos; if (isSide1) { sideLine1.setLength(outerRectLength); newStartPos = sideLine1.p2(); } else { sideLine2.setLength(outerRectLength); newStartPos = sideLine2.p2(); } // find vector from point to newPoint QPointF changeVector = currPoint - newStartPos; // create newLine which moves newBranch by newPointVector finalLine.setP1(newStartPos); finalLine.setP2(newBranch.p2() - changeVector); } else { QPointF midPoint; midPoint.setX((topLine.p1().x() + topLine.p2().x())/2); midPoint.setY((topLine.p1().y() + topLine.p2().y())/2); QPointF diffVec = currPoint - midPoint; finalLine.setP1(midPoint); finalLine.setP2(newBranch.p2() - diffVec); } return finalLine; }
void tst_QLine::testIntersection_data() { QTest::addColumn<double>("xa1"); QTest::addColumn<double>("ya1"); QTest::addColumn<double>("xa2"); QTest::addColumn<double>("ya2"); QTest::addColumn<double>("xb1"); QTest::addColumn<double>("yb1"); QTest::addColumn<double>("xb2"); QTest::addColumn<double>("yb2"); QTest::addColumn<int>("type"); QTest::addColumn<double>("ix"); QTest::addColumn<double>("iy"); QTest::newRow("parallel") << 1.0 << 1.0 << 3.0 << 4.0 << 5.0 << 6.0 << 7.0 << 9.0 << int(QLineF::NoIntersection) << 0.0 << 0.0; QTest::newRow("unbounded") << 1.0 << 1.0 << 5.0 << 5.0 << 0.0 << 4.0 << 3.0 << 4.0 << int(QLineF::UnboundedIntersection) << 4.0 << 4.0; QTest::newRow("bounded") << 1.0 << 1.0 << 5.0 << 5.0 << 0.0 << 4.0 << 5.0 << 4.0 << int(QLineF::BoundedIntersection) << 4.0 << 4.0; QTest::newRow("almost vertical") << 0.0 << 10.0 << 20.0000000000001 << 10.0 << 10.0 << 0.0 << 10.0 << 20.0 << int(QLineF::BoundedIntersection) << 10.0 << 10.0; QTest::newRow("almost horizontal") << 0.0 << 10.0 << 20.0 << 10.0 << 10.0000000000001 << 0.0 << 10.0 << 20.0 << int(QLineF::BoundedIntersection) << 10.0 << 10.0; QTest::newRow("long vertical") << 100.1599256468623 << 100.7861905065196 << 100.1599256468604 << -9999.78619050651 << 10.0 << 50.0 << 190.0 << 50.0 << int(QLineF::BoundedIntersection) << 100.1599256468622 << 50.0; QLineF baseA(0, -50, 0, 50); QLineF baseB(-50, 0, 50, 0); for (int i = 0; i < 1000; ++i) { QLineF a = QLineF::fromPolar(50, i); a.setP1(-a.p2()); QLineF b = QLineF::fromPolar(50, i * 0.997 + 90); b.setP1(-b.p2()); // make the qFuzzyCompare be a bit more lenient a = a.translated(1, 1); b = b.translated(1, 1); QTest::newRow(("rotation-" + QByteArray::number(i)).constData()) << (double)a.x1() << (double)a.y1() << (double)a.x2() << (double)a.y2() << (double)b.x1() << (double)b.y1() << (double)b.x2() << (double)b.y2() << int(QLineF::BoundedIntersection) << 1.0 << 1.0; } }