/// <summary> /// Deform snake in the given external force field /// /// [x,y] = snakedeform(x,y,alpha,beta,gamma,kappa,fx,fy,ITER) /// /// </summary> /// <param name="x">轮廓-X</param> /// <param name="y">轮廓-Y</param> /// <param name="alpha">elasticity parameter</param> /// <param name="beta">rigidity parameter</param> /// <param name="gamma">viscosity parameter</param> /// <param name="kappa">external force weight</param> /// <param name="fx">external force field (x)</param> /// <param name="fy">external force field (y)</param> /// <param name="ITER">iteration</param> public void SnakeDeform(ref NcvVector x, ref NcvVector y, double alpha, double beta, double gamma, double kappa, double[] fx, double[] fy, int ITER) { int n = x.n; NcvVector vecAlpha = alpha * NcvVector.Ones(n); NcvVector vecBeta = beta * NcvVector.Ones(n); // produce the five diagnal vectors NcvVector alpham1 = NcvVector.cat(vecAlpha.sub(1, n - 1), vecAlpha.sub(0, 1)); NcvVector alphap1 = NcvVector.cat(vecAlpha.sub(n - 1, 1), vecAlpha.sub(0, n - 1)); NcvVector betam1 = NcvVector.cat(vecBeta.sub(1, n - 1), vecBeta.sub(0, 1)); NcvVector betap1 = NcvVector.cat(vecBeta.sub(n - 1, 1), vecBeta.sub(0, n - 1)); NcvVector a = betam1; NcvVector b = -vecAlpha - 2 * vecBeta - 2 * betam1; NcvVector c = vecAlpha + alphap1 + betam1 + 4 * vecBeta + betap1; NcvVector d = -alphap1 - 2 * vecBeta - 2 * betap1; NcvVector e = betap1; // generate the parameters matrix NcvMatrix A = NcvMatrix.diag(a.sub(0, n - 2), -2) + NcvMatrix.diag(a.sub(n - 2, 2), n - 2); A = A + NcvMatrix.diag(b.sub(0, n - 1), -1) + NcvMatrix.diag(b.sub(n - 1, 1), n - 1); A = A + NcvMatrix.diag(c); A = A + NcvMatrix.diag(d.sub(0, n - 1), 1) + NcvMatrix.diag(d.sub(n - 1, 1), -(n - 1)); A = A + NcvMatrix.diag(e.sub(0, n - 2), 2) + NcvMatrix.diag(e.sub(n - 2, 2), -(n - 2)); //Logger.Info("A=" + A.ToString()); NcvMatrix invAI = NcvMatrix.inv(A + gamma * NcvMatrix.diag(NcvVector.Ones(n))); //Logger.Info("invAI=" + invAI.ToString()); //Logger.Info("fx=" + new Matrix(fx, m_Cols, m_Rows).ToString()); //Logger.Info("fy=" + new Matrix(fy, m_Cols, m_Rows).ToString()); for (int count = 0; count < ITER; count++) { NcvVector vfx = NcvVector.interp2(fx, m_Cols, m_Rows, x, y, "*linear"); NcvVector vfy = NcvVector.interp2(fy, m_Cols, m_Rows, x, y, "*linear"); //Logger.Info("vfx=" + vfx.ToString()); //Logger.Info("vfy=" + vfy.ToString()); // deform snake x = invAI * (gamma * x + kappa * vfx); y = invAI * (gamma * y + kappa * vfy); //Logger.Info("x=" + x.ToString()); //Logger.Info("y=" + y.ToString()); } }
/// <summary> /// Deform snake in the given external force field with pressure force added /// </summary> /// <param name="x">轮廓-X</param> /// <param name="y">轮廓-Y</param> /// <param name="alpha">elasticity parameter</param> /// <param name="beta">rigidity parameter</param> /// <param name="gamma">viscosity parameter</param> /// <param name="kappa">external force weight</param> /// <param name="kappap">pressure force weight</param> /// <param name="fx">external force field (x)</param> /// <param name="fy">external force field (y)</param> /// <param name="ITER"></param> public void SnakeDeform2(ref NcvVector x, ref NcvVector y, double alpha, double beta, double gamma, double kappa, double kappap, double[] fx, double[] fy, int ITER) { int n = x.n; NcvVector vecAlpha = alpha * NcvVector.Ones(n); NcvVector vecBeta = beta * NcvVector.Ones(n); // produce the five diagnal vectors NcvVector alpham1 = NcvVector.cat(vecAlpha.sub(1, n - 1), vecAlpha.sub(0, 1)); NcvVector alphap1 = NcvVector.cat(vecAlpha.sub(n - 1, 1), vecAlpha.sub(0, n - 1)); NcvVector betam1 = NcvVector.cat(vecBeta.sub(1, n - 1), vecBeta.sub(0, 1)); NcvVector betap1 = NcvVector.cat(vecBeta.sub(n - 1, 1), vecBeta.sub(0, n - 1)); NcvVector a = betam1; NcvVector b = -vecAlpha - 2 * vecBeta - 2 * betam1; NcvVector c = vecAlpha + alphap1 + betam1 + 4 * vecBeta + betap1; NcvVector d = -alphap1 - 2 * vecBeta - 2 * betap1; NcvVector e = betap1; // generate the parameters matrix NcvMatrix A = NcvMatrix.diag(a.sub(0, n - 2), -2) + NcvMatrix.diag(a.sub(n - 2, 2), n - 2); A = A + NcvMatrix.diag(b.sub(0, n - 1), -1) + NcvMatrix.diag(b.sub(n - 1, 1), n - 1); A = A + NcvMatrix.diag(c); A = A + NcvMatrix.diag(d.sub(0, n - 1), 1) + NcvMatrix.diag(d.sub(n - 1, 1), -(n - 1)); A = A + NcvMatrix.diag(e.sub(0, n - 2), 2) + NcvMatrix.diag(e.sub(n - 2, 2), -(n - 2)); NcvMatrix invAI = NcvMatrix.inv(A + gamma * NcvMatrix.diag(NcvVector.Ones(n))); for (int count = 0; count < ITER; count++) { NcvVector vfx = NcvVector.interp2(fx, m_Cols, m_Rows, x, y, "*linear"); NcvVector vfy = NcvVector.interp2(fy, m_Cols, m_Rows, x, y, "*linear"); // adding the pressure force NcvVector xp = NcvVector.cat(x.sub(1, n - 1), x.sub(0, 1)); NcvVector yp = NcvVector.cat(y.sub(1, n - 1), y.sub(0, 1)); NcvVector xm = NcvVector.cat(x.sub(n - 1, 1), x.sub(0, n - 1)); NcvVector ym = NcvVector.cat(y.sub(n - 1, 1), y.sub(0, n - 1)); NcvVector qx = xp - xm; NcvVector qy = yp - ym; NcvVector pmag = NcvVector.Sqrt(NcvVector.DotProduct(qx, qx) + NcvVector.DotProduct(qy, qy)); NcvVector px = NcvVector.DotDivide(qy, pmag); NcvVector py = NcvVector.DotDivide(-qx, pmag); // deform snake x = invAI * (gamma * x + kappa * vfx + kappap * px); y = invAI * (gamma * y + kappa * vfy + kappap * py); } }