Example #1
0
Dubins::Dubins(const QVector2D &posA,
               qreal angleA,
               const QVector2D &posB,
               qreal angleB,
               qreal minTurnRadius) :
    _posA(posA.toPointF()),
    _angleA(angleA),
    _posB(posB.toPointF()),
    _angleB(angleB),
    _minTurnRadius(minTurnRadius),
    _isValid(false)
{
    _solvePath();
}
Example #2
0
float SCgBus::dotPos(const QPointF &point) const
{
    // get sector with minimal distance to point
    // and calculates relative dot position on it

    qreal minDist = -1.f;
    qreal result = 0.f;
    QPointF np = mapFromScene(point);

    for (int i = 1; i < mPoints.size(); i++)
    {
        QPointF p1 = mPoints[i - 1];
        QPointF p2 = mPoints[i];

        QVector2D v(p2 - p1);
        QVector2D vp(np - p1);

        QVector2D vn = v.normalized();
        //vp.normalize();

        // calculate point on line
        QVector2D p = QVector2D(p1) + vn * QVector2D::dotProduct(vn, vp);
        if(v.length() == 0)
            return result;
        qreal dotPos = QVector2D(p.toPointF() - p1).length() / v.length();

        if (dotPos < 0.f || dotPos > 1.f)
            continue;

        // we doesn't need to get real length, because we need minimum
        // so we get squared length to make that procedure faster
        qreal d = QVector2D(np - p.toPointF()).lengthSquared();

        // compare with minimum distance
        if (minDist < 0.f || minDist > d)
        {
            minDist = d;
            result = (i - 1) + dotPos;
        }
    }

    return result;
}
Example #3
0
    void NeuroLinkItem::adjustLinks()
    {
        QVector2D front(_line.p2());
        QVector2D back(_line.p1());
        QVector2D center = front + (c2 - front) * 0.33 + (back - front) * 0.1;

        foreach (NeuroItem *ni, _incoming)
        {
            MixinArrow *link = dynamic_cast<MixinArrow *>(ni);
            if (link)
                link->setLine(link->line().p1(), mapToScene(center.toPointF()));
        }
Example #4
0
void Car::advance(int phase)
{
    if( phase == 0 ) {
        return;
    }
    if( ! scene()->cellBlocked(this) ) {
        QRectF carRect = boundingRect();
        QVector2D v = QVector2D(targetPoint - startPoint) / 100.0 * progress;

        carRect.moveCenter( v.toPointF() + startPoint );        
        setPos(carRect.topLeft());

        progress += progressDelta;

        if( progress >= 100 ) {
            _direction = targetDirection;
            setCell( targetCellRow, targetCellCol );
            progress %= 100;
        }

        update();
    }
}
Example #5
0
QLineF Geometry::veryLongLine(QPointF const &pointOnLine, QVector2D const &directionVector)
{
	qreal const halfLength = 10000;
	return QLineF(pointOnLine + halfLength * directionVector.toPointF()
			, pointOnLine - halfLength * directionVector.toPointF());
}
/* draw an angle from the current point to b and then to c,
 * with a rounded corner of the given radius.
 */
void
KeyboardLayoutWidget::roundedCorner (QPainterPath& path,
        QPointF b, QPointF c, double radius)
{
    /* we may have 5 point here
     * a is the current point
     * c is the end point
     * and b is the corner
     * we will have a rounded corner with radious (maybe adjust by a,b,c position)
     *
     * a1 is on a-b, and c1 is on b-c
     */

    QPointF a = path.currentPosition();

    //qDebug() << "current" << a << b << c;

    /* make sure radius is not too large */
    double dist1 = distance (a, b);
    double dist2 = distance (b, c);

    //qDebug() << "dist" << dist1 << dist2 << radius;

    radius = qMin (radius, qMin (dist1, dist2));

    QPointF ba = a - b;
    QPointF bc = c - b;
    QVector2D na(ba);
    QVector2D nc(bc);
    na.normalize();
    nc.normalize();

    qreal cosine = QVector2D::dotProduct(na, nc);
    qreal halfcosine = qSqrt((1 + cosine) / 2);
    qreal halfsine = qSqrt( 1- halfcosine * halfcosine);
    qreal halftan = halfsine / halfcosine;
    QPointF a1 = b + na.toPointF() * (radius / halftan);
    QPointF c1 = b + nc.toPointF() * (radius / halftan);

    QVector2D n = na + nc;
    n.normalize();
    QPointF ctr = b + n.toPointF() * radius / halfsine;
    QRectF arcRect(ctr.x() - radius, ctr.y() - radius, 2 * radius, 2 * radius);

    qreal phiA, phiC;
    //qDebug() << c1 << ctr << a1;
    QVector2D ctra = QVector2D(a1 - ctr);
    QVector2D ctrc = QVector2D(c1 - ctr);
    ctra.normalize();
    ctrc.normalize();
    phiA = angle(ctra);
    phiC = angle(ctrc);

    qreal delta = phiC - phiA;
    while (delta > 0)
        delta -= 360;

    while (delta < -360)
        delta += 360;

    if (delta <- 180)
        delta += 360;

    //qDebug() << arcRect << ctra << ctrc << ctr << "degree" << phiA << phiC;

    path.lineTo(a1);
    path.arcTo(arcRect, phiA, delta);
    path.lineTo(c1);
    path.lineTo(c);
}
Example #7
0
/*! \internal
  
  Draws the line ending with the specified \a painter at the position \a pos. The direction of the
  line ending is controlled with \a dir.
*/
void QCPLineEnding::draw(QCPPainter *painter, const QVector2D &pos, const QVector2D &dir) const
{
  if (mStyle == esNone)
    return;
  
  QVector2D lengthVec(dir.normalized());
  if (lengthVec.isNull())
    lengthVec = QVector2D(1, 0);
  QVector2D widthVec(-lengthVec.y(), lengthVec.x());
  lengthVec *= (float)(mLength*(mInverted ? -1 : 1));
  widthVec *= (float)(mWidth*0.5*(mInverted ? -1 : 1));
  
  QPen penBackup = painter->pen();
  QBrush brushBackup = painter->brush();
  QPen miterPen = penBackup;
  miterPen.setJoinStyle(Qt::MiterJoin); // to make arrow heads spikey
  QBrush brush(painter->pen().color(), Qt::SolidPattern);
  switch (mStyle)
  {
    case esNone: break;
    case esFlatArrow:
    {
      QPointF points[3] = {pos.toPointF(),
                           (pos-lengthVec+widthVec).toPointF(),
                           (pos-lengthVec-widthVec).toPointF()
                          };
      painter->setPen(miterPen);
      painter->setBrush(brush);
      painter->drawConvexPolygon(points, 3);
      painter->setBrush(brushBackup);
      painter->setPen(penBackup);
      break;
    }
    case esSpikeArrow:
    {
      QPointF points[4] = {pos.toPointF(),
                           (pos-lengthVec+widthVec).toPointF(),
                           (pos-lengthVec*0.8f).toPointF(),
                           (pos-lengthVec-widthVec).toPointF()
                          };
      painter->setPen(miterPen);
      painter->setBrush(brush);
      painter->drawConvexPolygon(points, 4);
      painter->setBrush(brushBackup);
      painter->setPen(penBackup);
      break;
    }
    case esLineArrow:
    {
      QPointF points[3] = {(pos-lengthVec+widthVec).toPointF(),
                           pos.toPointF(),
                           (pos-lengthVec-widthVec).toPointF()
                          };
      painter->setPen(miterPen);
      painter->drawPolyline(points, 3);
      painter->setPen(penBackup);
      break;
    }
    case esDisc:
    {
      painter->setBrush(brush);
      painter->drawEllipse(pos.toPointF(),  mWidth*0.5, mWidth*0.5);
      painter->setBrush(brushBackup);
      break;
    }
    case esSquare:
    {
      QVector2D widthVecPerp(-widthVec.y(), widthVec.x());
      QPointF points[4] = {(pos-widthVecPerp+widthVec).toPointF(),
                           (pos-widthVecPerp-widthVec).toPointF(),
                           (pos+widthVecPerp-widthVec).toPointF(),
                           (pos+widthVecPerp+widthVec).toPointF()
                          };
      painter->setPen(miterPen);
      painter->setBrush(brush);
      painter->drawConvexPolygon(points, 4);
      painter->setBrush(brushBackup);
      painter->setPen(penBackup);
      break;
    }
    case esDiamond:
    {
      QVector2D widthVecPerp(-widthVec.y(), widthVec.x());
      QPointF points[4] = {(pos-widthVecPerp).toPointF(),
                           (pos-widthVec).toPointF(),
                           (pos+widthVecPerp).toPointF(),
                           (pos+widthVec).toPointF()
                          };
      painter->setPen(miterPen);
      painter->setBrush(brush);
      painter->drawConvexPolygon(points, 4);
      painter->setBrush(brushBackup);
      painter->setPen(penBackup);
      break;
    }
    case esBar:
    {
      painter->drawLine((pos+widthVec).toPointF(), (pos-widthVec).toPointF());
      break;
    }
    case esHalfBar:
    {
      painter->drawLine((pos+widthVec).toPointF(), pos.toPointF());
      break;
    }
    case esSkewedBar:
    {
      if (qFuzzyIsNull(painter->pen().widthF()) && !painter->modes().testFlag(QCPPainter::pmNonCosmetic))
      {
        // if drawing with cosmetic pen (perfectly thin stroke, happens only in vector exports), draw bar exactly on tip of line
        painter->drawLine((pos+widthVec+lengthVec*0.2f*(mInverted?-1:1)).toPointF(),
                          (pos-widthVec-lengthVec*0.2f*(mInverted?-1:1)).toPointF());
      } else
      {
        // if drawing with thick (non-cosmetic) pen, shift bar a little in line direction to prevent line from sticking through bar slightly
        painter->drawLine((pos+widthVec+lengthVec*0.2f*(mInverted?-1:1)+dir.normalized()*qMax(1.0f, (float)painter->pen().widthF())*0.5f).toPointF(),
                          (pos-widthVec-lengthVec*0.2f*(mInverted?-1:1)+dir.normalized()*qMax(1.0f, (float)painter->pen().widthF())*0.5f).toPointF());
      }
      break;
    }
  }
}