QPolygonF
PageLayout::rightPageOutline() const
{
	if (m_uncutOutline.size() < 4) {
		return QPolygonF();
	}

	switch (m_type) {
		case SINGLE_PAGE_UNCUT:
		case SINGLE_PAGE_CUT:
			return QPolygonF();
		case TWO_PAGES:
			break;
	}

	QLineF const line1(m_uncutOutline[1], m_uncutOutline[2]);
	QLineF line2(extendToCover(m_cutter1, m_uncutOutline));
	ensureSameDirection(line1, line2);
	QLineF const reverse_line1(line1.p2(), line1.p1());
	QLineF const reverse_line2(line2.p2(), line2.p1());
	
	QPolygonF poly;
	poly << line1.p1();
	maybeAddIntersectionPoint(poly, line1.normalVector(), line2.normalVector());
	poly << line2.p1() << line2.p2();
	maybeAddIntersectionPoint(poly, reverse_line1.normalVector(), reverse_line2.normalVector());
	poly << line1.p2();

	return PolygonUtils::round(m_uncutOutline).intersected(PolygonUtils::round(poly));
}
/**
	@param point Un point donne
	@param line Un segment de droite donnee
	@param intersection si ce pointeur est different de 0, le QPointF ainsi
	designe contiendra les coordonnees du projete orthogonal, meme si celui-ci
	n'appartient pas au segment de droite
	@return true si le projete orthogonal du point sur la droite appartient au
	segment de droite.
*/
bool QET::orthogonalProjection(const QPointF &point, const QLineF &line, QPointF *intersection) {
	// recupere le vecteur normal de `line'
	QLineF line_normal_vector(line.normalVector());
	QPointF normal_vector(line_normal_vector.dx(), line_normal_vector.dy());
	
	// cree une droite perpendiculaire a `line' passant par `point'
	QLineF perpendicular_line(point, point + normal_vector);
	
	// determine le point d'intersection des deux droites = le projete orthogonal
	QPointF intersection_point;
	QLineF::IntersectType it = line.intersect(perpendicular_line, &intersection_point);
	
	// ne devrait pas arriver (mais bon...)
	if (it == QLineF::NoIntersection) return(false);
	
	// fournit le point d'intersection a l'appelant si necessaire
	if (intersection) {
		*intersection = intersection_point;
	}
	
	// determine si le point d'intersection appartient au segment de droite
	if (QET::lineContainsPoint(line, intersection_point)) {
		return(true);
	}
	return(false);
}
QPainterPath CopyFilterGUIConnectionItem::shape() const
{
	QLineF l = line();

	QPainterPath path;
	path.setFillRule(Qt::WindingFill);
	double length = line().length();
	if (length > 0)
	{
		double offset = min(length, maxArrowSize);
		QLineF unit = l.unitVector();
		QLineF normal = l.normalVector().unitVector();
		QPointF v(unit.dx(), unit.dy());
		QPointF n(normal.dx(), normal.dy());
		QPointF p2 = l.p2();

		QPointF p3 = p2 - v * offset + 0.5 * n * offset;
		QPointF p4 = p2 - v * offset - 0.5 * n * offset;
		QPolygonF polygon;
		polygon.append(p4);
		polygon.append(p3);
		polygon.append(p2);
		path.addPolygon(polygon);

		QPolygonF polygon2;
		QPointF p1 = l.p1();
		polygon2.append(p2 + 3 * n);
		polygon2.append(p2 - 2 * n);
		polygon2.append(p1 - 2 * n);
		polygon2.append(p1 + 3 * n);
		path.addPolygon(polygon2);

		if (factor != 1.0 || isDecibel)
		{
			QFont font;
			font.setPixelSize(10);
			QPointF center = (l.p1() + l.p2()) / 2;
			QString text = QString("%1").arg(factor);
			if (isDecibel)
				text += " dB";

			QFontMetrics fontMetrics(font);
			QSizeF size = fontMetrics.size(0, text);
			size += QSizeF(2, 0);
			QRectF rect;
			rect.setSize(size);
			rect.moveCenter(center);
			path.addRoundedRect(rect.adjusted(-0.5, 0.5, 0.5, 0.5), 3, 3);
		}
	}

	return path;
}
Beispiel #4
0
QPolygonF QGVEdge::toBox(const QLineF &line) const
{
    QLineF n = line.normalVector();
    QPointF o(n.dx() * 0.5, n.dy() * 0.5);

    QPolygonF polygon;
    polygon.append(line.p1() + o);
    polygon.append(line.p2() + o);
    polygon.append(line.p2() - o);
    polygon.append(line.p1() - o);
    return polygon;
}
Beispiel #5
0
QPolygonF QGVEdge::toArrow(const QLineF &line) const
{
    QLineF n = line.normalVector();
    QPointF o(n.dx() / 3.0, n.dy() / 3.0);

    //Only support normal arrow type
    QPolygonF polygon;
    polygon.append(line.p1() + o);
    polygon.append(line.p2());
    polygon.append(line.p1() - o);

    return polygon;
}
Beispiel #6
0
bool GraphConnection::isPointing(const QRectF &rect) const
{
    //check individual line segments
    for (int i = 1; i < _impl->points.size(); i++)
    {
        const QLineF line(_impl->points[i-1], _impl->points[i]);
        QLineF norm = line.normalVector(); norm.setLength(GraphConnectionSelectPad);
        if (QRectF(line.p2(), norm.p2()).intersects(rect)) return true;
    }

    //check arrow head
    return not _impl->arrowHead.intersected(rect).isEmpty();
}
void CopyFilterGUIConnectionItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
{
	QLineF l = line();
	if (!l.isNull())
	{
		painter->setBrush(Qt::black);
		if (isSelected())
		{
			painter->setBrush(Qt::blue);
			painter->setPen(QPen(Qt::blue, 1.5));
		}
		painter->drawLine(line());

		double length = line().length();
		double offset = min(length, maxArrowSize);
		QLineF unit = l.unitVector();
		QLineF normal = l.normalVector().unitVector();
		QPointF v(unit.dx(), unit.dy());
		QPointF n(normal.dx(), normal.dy());
		QPointF p2 = l.p2();

		QPointF p3 = p2 - v * offset + 0.5 * n * offset;
		QPointF p4 = p2 - v * offset - 0.5 * n * offset;
		QPolygonF polygon;
		polygon.append(p2);
		polygon.append(p3);
		polygon.append(p4);

		painter->drawPolygon(polygon);

		if (factor != 1.0 || isDecibel)
		{
			QFont font = painter->font();
			font.setPixelSize(10);
			painter->setFont(font);
			QPointF center = (l.p1() + l.p2()) / 2;
			QString text = QString("%1").arg(factor);
			if (isDecibel)
				text += " dB";

			QSizeF size = painter->fontMetrics().size(0, text);
			size += QSizeF(2, 0);
			QRectF rect;
			rect.setSize(size);
			rect.moveCenter(center);
			painter->setBrush(Qt::white);
			painter->drawRoundedRect(rect.adjusted(-0.5, 0.5, 0.5, 0.5), 3, 3);
			painter->drawText(rect, Qt::AlignCenter, text);
		}
	}
}
bool
TextLineTracer::isInsideBounds(
	QPointF const& pt, QLineF const& left_bound, QLineF const& right_bound)
{
	QPointF left_normal_inside(left_bound.normalVector().p2() - left_bound.p1());
	if (left_normal_inside.x() < 0) {
		left_normal_inside = -left_normal_inside;
	}
	QPointF const left_vec(pt - left_bound.p1());
	if (left_normal_inside.x() * left_vec.x() + left_normal_inside.y() * left_vec.y() < 0) {
		return false;
	}

	QPointF right_normal_inside(right_bound.normalVector().p2() - right_bound.p1());
	if (right_normal_inside.x() > 0) {
		right_normal_inside = -right_normal_inside;
	}
	QPointF const right_vec(pt - right_bound.p1());
	if (right_normal_inside.x() * right_vec.x() + right_normal_inside.y() * right_vec.y() < 0) {
		return false;
	}

	return true;
}
Beispiel #9
0
void GraphicsPathItem::paint (QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) {
	painter->setPen (QPen (QBrush (*_color), 0.1, Qt::SolidLine));
	painter->setBrush (QBrush (*_color));

	painter->drawLine (_start, _end);

	QPainterPath path;
	QLineF unit  = QLineF (_start, _end).unitVector ();
	QLineF normal = unit.normalVector ();
	QPointF u (unit.dx (), unit.dy ());
	QPointF v (normal.dx (), normal.dy ());
	QPointF middle = 0.5 * (QPointF(_start) + QPointF (_end));
	path.moveTo (middle + 0.4*u);
	path.lineTo (middle - 0.2*u + 0.2*v);
	path.lineTo (middle - 0.2*u - 0.2*v);
	path.closeSubpath ();
	painter->drawPath (path);
}
void
SplineTransferFunction::updateNormals()
{
  m_normals.clear();
  m_rightNormals.clear();
  m_leftNormals.clear();

  for (int i=0; i<m_points.size(); ++i)
    {
      QLineF ln;
      if (i == 0)
	ln = QLineF(m_points[i], m_points[i+1]);
      else if (i == m_points.size()-1)
	ln = QLineF(m_points[i-1], m_points[i]);
      else
	ln = QLineF(m_points[i-1], m_points[i+1]);
      
      QLineF unitVec;
      if (ln.length() > 0)
	unitVec = ln.normalVector().unitVector();
      else
	unitVec = QLineF(QPointF(0,0), QPointF(1,0));

      unitVec.translate(-unitVec.p1());

      float a = m_normalRotations[i];
      QPointF p1 = unitVec.p2();
      QPointF p2;
      p2.setX(p1.x()*cos(a) + p1.y()*sin(a));
      p2.setY(-p1.x()*sin(a) + p1.y()*cos(a));
      unitVec = QLineF(QPointF(0,0), p2);

      QPointF v1, v2;
      v1 = m_points[i] + m_normalWidths[i].x()*unitVec.p2();
      v2 = m_points[i] - m_normalWidths[i].y()*unitVec.p2();

      m_normals << unitVec.p2();
      m_rightNormals << v1;
      m_leftNormals << v2;
    }  
}
void VBezier::editPoints(QPointF p, VElement::EditAction action)
{
    static bool isDraging = false;
    static int currentNode;
    static int param;
    if(action == CLICK)
    {
        for(uint i=0;i<nodes.size();i++)
        {
            if(QLineF(nodes[i].p, p).length() < 6)
            {
                currentNode = i;
                param = 0;
                isDraging = true;
            }
            if(QLineF(nodes[i].c1, p).length() < 6)
            {
                currentNode = i;
                param = 1;
                isDraging = true;
            }
            if(QLineF(nodes[i].c2, p).length() < 6)
            {
                currentNode = i;
                param = 2;
                isDraging = true;
            }
        }
    }
    else if(action == DRAG)
    {
        if(isDraging)
        {
            if(param == 0)
            {
                VBezier::Node &n = nodes[currentNode];
                QPointF delta = p - n.p;
                n.p += delta;
                n.c1 += delta;
                n.c2 += delta;
            }
            else if(param == 1)
            {
                VBezier::Node &n = nodes[currentNode];
                QPointF delta = n.p - p;
                n.c1 = p;
                n.c2= n.p + delta;
            }
            if(param == 2)
            {
                VBezier::Node &n = nodes[currentNode];
                QPointF delta = n.p - p;
                n.c1= n.p + delta;
                n.c2 = p;
            }
            rebuildBB();
        }
    }
    else if(action == RELEASE)
    {
        isDraging = false;
    }
    else if(action == ADDPOINT)
    {
        std::vector<int> distanceToSide;
        int min = 0;
        nodes.push_back(nodes[0]); // dla linii między pierwszym i ostatnim wierzchołkiem
        for(uint i=0;i<nodes.size()-1;i++)
        {
            qreal distToA = QLineF(nodes[i].p, p).length();
            qreal distToB = QLineF(nodes[i+1].p, p).length();
            QLineF v(nodes[i].p, p);
            QLineF unit =  QLineF(nodes[i].p, nodes[i+1].p).unitVector();
            QLineF normal = unit.normalVector();

            qreal proj = unit.dx()*v.dx() + unit.dy()*v.dy();
            qreal distToLine = fabs(normal.dx()*v.dx() + normal.dy()*v.dy());

            if(proj<0)
                distToLine = distToA;
            if(proj>QLineF(nodes[i].p, nodes[i+1].p).length())
                distToLine = distToB;

            distanceToSide.push_back(distToLine);
            if(distanceToSide[i] < distanceToSide[min])
                min = i;
        }
        nodes.pop_back();
        min+=1;

        if(min == nodes.size())
        {
            qreal distToFirst = QLineF(nodes[0].p, p).length();
            qreal distToLast = QLineF(nodes[min-1].p, p).length();
            if(distToFirst < distToLast)
            {
                min = 0;
            }
        }

        Node newNode;
        newNode.p = p;
        newNode.c1 = p;
        newNode.c2 = p;
        nodes.insert(nodes.begin() + min, newNode);
        currentNode = min;
        isDraging = true;
        param = 2;
        rebuildBB();
    }
    else if(action == DELETEPOINT)
    {
        for(uint i=0;i<nodes.size();i++)
        {
            if(QLineF(nodes[i].p, p).length() < 6)
            {
                nodes.erase(nodes.begin()+i);
                rebuildBB();
                break;
            }
        }
    }
}
Beispiel #12
0
static ShiftResult shift(const QBezier *orig, QBezier *shifted, qreal offset, qreal threshold)
{
    int map[4];
    bool p1_p2_equal = (orig->x1 == orig->x2 && orig->y1 == orig->y2);
    bool p2_p3_equal = (orig->x2 == orig->x3 && orig->y2 == orig->y3);
    bool p3_p4_equal = (orig->x3 == orig->x4 && orig->y3 == orig->y4);

    QPointF points[4];
    int np = 0;
    points[np] = QPointF(orig->x1, orig->y1);
    map[0] = 0;
    ++np;
    if (!p1_p2_equal) {
        points[np] = QPointF(orig->x2, orig->y2);
        ++np;
    }
    map[1] = np - 1;
    if (!p2_p3_equal) {
        points[np] = QPointF(orig->x3, orig->y3);
        ++np;
    }
    map[2] = np - 1;
    if (!p3_p4_equal) {
        points[np] = QPointF(orig->x4, orig->y4);
        ++np;
    }
    map[3] = np - 1;
    if (np == 1)
        return Discard;

    QRectF b = orig->bounds();
    if (np == 4 && b.width() < .1*offset && b.height() < .1*offset) {
        qreal l = (orig->x1 - orig->x2)*(orig->x1 - orig->x2) +
                  (orig->y1 - orig->y2)*(orig->y1 - orig->y1) *
                  (orig->x3 - orig->x4)*(orig->x3 - orig->x4) +
                  (orig->y3 - orig->y4)*(orig->y3 - orig->y4);
        qreal dot = (orig->x1 - orig->x2)*(orig->x3 - orig->x4) +
                    (orig->y1 - orig->y2)*(orig->y3 - orig->y4);
        if (dot < 0 && dot*dot < 0.8*l)
            // the points are close and reverse dirction. Approximate the whole
            // thing by a semi circle
            return Circle;
    }

    QPointF points_shifted[4];

    QLineF prev = QLineF(QPointF(), points[1] - points[0]);
    QPointF prev_normal = prev.normalVector().unitVector().p2();

    points_shifted[0] = points[0] + offset * prev_normal;

    for (int i = 1; i < np - 1; ++i) {
        QLineF next = QLineF(QPointF(), points[i + 1] - points[i]);
        QPointF next_normal = next.normalVector().unitVector().p2();

        QPointF normal_sum = prev_normal + next_normal;

        qreal r = qreal(1.0) + prev_normal.x() * next_normal.x()
                  + prev_normal.y() * next_normal.y();

        if (qFuzzyIsNull(r)) {
            points_shifted[i] = points[i] + offset * prev_normal;
        } else {
            qreal k = offset / r;
            points_shifted[i] = points[i] + k * normal_sum;
        }

        prev_normal = next_normal;
    }

    points_shifted[np - 1] = points[np - 1] + offset * prev_normal;

    *shifted = QBezier::fromPoints(points_shifted[map[0]], points_shifted[map[1]],
                                   points_shifted[map[2]], points_shifted[map[3]]);

    return good_offset(orig, shifted, offset, threshold);
}