Пример #1
0
QRect CurveTracker::trackerRect( const QFont &font ) const
{
    QRect r = QwtPlotPicker::trackerRect( font );
    
    // align r to the first curve

    const QwtPlotItemList curves = plot()->itemList( QwtPlotItem::Rtti_PlotCurve );
    if ( curves.size() > 0 )
    {
        QPointF pos = invTransform( trackerPosition() );

        const QLineF line = curveLineAt(    
            static_cast<const QwtPlotCurve *>( curves[0] ), pos.x() );
        if ( !line.isNull() )
        {
            const double curveY = line.pointAt(
                ( pos.x() - line.p1().x() ) / line.dx() ).y();

            pos.setY( curveY );
            pos = transform( pos );

            r.moveBottom( pos.y() );            
        }
    }

    return r;
}
Пример #2
0
QPointF CanvasMode_EditSpiral::getSegment(double angle)
{
	PageItem *currItem = m_doc->m_Selection->itemAt(0);
	PageItem_Spiral *item = currItem->asSpiral();
	double ww = item->width();
	double wws = 0.0;
	double wwn = ww;
	double hh = item->height() - (item->height() / (item->spiralFactor + 1.0));
	double segStart = 0.0;
	double segEnd = 180;
	bool segPart = true;
	QPointF ret = QPointF(item->width() / 2.0, item->height() / 2.0);
	if (angle < 0)
		return ret;
	while (true)
	{
		QLineF lin = QLineF(QPointF(wws, hh), QPointF(wwn, hh));
		if ((angle <= segEnd) && (angle >= segStart))
		{
			ret = lin.pointAt(0.5);
			break;
		}
		ww /= item->spiralFactor;
		wws = wwn;
		if (segPart)
			wwn -= ww;
		else
			wwn += ww;
		segPart = !segPart;
		segStart += 180.0;
		segEnd += 180.0;
	}
	return ret;
}
Пример #3
0
QString CurveTracker::curveInfoAt( 
    const QwtPlotCurve *curve, const QPointF &pos ) const
{
    const QLineF line = curveLineAt( curve, pos.x() );
    if ( line.isNull() )
        return QString::null;

    QPointF p = line.pointAt(( pos.x() - line.p1().x() ) / line.dx());

    QString info( "<font color=""%1"">%2 / %3</font>" );
    return info.arg( curve->pen().color().name() ).arg( p.y() ).arg(p.x());
}
Пример #4
0
bool lineBoundedByRect(QLineF& line, QRectF const& rect)
{
	QLineF const rect_lines[4] = {
		QLineF(rect.topLeft(), rect.topRight()),
		QLineF(rect.bottomLeft(), rect.bottomRight()),
		QLineF(rect.topLeft(), rect.bottomLeft()),
		QLineF(rect.topRight(), rect.bottomRight())
	};
	
	double max = NumericTraits<double>::min();
	double min = NumericTraits<double>::max();

	double s1 = 0;
	double s2 = 0;
	BOOST_FOREACH(QLineF const& rect_line, rect_lines) {	
		if (!lineIntersectionScalar(rect_line, line, s1, s2)) {
			// line is parallel to rect_line.
			continue;
		}
		if (s1 < 0 || s1 > 1) {
			// Intersection outside of rect.
			continue;
		}

		if (s2 > max) {
			max = s2;
		}
		if (s2 < min) {
			min = s2;
		}
	}

	if (max > min) {
		line = QLineF(line.pointAt(min), line.pointAt(max));
		return true;
	} else {
		return false;
	}
}
Пример #5
0
QPointF LineObject::objectMidPoint() const
{
    QLineF lyne = line();
    QPointF mp = lyne.pointAt(0.5);
    qreal rot = radians(rotation());
    qreal cosRot = qCos(rot);
    qreal sinRot = qSin(rot);
    qreal mx = mp.x()*scale();
    qreal my = mp.y()*scale();
    qreal rotMidX = mx*cosRot - my*sinRot;
    qreal rotMidY = mx*sinRot + my*cosRot;

    return (scenePos() + QPointF(rotMidX, rotMidY));
}
Пример #6
0
const QPointF PortHandler::nearestPort(const QPointF &location, const QStringList &types) const
{
	// location in scene coords, so we map it to mNode.
	const QPointF locationInLocalCoords = mNode->mapFromScene(location);

	QPointF nearestPortPoint;
	qreal minDistance = -1; // just smth negative

	// Point port observing.
	QPair<int, qreal> const pointPortRes = nearestPointPortNumberAndDistance(locationInLocalCoords, types);
	if (pointPortRes.second >= 0) {
		minDistance = pointPortRes.second;
		nearestPortPoint = transformPortForNodeSize(mPointPorts[pointPortRes.first]);
	}

	// Line port observing.
	QPair<int, qreal> const linePortRes = nearestLinePortNumberAndDistance(locationInLocalCoords, types);
	if (linePortRes.second >= 0 &&
		(linePortRes.second < minDistance || minDistance < 0)
	) {
		minDistance = linePortRes.second;
		const qreal positionAtLineCoef = qMin(qMax(0., nearestPointOfLinePort(linePortRes.first, locationInLocalCoords))
				, mMaximumFractionPartValue);
		const QLineF sceneLine = transformPortForNodeSize(mLinePorts[linePortRes.first]);
		nearestPortPoint = sceneLine.pointAt(positionAtLineCoef);
	}

	QPair<int, qreal> const circularPortRes = nearestCircularPortNumberAndDistance(locationInLocalCoords, types);
	if (circularPortRes.second >= 0 &&
		(circularPortRes.second < minDistance || minDistance < 0))
	{
		minDistance = circularPortRes.second;
		nearestPortPoint = coordinateOfCircular(circularPortRes.first, locationInLocalCoords);
	}

	if (minDistance > -0.5) {
		// Moving to scene coords.
		return nearestPortPoint;
	}

	return location;
}
Пример #7
0
GridLineTraverser::GridLineTraverser(QLineF const& line)
{
	QPoint const p1(line.p1().toPoint());
	QPoint const p2(line.p2().toPoint());
	int h_spans, v_spans, num_spans;
	double s1 = 0.0, s2 = 0.0;
	if ((h_spans = abs(p1.x() - p2.x())) > (v_spans = abs(p1.y() - p2.y()))) {
		// Major direction: horizontal.
		num_spans = h_spans;
		lineIntersectionScalar(line, QLineF(p1, QPoint(p1.x(), p1.y() + 1)), s1);
		lineIntersectionScalar(line, QLineF(p2, QPoint(p2.x(), p2.y() + 1)), s2);
	} else {
		// Major direction: vertical.
		num_spans = v_spans;
		lineIntersectionScalar(line, QLineF(p1, QPoint(p1.x() + 1, p1.y())), s1);
		lineIntersectionScalar(line, QLineF(p2, QPoint(p2.x() + 1, p2.y())), s2);
	}
	
	m_dt = num_spans == 0 ? 0 : 1.0 / num_spans;
	m_line.setP1(line.pointAt(s1));
	m_line.setP2(line.pointAt(s2));
	m_totalStops = num_spans + 1;
	m_stopsDone = 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;

    // We need to specialcase lines of 3 or 4 points due to numerical
    // instability in intersections below
    if (np > 2 && qbezier_is_line(points, np)) {
        if (points[0] == points[np-1])
            return Discard;

        QLineF l = qline_shifted(points[0], points[np-1], offset);
        *shifted = QBezier::fromPoints(l.p1(), l.pointAt(qreal(0.33)), l.pointAt(qreal(0.66)), l.p2());
        return Ok;
    }

    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 = 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);
}