dualquat<value_t> DIB (const std::vector<dualquat<value_t>>& quats, const std::vector<value_t>& weights) { assert(quats.size() == weights.size()); dualquat<value_t> b = DLB(quats, weights); auto logmean = [&]() { dualquat<value_t> avg(0); for (size_t i = 0; i < quats.size(); i++) avg += ((b.C())*quats[i]).log()*weights[i]; return avg; }; auto x = logmean(); auto norm = x.dot(x); for(;;){ b *= x.numexp(); auto xnew = logmean(); const auto newnorm = xnew.dot(xnew); if(norm < newnorm || newnorm < EPS(value_t)) break; else { x = xnew; norm = newnorm; } } // std::cout << "precision: " << norm << std::endl; return b; }
void GLPatch::paramSurfaces(BezierPatch G, float res[]) { glm::mat4x4 M(glm::vec4(-1.0f, 3.0f, -3.0f, 1.0f), glm::vec4( 3.0f, -6.0f, 3.0f, 0.0f), glm::vec4(-3.0f, 3.0f, 0.0f, 0.0f), glm::vec4( 1.0f, 0.0f, 0.0f, 0.0f)); for (float s = 0.f; s < 5.f; s += 1.f){ for (float t = 0.f; t < 5.f; t += 1.f){ glm::vec4 S(s * s * s, s * s, s, 1.0f); glm::vec4 T(t * t * t, t * t, t, 1.0f); glm::mat4x4 DLB(glm::vec4(8.0f, 0.0f, 0.0f, 0.0f), glm::vec4(4.0f, 4.0f, 0.0f, 0.0f), glm::vec4(2.0f, 4.0f, 2.0f, 0.0f), glm::vec4(1.0f, 3.0f, 3.0f, 1.0f)); DLB /= 8.0f; glm::mat4x4 DRB(glm::vec4(1.0f, 3.0f, 3.0f, 1.0f), glm::vec4(0.0f, 2.0f, 4.0f, 2.0f), glm::vec4(0.0f, 0.0f, 4.0f, 4.0f), glm::vec4(0.0f, 0.0f, 0.0f, 8.0f)); DRB /= 8.0f; BezierPatch G11 = glm::transpose(DLB) * G * DLB; addtolist(G11, res, 0); BezierPatch G12 = glm::transpose(DRB) * G * DLB; addtolist(G11, res, 47); BezierPatch G21 = glm::transpose(DLB) * G * DRB; addtolist(G11, res, 95); BezierPatch G22 = glm::transpose(DRB) * G * DRB; addtolist(G11, res, 143); } } }