qreal polynomIntegral(const Polynom &p) {
	// all xPow's should be zero
	qreal result = 0;
	for (int i = 0; i < p.size(); ++i)
		result += p.at(i).c / (1 + p.at(i).yPow);
	return result;
}
void addToPolynom(Polynom &p, const Monom &m) {
	for (int i = 0; i < p.size(); ++i)
		if (p.at(i).xPow == m.xPow && p.at(i).yPow == m.yPow) {
			p[i].c += m.c;
			return;
		}
	if (!qFuzzyIsNull(m.c))
		p.append(m);
}
Polynom polynomMultiply(const Polynom &p1, const Polynom &p2) {
	Polynom result;
	int i, j;
	Monom m;
	for (i = 0; i < p1.size(); ++i)
		for (j = 0; j < p2.size(); ++j) {
			m.xPow = p1.at(i).xPow + p2.at(j).xPow;
			m.yPow = p1.at(i).yPow + p2.at(j).yPow;
			m.c = p1.at(i).c * p2.at(j).c;
			addToPolynom(result, m);
		}
	return result;
}
void addToPolynom(Polynom &p, quint32 xPow, quint32 yPow, qreal c) {
	if (qFuzzyIsNull(c))
		return;
	for (int i = 0; i < p.size(); ++i)
		if (p.at(i).xPow == xPow && p.at(i).yPow == yPow) {
			p[i].c += c;
			return;
		}
	Monom m;
	m.xPow = xPow;
	m.yPow = yPow;
	m.c = c;
	p.append(m);
}
qreal getIntegralForGoodTriangle(QPointF * const triangle, const Polynom &polynom) {
	qreal transform[4];
	transformateTriangle(triangle, transform);
	qreal newcx = transform[0] * triangle[2].x() + transform[2];
	Polynom newPolynom, polynomPart1, polynomPart2, polynomBase;
	int i, j;
	for (i = 0; i < polynom.size(); ++i) {
		polynomPart1.clear();
		polynomBase.clear();
		addToPolynom(polynomBase, 1, 0, 1 / transform[0]);
		addToPolynom(polynomBase, 0, 0, -transform[2] / transform[0]);
		polynomPart1 = polynomPower(polynomBase, polynom.at(i).xPow);
		polynomPart2.clear();
		polynomBase.clear();
		addToPolynom(polynomBase, 0, 1, 1 / transform[1]);
		addToPolynom(polynomBase, 0, 0, -transform[3] / transform[1]);
		polynomPart2 = polynomPower(polynomBase, polynom.at(i).yPow);
		for (j = 0; j < polynomPart2.size(); ++j)
			polynomPart2[j].c *= polynom.at(i).c;
		newPolynom = polynomAdd(newPolynom,
			polynomMultiply(polynomPart1, polynomPart2));
	}
	qreal result = 0;
	for (i = 0; i < newPolynom.size(); ++i) {
		polynomBase.clear();
		addToPolynom(polynomBase, 0, 0, 1);
		addToPolynom(polynomBase, 0, 1, newcx - 1);
		polynomBase = polynomPower(polynomBase, newPolynom.at(i).xPow + 1);
		addToPolynom(polynomBase, 0,
			newPolynom.at(i).xPow + 1, qPow(newcx, newPolynom.at(i).xPow + 1));
		for (j = 0; j < polynomBase.size(); ++j) {
			polynomBase[j].c /= newPolynom.at(i).xPow + 1;
			polynomBase[j].yPow += newPolynom.at(i).yPow;
		}
		result += newPolynom.at(i).c * polynomIntegral(polynomBase) /
			qAbs(transform[0] * transform[1]);
	}
	return result;
}
Polynom polynomAdd(const Polynom &p1, const Polynom &p2) {
	Polynom result = p1;
	for (int i = 0; i < p2.size(); ++i)
		addToPolynom(result, p2.at(i));
	return result;
}