//============================================================================== void multiply(const expansion& a, double b, expansion& product) { // basic idea: // multiply each entry in a by b (producing two new entries), then // two_sum them in such a way to guarantee increasing/non-overlapping output product.resize(2*a.size()); if(a.empty()) return; two_product(a[0], b, product[1], product[0]); // finalize product[0] double x, y, z; for(unsigned int i=1; i<a.size(); ++i){ two_product(a[i], b, x, y); // finalize product[2*i-1] two_sum(product[2*i-1], y, z, product[2*i-1]); // finalize product[2*i], could be fast_two_sum instead fast_two_sum(x, z, product[2*i+1], product[2*i]); } // multiplication is a prime candidate for producing spurious zeros, so // remove them by default remove_zeros(product); }
Sign orientation_essa(const segment& s, const point& p) { double a[12]; a[0] = two_product(s.b.x, p.y, a[1]); a[2] = two_product(s.a.y, p.x, a[3]); a[4] = two_product(s.a.x, s.b.y, a[5]); a[6] = two_product(s.a.x, -p.y, a[7]); a[8] = two_product(s.b.y, -p.x, a[9]); a[10] = two_product(s.a.y, -s.b.x, a[11]); return signum<12>(a); }
int predicates::orientation(const point &a, const point &b, const point &c) { // (b - a) x (c - a) // b - a = v1 = (b.x - a.x, b.y - a.y) // c - a = v2 = (c.x - a.x, c.y - a.y) // v1 x v2 = v1.x * v2.y - v1.y * v2.x // v1 x v2 = (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x) // v1 x v2 = b.x * c.y - a.x * c.y - b.x * a.y // + a.x * a.y // -b.y * c.x + a.y * c.x + b.y * a.x // - a.y * a.x expansion e; e.add(two_product(b.x, c.y)); e.add(two_product(-a.x, c.y)); e.add(two_product(-b.x, a.y)); e.add(two_product(-b.y, c.x)); e.add(two_product(a.y, c.x)); e.add(two_product(b.y, a.x)); return e.sign(); }
//============================================================================== void multiply(double a, double b, expansion& product) { product.resize(2); two_product(a, b, product[1], product[0]); }