Пример #1
0
/**
 * Update text distribution between edges
 */
void GuiEdge::updateLabels()
{
	float sum_len = 0;
	QPoint end_sequence;

	bool first_run = full_label.length() == 0;

	for (GuiEdge* i = this;;
		i->succ()->firstSucc() && (i = addGui (i->succ()->firstSucc())))
	{
		sum_len += i->length();
		if (first_run) full_label += i->edgeLabel();
		if (i->succ() && i->succ()->real())
		{
			end_sequence = addAux(i->succ())->coor();
			break;
		}
	}

	float n_letters = 0;
	float last_round_up = 0;
	int full_len = full_label.length();
	
	QPoint delta = end_sequence - edge_start_point_priv.toPoint();
	reverse = -delta.x() > delta.y();

	QString buf = full_label;

	for (GuiEdge* i = this;;
		i->succ()->firstSucc() && (i = addGui (i->succ()->firstSucc())))
	{
		i->reverse = reverse;
		n_letters = full_len*i->length()/sum_len + last_round_up;	//give an appropriate substring
		last_round_up = n_letters - (int)n_letters;

		if (i->succ() && i->succ()->real())//take the last character
			n_letters ++;

		if (reverse)
		{
			i->setEdgeLabel (buf.right (n_letters));
			buf.remove (buf.length() + 1 - n_letters, n_letters);
		}
		else
		{
			i->setEdgeLabel (buf.left (n_letters));
			buf.remove (0, n_letters);
		}
		if (i->succ() && i->succ()->real()) break;

	}
}
Пример #2
0
int addAux(LinkedList & lsum, Node * nptr1, Node * nptr2) {
    if (nptr1 && nptr2) {
        int carry = addAux(lsum, nptr1->next, nptr2->next);
        int sum = carry + nptr1->getVal() + nptr2->getVal();
        lsum.prepend(new Node('0' + sum % 10));
        return sum / 10;
    }
    if (!nptr1 && !nptr2) {
        return 0;
    } else {
        assert(false); // For now
    }
}
Пример #3
0
/**
 * Draws a label near the edge
 */
void GuiEdge::drawText (QPainter * painter) const
{
	int len = edgeLabel().length();
	float k = 0.8f;
	float start = 0.1f;
	if (Edge::pred() && !addAux (Edge::pred())->real())//press letters to the virtual nodes
	{
		k += start;
		start = 0;
	}
	if (Edge::succ() && !addAux (Edge::succ())->real())//press letters to the virtual nodes
	{
		k = 1 - start;
	}
	if (reverse)
	{
		k = -k;
		start = 1 - start;
	}
	QPointF delta = edge_end_point_priv - edge_start_point_priv;
	float letter_size = 1.3*edge_curve_priv.length()/len;
	if (letter_size > 25) letter_size = 25;
	if (letter_size > 8 && !cycle())
	{

		for (int i = 0; i < len; ++i)
		{
			float slope = edge_curve_priv.slopeAtPercent (start + k*float(i)/len);
			float ang = atan(slope);
			QPointF pos = edge_curve_priv.pointAtPercent(start + k*float(i)/len);
			pos += QPointF (cos (Pi/2 + ang), sin(Pi/2 + ang))*letter_size;
			QFont curf = painter->font();
			curf.setPixelSize (letter_size);
			painter->setFont (curf);
			painter->drawText (pos, QString(edgeLabel().at(i)));
		}
	}
}
Пример #4
0
int main() {
    srand(time(0));
    std::cout << "--- Test lists when digits are in increasing magnitude\n";
    for (int k = 0; k < NUM_ITERATIONS; ++k) {
        int NUM_DIGITS1 = (rand() % NUM_DIGITS_MAX) + 1;
        int NUM_DIGITS2 = (rand() % NUM_DIGITS_MAX) + 1;
        LinkedList l1, l2;
        // Leading zeroes are handled like any other number for simple testing
        for (int i = 0; i < NUM_DIGITS1; ++i) {
            l1.append(new Node(rand() % 10 + '0'));
        }
        for (int i = 0; i < NUM_DIGITS2; ++i) {
            l2.append(new Node(rand() % 10 + '0'));
        }
        LinkedList lsum;
        Node * n1, * n2;
        n1 = l1.root;
        n2 = l2.root;
        int carry = 0;
        while (n1 && n2) {
            int sum = n1->getVal() + n2->getVal() + carry;
            lsum.append(new Node('0' + sum % 10));
            carry = sum / 10;
            n1 = n1->next;
            n2 = n2->next;
        }
        if (n1 || n2) { // One # was longer than the other
            Node * n = n1 ? n1 : n2;
            while (n) {
                int sum = n->getVal() + carry;
                lsum.append(new Node('0' + sum % 10));
                carry = sum / 10;
                n = n->next;
            }
        }
        if (carry) {
            lsum.append(new Node('0' + carry));
        }
        std::cout << l1.toNum(1) << " + " << l2.toNum(1) << " = "
                  << lsum.toNum(1) << std::endl;
        assert(l1.toNum(1) + l2.toNum(1) == lsum.toNum(1));
    }
    std::cout << "--- Test lists when digits are in decreasing magnitude\n";
    for (int k = 0; k < NUM_ITERATIONS; ++k) {
        int NUM_DIGITS1 = (rand() % NUM_DIGITS_MAX) + 1;
        int NUM_DIGITS2 = (rand() % NUM_DIGITS_MAX) + 1;
        LinkedList l1, l2, lsum;
        for (int i = 0; i < NUM_DIGITS1; ++i) {
            l1.append(new Node(rand() % 10 + '0'));
        }
        for (int i = 0; i < NUM_DIGITS2; ++i) {
            l2.append(new Node(rand() % 10 + '0'));
        }
        // Add filler digits to generalize to the case where lists are same size
        while (l1.size < l2.size) {
            l1.prepend(new Node('0'));
        }
        while (l2.size < l1.size) {
            l2.prepend(new Node('0'));
        }
        int carry = addAux(lsum, l1.root, l2.root);
        if (carry) {
            lsum.prepend(new Node('0' + carry));
        }
        std::cout << l1.toNum(0) << " + " << l2.toNum(0) << " = "
                 << lsum.toNum(0) << std::endl;
        assert(l1.toNum(0) + l2.toNum(0) == lsum.toNum(0));
    }
    return 0;
}
Пример #5
0
/**
 * Update position the edge
 */
void GuiEdge::updatePosition (bool original_run)
{
	GuiNode* pre = addGui (pred());
	GuiNode* suc = addGui (succ());

	edge_start_point_priv = mapFromItem( pre, pre->width()/2, pre->height()/2);
    edge_end_point_priv = mapFromItem( suc, suc->width()/2, suc->height()/2);//!!!rarely it not work

	if (pre == suc)//mesh edge
	{
		QPointF heigh (0, 2*pre->height());

		QPointF middle (pre->pos().x() - 10, pre->pos().y() + pre->height()/2);
		QPointF middleDirUp = middle + heigh;
		QPointF middleDirDown = middle - heigh;

		edge_start_dir_priv = edge_start_point_priv + heigh;
		edge_end_dir_priv = edge_end_point_priv - heigh;

		QPolygonF polygon = suc->polygon();
		polygon.translate (suc->pos());
		getIntersection (QLineF (edge_start_point_priv, edge_start_dir_priv), polygon, &edge_start_point_priv);
		getIntersection (QLineF (edge_end_point_priv, edge_end_dir_priv), polygon, &edge_end_point_priv);

		QPainterPath path;
		path.moveTo (edge_start_point_priv);
		path.cubicTo (edge_start_dir_priv, middleDirUp, middle);
		path.cubicTo (middleDirDown, edge_end_dir_priv, edge_end_point_priv);
		edge_curve_priv = path;
	}
	else
	{
		edge_valid_priv = true;
		
		QPolygonF headPolygon = suc->polygon();
		headPolygon.translate (suc->pos());
		QPolygonF tailPolygon = pre->polygon();
		tailPolygon.translate (pre->pos());


		if (suc->real())
			edge_valid_priv = edge_valid_priv && getIntersection (QLineF (edge_start_point_priv, edge_end_point_priv), headPolygon, &edge_end_point_priv) == QLineF::BoundedIntersection;
		if (pre->real()) 
			edge_valid_priv = edge_valid_priv && getIntersection (QLineF (edge_start_point_priv, edge_end_point_priv), tailPolygon, &edge_start_point_priv) == QLineF::BoundedIntersection;

		QPointF delta = edge_start_point_priv - edge_end_point_priv;
		delta.setX(0);

		if (pre->real()) 
			edge_start_dir_priv = (edge_start_point_priv + edge_end_point_priv)/2;
		else
		{
			if (pre->firstPred() != 0)
				edge_start_dir_priv = (suc->coor() - pre->firstPred()->pred()->coor())/8 + pre->coor();
			else
				edge_start_dir_priv = edge_start_point_priv - delta/2;
		}

		if (suc->real())
			edge_end_dir_priv = (edge_start_point_priv + edge_end_point_priv)/2;
		else
			if (suc->firstSucc() != 0)
				edge_end_dir_priv = (pre->coor() - suc->firstSucc()->succ()->coor())/8 + suc->coor();
			else
				edge_end_dir_priv = edge_end_point_priv + delta/2;

		QPainterPath path;
		path.moveTo (edge_start_point_priv);
		path.cubicTo (edge_start_dir_priv, edge_end_dir_priv, edge_end_point_priv);

		if (edge_valid_priv) edge_curve_priv = path;
	}

    edge_top_left_priv.setX( min< qreal>( edge_start_point_priv.x(), edge_end_point_priv.x()));
    edge_top_left_priv.setY( min< qreal>( edge_start_point_priv.y(), edge_end_point_priv.y()));
    edge_bottom_right_priv.setX( max< qreal>( edge_start_point_priv.x(), edge_end_point_priv.x()));
    edge_bottom_right_priv.setY( max< qreal>( edge_start_point_priv.y(), edge_end_point_priv.y())); 

	if (original_run)
	{
		if (Edge::succ() && !addAux (Edge::succ())->real() && Edge::succ()->firstSucc())
			addGui (Edge::succ()->firstSucc())->updatePosition (false);//avoidance sharp corners
		
		if (Edge::pred() && !addAux (Edge::pred())->real() && Edge::pred()->firstPred())
			addGui (Edge::pred()->firstPred())->updatePosition (false);//avoidance sharp corners
		
		GuiEdge* i = this;
		for (i; !i->startEdge(); i->pred()->firstPred() && (i = addGui (i->pred()->firstPred())));
		i->updateLabels();
	}
    prepareGeometryChange();
}
Пример #6
0
/**
 * Return if this edge first in a sequence
 */
bool GuiEdge::startEdge() const
{//		   pred exists and, it real					or it is a root
	return Edge::pred() && (addAux (Edge::pred())->real() || addAux (Edge::pred())->isRoot());
}