double Path::RaffineTk (Geom::Point pt, Geom::Point p0, Geom::Point p1, Geom::Point p2, Geom::Point p3, double it) { // Refinement of the tk values. // Just one iteration of Newtow Raphson, given that we're approaching the curve anyway. // [fr: vu que de toute facon la courbe est approchC)e] double const Ax = pt[Geom::X] - p0[Geom::X] * N03(it) - p1[Geom::X] * N13(it) - p2[Geom::X] * N23(it) - p3[Geom::X] * N33(it); double const Bx = (p1[Geom::X] - p0[Geom::X]) * N02(it) + (p2[Geom::X] - p1[Geom::X]) * N12(it) + (p3[Geom::X] - p2[Geom::X]) * N22(it); double const Cx = (p0[Geom::X] - 2 * p1[Geom::X] + p2[Geom::X]) * N01(it) + (p3[Geom::X] - 2 * p2[Geom::X] + p1[Geom::X]) * N11(it); double const Ay = pt[Geom::Y] - p0[Geom::Y] * N03(it) - p1[Geom::Y] * N13(it) - p2[Geom::Y] * N23(it) - p3[Geom::Y] * N33(it); double const By = (p1[Geom::Y] - p0[Geom::Y]) * N02(it) + (p2[Geom::Y] - p1[Geom::Y]) * N12(it) + (p3[Geom::Y] - p2[Geom::Y]) * N22(it); double const Cy = (p0[Geom::Y] - 2 * p1[Geom::Y] + p2[Geom::Y]) * N01(it) + (p3[Geom::Y] - 2 * p2[Geom::Y] + p1[Geom::Y]) * N11(it); double const dF = -6 * (Ax * Bx + Ay * By); double const ddF = 18 * (Bx * Bx + By * By) - 12 * (Ax * Cx + Ay * Cy); if (fabs (ddF) > 0.0000001) { return it - dF / ddF; } return it; }
void dynamics_mul::compute_intensity_force(){ HMesh::HalfEdgeAttributeVector<int> touched(s_dsc->get_no_halfedges(), 0); for (auto eit = s_dsc->halfedges_begin(); eit != s_dsc->halfedges_end(); eit++) { if(s_dsc->is_interface(*eit) and !touched[*eit]){ auto hew = s_dsc->walker(*eit); double c0 = mean_inten_[s_dsc->get_label(hew.face())]; double c1 = mean_inten_[s_dsc->get_label(hew.opp().face())]; // Loop on the edge auto p0 = s_dsc->get_pos(hew.opp().vertex()); auto p1 = s_dsc->get_pos(hew.vertex()); Vec2 L01 = p1 - p0; L01.normalize(); Vec2 N01(L01[1], -L01[0]); // Outward pointing normal int length = (int)(p1 - p0).length(); double f0 = 0.0, f1 = 0.0; Vec2 fg0(0.0), fg1(0.0); for (int i = 0; i <= length; i++) { auto p = p0 + (p1 - p0)*(double(i)/(double)length); double I = s_img->get_intensity(p[0], p[1]); // Normalize force int normalizedF = 1; double f ; switch (normalizedF) { case 1: f = ( (c0-c1)*(2*I - c0 - c1)) / ((c0-c1)*(c0-c1)); break; case 2: f = ( (c0-c1)*(2*I - c0 - c1)) / std::abs((c0 - c1)); break; case 3: f = (c0-c1)*(2*I - c0 - c1); break; default: f = 0.0; break; } Vec2 fu = N01*(c0-c1)*(2*I - c0 - c1); // Image gradient force int lengthM = 10; Vec2 gm(0.0); double max_grad = 0; for (int l = 0; l < lengthM; l++) { Vec2 curPt = p + fu*(l/(double)(lengthM)); Vec2 gg = s_img->grad((int)curPt[0], (int)curPt[1]); if (max_grad < gg.length()) { max_grad = gg.length(); gm = gg*(lengthM - l)/(double)lengthM; } } Vec2 fg = gm*(2*I - c0 - c1); Vec2 fv = (fu + fg)/((c0-c1)*(c0-c1)); fg0 += fv*(p-p1).length() / (double)length; fg1 += fv*(p-p0).length() / (double)length; // Barry Centric coordinate f0 += f*(p-p1).length() / (double)length; f1 += f*(p-p0).length() / (double)length; // Image gradient force // Vec2 fg = s_img->grad((int)p[0], (int)p[1]) * (2*I - c0 - c1) / ((c0-c1)*(c0-c1)); // fg0 += fg*(p-p1).length() / (double)length; // fg1 += fg*(p-p0).length() / (double)length; } // Set force Vec2 f_x0 = fg0; // N01*f0; Vec2 f_x1 = fg1; // N01*f1; s_dsc->add_node_external_force(hew.opp().vertex(), f_x0*g_param.beta); s_dsc->add_node_external_force(hew.vertex(), f_x1*g_param.beta); // Avoid retouch the edge touched[*eit] = 1; touched[hew.opp().halfedge()] = 1; } } }