// Slow convolution, multiplying two polynomials.
// Complexity: O(nu * nv).
void conv(const Poly& u, const Poly& v, Poly& w) {
    if(u.empty() || v.empty()) {w.clear(); return;}
    int nu = u.size(), nv = v.size();
    w.assign(nu + nv - 1, 0);
    for(int i = 0; i < nu; i++)
        for(int j = 0; j < nv; j++)
            w[i+j] ^= (u[i] & v[j]);
    tidy(w);
}
示例#2
0
文件: poly.cpp 项目: luzpaz/scribus
Poly divide(Poly const &a, Poly const &b, Poly &r) {
	Poly c;
	r = a; // remainder
	assert(!b.empty());

	const unsigned k = a.degree();
	const unsigned l = b.degree();
	c.resize(k, 0.);

	for(unsigned i = k; i >= l; i--) {
		assert(i >= 0);
		double ci = r.back()/b.back();
		c[i-l] += ci;
		Poly bb = ci*b;
		//std::cout << ci <<"*(" << b.shifted(i-l) << ") = "
		//          << bb.shifted(i-l) << "     r= " << r << std::endl;
		r -= bb.shifted(i-l);
		r.pop_back();
	}
	//std::cout << "r= " << r << std::endl;
	r.normalize();
	c.normalize();

	return c;
}
示例#3
0
void reduce(Poly &v)
{
  while (!v.empty() && v.back() % MOD == 0)
  {
    v.pop_back();
  }
}
// GCD
void gcd(const Poly& m, const Poly& n, Poly& w) {
    if(n.empty()) {
        w = m;
        return;
    }
    Poly q, r;
    deconv(m, n, q, r);
    gcd(n, r, w);
}
示例#5
0
文件: poly.cpp 项目: luzpaz/scribus
Poly gcd(Poly const &a, Poly const &b, const double tol) {
	if(a.size() < b.size())
		return gcd(b, a);
	if(b.empty())
		return a;
	if(b.size() == 1)
		return a;
	Poly r;
	divide(a, b, r);
	return gcd(b, r);
}
示例#6
0
文件: helper.cpp 项目: payload/gorge
float checkCollision(const Poly& a, const Poly& b, Vec2* pnormal, Vec2* pwhere) {
	Vec2 normal;
	Vec2 where;
	if (a.empty() || b.empty()) return 0;

	float distance = 9e99;
	for (size_t m = 0; m < 2; m++) {
		const Poly* pa = m ? &a : &b;
		const Poly* pb = m ? &b : &a;

		Vec2 p1 = pa->back();
		for (Vec2 p2: *pa) {
			float c_d = 0;
			Vec2 c_n;
			Vec2 c_w;
			Vec2 n = {p1.y - p2.y, p2.x - p1.x};
			for (Vec2 w: *pb) {
				float d = (p1.x - w.x) * n.x + (p1.y - w.y) * n.y;
				if (d > c_d) {
					c_d = d;
					c_n = n;
					c_w = w;
				}
			}
			if (c_d == 0) return 0;
			float ool = 1 / sqrtf(n.x * n.x + n.y * n.y);
			c_d *= ool;
			if (c_d < distance) {
				distance = c_d;
				if (m == 1) ool = -ool;
				normal = n * ool;
				where = c_w;
			}
			p1 = p2;
		}
	}
	if (pnormal) *pnormal = normal;
	if (pwhere) *pwhere = where;
	return distance;
}
示例#7
0
bool is_zero(Poly p)
{
  reduce(p);
  return p.empty();
}
// Simplify the polynomial, eliminates the high-degree zero term.
void tidy(Poly& c) {
    while(!c.empty() && c.back() == 0)
        c.pop_back();
}