std::vector<int> karatsuba(const std::vector<int> &a, const std::vector<int> &b) { // a = a2 * k^n + a1 // b = b2 * k^n + b1 // a * b = (a2 * b2) * k^2n + (a2 * b1 + a1 * b2) * k^n + (a1 * b1) // = (a2 * b2) * k^2n + ((a1 + a2) * (b1 + b2) - (a2 * b2) - (a1 * b1)) * k^n + (a1 * b1) // = z0 * k^2n + z2 * k^n + z1 // z0 = a2 * b2 // z1 = a1 * b1 if (a.size() < b.size()) return karatsuba(b, a); if (b.size() == 0) return std::vector<int>(); //if (a.size() <= 50) // return multiply(a, b); if (a.size() < 3) return multiply(a, b); size_t half = a.size() / 2; size_t b_half = std::min(half, size_t(b.end() - b.begin())); std::vector<int> a1(a.begin(), a.begin() + half); std::vector<int> a2(a.begin() + half, a.end()); std::vector<int> b1(b.begin(), b.begin() + b_half); std::vector<int> b2(b.begin() + b_half, b.end()); std::vector<int> z0 = karatsuba(a2, b2); std::vector<int> z1 = karatsuba(a1, b1); std::vector<int> a3 = a1; addTo(a3, a2, 0); std::vector<int> b3 = b1; addTo(b3, b2, 0); std::vector<int> z2 = karatsuba(a3, b3); subFrom(z2, z0, 0); subFrom(z2, z1, 0); std::vector<int> ret; ret.reserve(a.size() + b.size()); addTo(ret, z1, 0); addTo(ret, z2, half); addTo(ret, z0, half * 2); normalize(ret); return ret; }
void Barrel::calcPhys(Model *m) { Vec3 lob(m->lowerBound()); Vec3 upb(m->upperBound()); center_ = lob; addTo(center_, upb); scale(center_, 0.5f); subFrom(upb, lob); radius_ = std::max(upb.x, upb.y) * 0.5f; height_ = upb.z; }
virtual void prepare(CameraInfo const &cam) { Vec3 wPos(worldPos()); Vec3 back(wPos); subFrom(back, cam_->lookAt); normalize(back); cam_->back = back; Vec3 up(0, 0, 1); Vec3 right; cross(right, up, back); normalize(right); cross(up, back, right); cam_->mmat_.setRow(0, right); cam_->mmat_.setRow(1, up); cam_->mmat_.setRow(2, back); Vec3 zPos; cam_->mmat_.setTranslation(zPos); cam_->mmat_.setRow(3, zPos); subFrom(zPos, wPos); multiply(cam_->mmat_, zPos); cam_->mmat_.setTranslation(zPos); }