Beispiel #1
0
void PageItem_Line::getBoundingRect(double *x1, double *y1, double *x2, double *y2) const
{
	double minx =  std::numeric_limits<double>::max();
	double miny =  std::numeric_limits<double>::max();
	double maxx = -std::numeric_limits<double>::max();
	double maxy = -std::numeric_limits<double>::max();
	if (m_rotation != 0)
	{
		FPointArray pb;
		pb.resize(0);
		pb.addPoint(FPoint(0,       -m_lineWidth / 2.0, m_xPos, m_yPos, m_rotation, 1.0, 1.0));
		pb.addPoint(FPoint(m_width, -m_lineWidth / 2.0, m_xPos, m_yPos, m_rotation, 1.0, 1.0));
		pb.addPoint(FPoint(m_width, +m_lineWidth / 2.0, m_xPos, m_yPos, m_rotation, 1.0, 1.0));
		pb.addPoint(FPoint(0,       +m_lineWidth / 2.0, m_xPos, m_yPos, m_rotation, 1.0, 1.0));
		for (uint pc = 0; pc < 4; ++pc)
		{
			minx = qMin(minx, pb.point(pc).x());
			miny = qMin(miny, pb.point(pc).y());
			maxx = qMax(maxx, pb.point(pc).x());
			maxy = qMax(maxy, pb.point(pc).y());
		}
		*x1 = minx;
		*y1 = miny;
		*x2 = maxx;
		*y2 = maxy;
	}
	else
	{
		*x1 = m_xPos;
		*y1 = m_yPos - qMax(1.0, m_lineWidth) / 2.0;
		*x2 = m_xPos + m_width;
		*y2 = m_yPos + qMax(1.0, m_lineWidth) / 2.0;
	}

	QRectF totalRect = QRectF(QPointF(*x1, *y1), QPointF(*x2, *y2));
	if (m_startArrowIndex != 0)
	{
		QTransform arrowTrans;
		FPointArray arrow = m_Doc->arrowStyles().at(m_startArrowIndex-1).points.copy();
		arrowTrans.translate(m_xPos, m_yPos);
		arrowTrans.rotate(m_rotation);
		arrowTrans.translate(0, 0);
		arrowTrans.scale(m_startArrowScale / 100.0, m_startArrowScale / 100.0);
		if (NamedLStyle.isEmpty())
		{
			if (m_lineWidth != 0.0)
				arrowTrans.scale(m_lineWidth, m_lineWidth);
		}
		else
		{
			multiLine ml = m_Doc->MLineStyles[NamedLStyle];
			if (ml[ml.size()-1].Width != 0.0)
				arrowTrans.scale(ml[ml.size()-1].Width, ml[ml.size()-1].Width);
		}
		arrowTrans.scale(-1,1);
		arrow.map(arrowTrans);
		FPoint minAr = getMinClipF(&arrow);
		FPoint maxAr = getMaxClipF(&arrow);
		totalRect = totalRect.united(QRectF(QPointF(minAr.x(), minAr.y()), QPointF(maxAr.x(), maxAr.y())));
	}
	if (m_endArrowIndex != 0)
	{
		QTransform arrowTrans;
		FPointArray arrow = m_Doc->arrowStyles().at(m_endArrowIndex-1).points.copy();
		arrowTrans.translate(m_xPos, m_yPos);
		arrowTrans.rotate(m_rotation);
		arrowTrans.translate(m_width, 0);
		arrowTrans.scale(m_endArrowScale / 100.0, m_endArrowScale / 100.0);
		if (NamedLStyle.isEmpty())
		{
			if (m_lineWidth != 0.0)
				arrowTrans.scale(m_lineWidth, m_lineWidth);
		}
		else
		{
			multiLine ml = m_Doc->MLineStyles[NamedLStyle];
			if (ml[ml.size()-1].Width != 0.0)
				arrowTrans.scale(ml[ml.size()-1].Width, ml[ml.size()-1].Width);
		}
		arrow.map(arrowTrans);
		FPoint minAr = getMinClipF(&arrow);
		FPoint maxAr = getMaxClipF(&arrow);
		totalRect = totalRect.united(QRectF(QPointF(minAr.x(), minAr.y()), QPointF(maxAr.x(), maxAr.y())));
	}
	totalRect.getCoords(x1, y1, x2, y2);
}
bool AbstractCoordinateSystem::clipLineToRect(QLineF *line, const QRectF &rect, LineClipResult *clipResult) {
	//we usually clip on large rectangles, so we don't need high precision here -> round to one float digit
	//this prevents some subtle float rounding artefacts that lead to disappearance
	//of lines along the boundaries of the rect. (e.g. axis lines).
	qreal x1 = round(line->x1(), 1);
	qreal x2 = round(line->x2(), 1);
	qreal y1 = round(line->y1(), 1);
	qreal y2 = round(line->y2(), 1);

	qreal left;
	qreal right;
	qreal top;
	qreal bottom;
	rect.getCoords(&left, &top, &right, &bottom);

	if (clipResult)
		clipResult->reset();

	enum { Left, Right, Top, Bottom };
	// clip the lines, after cohen-sutherland, see e.g. http://www.nondot.org/~sabre/graphpro/line6.html
	int p1 = ((x1 < left) << Left)
	         | ((x1 > right) << Right)
	         | ((y1 < top) << Top)
	         | ((y1 > bottom) << Bottom);
	int p2 = ((x2 < left) << Left)
	         | ((x2 > right) << Right)
	         | ((y2 < top) << Top)
	         | ((y2 > bottom) << Bottom);

	if (p1 & p2)
		// completely outside
		return false;

	if (p1 | p2) {
		qreal dx = x2 - x1;
		qreal dy = y2 - y1;

		// clip x coordinates
		if (x1 < left) {
			y1 += dy/dx * (left - x1);
			x1 = left;
			if (clipResult)
				clipResult->xClippedLeft[0] = true;
		} else if (x1 > right) {
			y1 -= dy/dx * (x1 - right);
			x1 = right;
			if (clipResult)
				clipResult->xClippedRight[0] = true;
		}
		if (x2 < left) {
			y2 += dy/dx * (left - x2);
			x2 = left;
			if (clipResult)
				clipResult->xClippedLeft[1] = true;
		} else if (x2 > right) {
			y2 -= dy/dx * (x2 - right);
			x2 = right;
			if (clipResult)
				clipResult->xClippedRight[1] = true;
		}
		p1 = ((y1 < top) << Top)
		     | ((y1 > bottom) << Bottom);
		p2 = ((y2 < top) << Top)
		     | ((y2 > bottom) << Bottom);
		if (p1 & p2)
			return false;
		// clip y coordinates
		if (y1 < top) {
			x1 += dx/dy * (top - y1);
			y1 = top;
			if (clipResult) {
				clipResult->xClippedRight[0] = false;
				clipResult->xClippedLeft[0] = false;
				clipResult->yClippedTop[0] = true;
			}
		} else if (y1 > bottom) {
			x1 -= dx/dy * (y1 - bottom);
			y1 = bottom;
			if (clipResult) {
				clipResult->xClippedRight[0] = false;
				clipResult->xClippedLeft[0] = false;
				clipResult->yClippedBottom[0] = true;
			}
		}
		if (y2 < top) {
			x2 += dx/dy * (top - y2);
			y2 = top;
			if (clipResult) {
				clipResult->xClippedRight[1] = false;
				clipResult->xClippedLeft[1] = false;
				clipResult->yClippedTop[1] = true;
			}
		} else if (y2 > bottom) {
			x2 -= dx/dy * (y2 - bottom);
			y2 = bottom;
			if (clipResult) {
				clipResult->xClippedRight[1] = false;
				clipResult->xClippedLeft[1] = false;
				clipResult->yClippedBottom[1] = true;
			}
		}
		*line = QLineF(QPointF(x1, y1), QPointF(x2, y2));
	}
	return true;
}
Beispiel #3
0
void PageItem_Spiral::getBoundingRect(double *x1, double *y1, double *x2, double *y2) const
{
	PageItem::getBoundingRect(x1, y1, x2, y2);
	QRectF totalRect = QRectF(QPointF(*x1, *y1), QPointF(*x2, *y2));
	if (m_startArrowIndex != 0 && !PoLine.empty())
	{
		QTransform arrowTrans;
		FPointArray arrow = m_Doc->arrowStyles().at(m_startArrowIndex-1).points.copy();
		arrowTrans.translate(m_xPos, m_yPos);
		arrowTrans.rotate(m_rotation);
		FPoint Start = PoLine.point(0);
		for (int xx = 1; xx < PoLine.size(); xx += 2)
		{
			FPoint Vector = PoLine.point(xx);
			if ((Start.x() != Vector.x()) || (Start.y() != Vector.y()))
			{
				arrowTrans.translate(Start.x(), Start.y());
				arrowTrans.rotate(atan2(Start.y()-Vector.y(),Start.x()-Vector.x())*(180.0/M_PI));
				arrowTrans.scale(m_startArrowScale / 100.0, m_startArrowScale / 100.0);
				if (NamedLStyle.isEmpty())
				{
					if (m_lineWidth != 0.0)
						arrowTrans.scale(m_lineWidth, m_lineWidth);
				}
				else
				{
					multiLine ml = m_Doc->MLineStyles[NamedLStyle];
					if (ml[ml.size()-1].Width != 0.0)
						arrowTrans.scale(ml[ml.size()-1].Width, ml[ml.size()-1].Width);
				}
				arrow.map(arrowTrans);
				break;
			}
		}
		FPoint minAr = getMinClipF(&arrow);
		FPoint maxAr = getMaxClipF(&arrow);
		totalRect = totalRect.united(QRectF(QPointF(minAr.x(), minAr.y()), QPointF(maxAr.x(), maxAr.y())));
	}
	if (m_endArrowIndex != 0 && PoLine.size() >= 2)
	{
		QTransform arrowTrans;
		FPointArray arrow = m_Doc->arrowStyles().at(m_endArrowIndex-1).points.copy();
		arrowTrans.translate(m_xPos, m_yPos);
		arrowTrans.rotate(m_rotation);
		FPoint End = PoLine.point(PoLine.size()-2);
		for (uint xx = PoLine.size()-1; xx > 0; xx -= 2)
		{
			FPoint Vector = PoLine.point(xx);
			if ((End.x() != Vector.x()) || (End.y() != Vector.y()))
			{
				arrowTrans.translate(End.x(), End.y());
				arrowTrans.rotate(atan2(End.y()-Vector.y(),End.x()-Vector.x())*(180.0/M_PI));
				arrowTrans.scale(m_endArrowScale / 100.0, m_endArrowScale / 100.0);
				if (NamedLStyle.isEmpty())
				{
					if (m_lineWidth != 0.0)
						arrowTrans.scale(m_lineWidth, m_lineWidth);
				}
				else
				{
					multiLine ml = m_Doc->MLineStyles[NamedLStyle];
					if (ml[ml.size()-1].Width != 0.0)
						arrowTrans.scale(ml[ml.size()-1].Width, ml[ml.size()-1].Width);
				}
				arrow.map(arrowTrans);
				break;
			}
		}
		FPoint minAr = getMinClipF(&arrow);
		FPoint maxAr = getMaxClipF(&arrow);
		totalRect = totalRect.united(QRectF(QPointF(minAr.x(), minAr.y()), QPointF(maxAr.x(), maxAr.y())));
	}
	totalRect.getCoords(x1, y1, x2, y2);
}
Beispiel #4
0
void SourceWidget::mouseReleaseEvent(QMouseEvent *event)
{
    // Once the user releases the mouse, the selection process is finished. We need to
    // extract the selection and update the glWidget
    if (event->button() == Qt::LeftButton) {
        
        // Draw the last line
        path.lineTo(event->pos());
        path.connectPath(path);
        update();
		
		// TODO: safety due to CGAL fail
//		if (path.length()<20)
//			return;

        QPolygonF selectionPoly = path.toFillPolygon();
        QRectF boundingRect = selectionPoly.boundingRect();
		
		// Don't pass bad selections on
		if (boundingRect.width()>20 && boundingRect.height()>20)
			;
		else
			return;
		
		// adjusted - boundary value will be cut without it
        QImage sourcePatch = image.copy(boundingRect.toRect().adjusted(-1,-1,1,1)); 
        
        // Pass source patch pixels to glWidet
        glWidget->setSourcePatch(sourcePatch);
        
        qreal x0,x1,y0,y1;
        boundingRect.getCoords(&x0,&y0,&x1,&y1);
		
		
		
        // Find a point on the boundary of the selection
        QPoint cPoint(-1,-1);
        for (int x=x0; x<=x1; x++) {
            for (int y=y0; y<=y1; y++) {
                if (selectionPoly.containsPoint(QPointF(x,y),Qt::WindingFill))
                    cPoint = QPoint(x,y);
            }
        }

        //assert(cPoint != QPoint(-1,-1));
		//TODO: No violence please...
		if (cPoint == QPoint(-1,-1)){
			qDebug() << "assert(cPoint != QPoint(-1,-1)) fails";
			return;
		}
		
        // Track the boundary of the selection
        std::vector<Point> boundaryVector;
        
        // TODO: Why does it fail with dir=0 ???
        int dir = 1;
        int x,y;
        int c=0;
        bool cont = true;
        do {
            x = cPoint.x();
            y = cPoint.y();
            cPoint = findStartingFromDir(selectionPoly ,x, y, dir);
            boundaryVector.push_back(Point((cPoint.x()-x0),((y1-y0) - (cPoint.y()-y0))));

            if (boundaryVector.size()>3){
                if(boundaryVector[0]==boundaryVector[c-1] && boundaryVector[1]==boundaryVector[c]){
                    boundaryVector.pop_back();
                    boundaryVector.pop_back();
                    cont = false;
                }
            }
            c++;
        } while (cont);
		
		if (boundaryVector.size()>8192) {
			path = QPainterPath();
			update();
			QMessageBox::warning(this, tr("Boundary Size"),
							   tr("Largest supported boundary size is 8192"));
			return;
		}
		
//		// Subsample
//		std::vector<Point> boundaryVectorNew;
//		bool subs = false;
//		for(std::vector<Point>::const_iterator it = boundaryVector.begin(); it != boundaryVector.end(); ++it){
//			if(subs)
//				boundaryVectorNew.push_back(Point((*it).x(),(*it).y()));
//			subs = 1-subs;
//		}
//		boundaryVector = boundaryVectorNew;
		
//		// Subsample
//		QPolygon selectionPolyNew; 
//		int i = 0;
//		for(std::vector<Point>::const_iterator it = boundaryVector.begin(); it != boundaryVector.end(); ++it){
//			selectionPolyNew.setPoint(i, (*it).x(), (*it).y());
//			i++;
//		}	

        // TODO: Since we didn't figure out the way yet to get from CGAL the information
        // about the whenever triangle inside the boundary, glWidget will do it with
        // the help of selectionPoly
		
//		QPolygon temp(boundaryVector);
//		selectionPoly = QPolygonF(temp);
		
        selectionPoly.translate(-x0,-y0);
//        boundingRect = selectionPoly.boundingRect();
//        boundingRect.getCoords(&x0,&y0,&x1,&y1);
        glWidget->updateSelection(boundaryVector, selectionPoly);
        glWidget->update();
    }
}