public List<Entity> CreateCombEntity(double[] sPos, bool bNorms) { //create normal offset comb lines List<Entity> normals = new List<Entity>(); Vect2 uv = new Vect2(); Vect3 xyz = new Vect3(); Vect3 xup = new Vect3(); List<Point3D> pts = new List<Point3D>(sPos.Length*2); List<Point3D> pup = new List<Point3D>(sPos.Length); for (int i = 0; i < sPos.Length; i++) { LinearPath nor = CreateNormal(sPos[i], ref uv, ref xyz, ref xup); //xVal(sPos[i], ref uv, ref xyz, ref xup); //pts.Add(Utilities.Vect3ToPoint3D(xyz)); //Vect3 xnor = xup - xyz; //if (xnor.Magnitude > COMBMAX)//enforce maxmimum combheight //{ // xnor.Magnitude = COMBMAX; // xup = xyz + xnor; //} pts.Add(Utilities.Vect3ToPoint3D(xyz)); pup.Add(Utilities.Vect3ToPoint3D(xup)); if (bNorms) normals.Add(nor); } pts.AddRange(pup); Mesh m = SurfaceTools.GetMesh(pts.ToArray(), 2); //m.GroupIndex = 0; m.EntityData = this; normals.Add(m); return normals; }
/// <summary> /// creates a new guidecomb optionally fit to the specified points and combheights /// </summary> /// <param name="label">the name of the curve</param> /// <param name="sail">the sail the curve is on</param> /// <param name="fits">optional array of fitpoints, geodesic if 2, otherwise spline</param> /// <param name="combs">optonal array of comb heights, minimum 5</param> public GuideComb(string label, Sail sail, IFitPoint[] fits, Vect2[] combs) : base(label, sail, fits) { if (fits != null) Fit(fits); if (combs != null) FitComb(combs); }
/// <summary> /// returns CNT evenly spaced points, inferior to CreateEntity /// </summary> /// <param name="CNT">the number of points desired on the line</param> /// <returns>the array of points</returns> public Vect3[] GetPathPoints(int CNT) { double s; Vect2 uv = new Vect2(); Vect3[] d = new Vect3[CNT]; for (int i = 0; i < CNT; i++) { s = (double)i / (double)(CNT - 1); d[i] = new Vect3(); xVal(s, ref uv, ref d[i]); } return d; }
public void uCvt(double s, ref Vect2 uv, ref Vect2 du, ref Vect2 ddu) { Vect2 uv1 = new Vect2(), du1 = new Vect2(), ddu1 = new Vect2() ; m_Warps[0].uCvt(s, ref uv, ref du, ref ddu); m_Warps[1].uCvt(s, ref uv1, ref du1, ref ddu1); //interpolate u point and derivatives for (int i = 0; i < 2; i++) { uv[i] = BLAS.interpolate(m_p, uv1[i], uv[i]); du[i] = BLAS.interpolate(m_p, du1[i], du[i]); ddu[i] = BLAS.interpolate(m_p, ddu1[i], ddu[i]); } }
private double FitCurve() { if (m_Group == null || m_Group.Count < 5) return 0; Vect2 uv = new Vect2(); Vect3 xyz = new Vect3(), xprev = new Vect3(); List<IFitPoint> fit = new List<IFitPoint>(m_Group.Count); //get target point on starting yarn //yar0.xVal(m_sPos, ref uv, ref xyz); double s1 = m_sPos, d = 0; //fit.Add(new FixedPoint(uv)); double length = 0, h=0; Vect2 v; List<Vect2> combs = new List<Vect2>(m_Group.Count); for (int i = 0; i < m_Group.Count; i++) { m_Group[i].xVal(s1, ref uv, ref xprev); fit.Add(new FixedPoint(uv[0], uv[1])); //find closest point on yar1 to the target point on yar0; if (i < m_Group.Count - 1) { xyz.Set(xprev); //find the spacing to the next yarn if (!CurveTools.xClosest(m_Group[i + 1], ref s1, ref uv, ref xyz, ref d, 1e-6, true)) Logger.logger.Instance.Log("xClosest failed in DensityComb"); //throw new Exception("xClosest failed in DensityComb"); h = xyz.Distance(xprev); //store the spacing and x-distance v = new Vect2(); v[0] = length; v[1] = m_Group.InverseSpacing(h); combs.Add(v); length += h;//accumulate length } } Length = length; //convert x-distance to s-spacing for (int i = 0; i < combs.Count; i++) fit[i][0] = combs[i][0] /= length; combs.Add(new Vect2(1, m_Group.InverseSpacing(h)));//add endpoint with spacing to previous curve //fit to the intersection points SurfaceCurve.SimpleFit(this, fit.ToArray()); FitComb(combs.ToArray()); return DPI = m_Group.YarnDenier * .0254 * (m_Group.Count - 1) / length; }
public void uNor(double s, ref Vect2 uv, ref Vect2 un) { Vect2 ut = new Vect2(); Vect3 xyz = new Vect3(), dxu = new Vect3(), dxv = new Vect3(); uVec(s, ref uv, ref ut); Surface.xVec(uv, ref xyz, ref dxu, ref dxv); //covariant metric tensor components double a11 = dxu.Norm; double a12 = dxu.Dot(dxv); double a22 = dxv.Norm; double det = Math.Sqrt(a11 * a22 - a12 * a12); //contravariant normal vector components in the surface plane un[0] = (a12 * ut[0] + a22 * ut[1]) / det; un[1] = -(a11 * ut[0] + a12 * ut[1]) / det; //return unit normal u components un.Magnitude = 1; }
public void hVal(double s, ref Vect2 uv, ref double h) { uVal(s, ref uv); double[] p = new double[1]; Comb.BsVal(s, ref p); h = p[0]; }
public override Point3D GetLabelPoint3D(double s) { Vect2 u = new Vect2(); Vect3 x = new Vect3(); Vect3 c = new Vect3(); xVal(s, ref u, ref x, ref c); c -= x; //get normal vector c.Magnitude /= 2;//half height return Utilities.Vect3ToPoint3D(x + c); }
bool IsOutside(Vect2 uv) { return uv.m_vec.Min() < 0.0 || uv.m_vec.Max() > 1.0; }
void CreateSpokes() { const int NGIR = 5; const int NANG = 5; Vect2[] uv = new Vect2[2]; CurveGroup group; //for (int nLu = 0; nLu < 1; nLu++) for (int nGir = 0; nGir < NGIR; nGir++) { group = new CurveGroup(string.Format("Spokes[{0}]", nGir), this); //group = new CurveGroup(string.Format("Spokes[{0}][{1}]", nLu, nGir), S); uv[0] = new Vect2(-0.3, BLAS.interpolant(nGir, NGIR)); //uv[1-nLu] = new Vect2(1,0); for (int nAng = 0; nAng < NANG; nAng++) { uv[1] = new Vect2(1.3, BLAS.interpolant(nAng, NANG)); MouldCurve g = new MouldCurve(string.Format(group.Label + "[{0}]", nAng), this, null); g.Fit(uv[0], uv[1]); group.Add(g); } Add(group); } }
public FixedPoint(Vect2 uv) : this(0, uv) { }
public void xRad(Vect2 uv, ref Vect3 xyz, ref double k) { SurfaceTools.xRad(this, uv, ref xyz, ref k); }
private Vect2 ParseVect2Lines(IList<string> lines) { Vect2 ret = new Vect2(); string[] split = lines.Last().Trim().Split(new char[] { ':' }); ret.FromString(split.Last()); return ret; }
public void xNor(Vect2 uv, ref Vect3 xyz, ref Vect3 xnor) { Vect3 dxu = new Vect3(), dxv = new Vect3(); xVec(uv, ref xyz, ref dxu, ref dxv); xnor = dxu.Cross(dxv); xnor.Magnitude = 1; //BLAS.unitize(ref xnor); }
public bool xClosest(ref Vect2 uv, ref Vect3 xyzTarget, ref double dist, double tol) { Vect3 x = new Vect3(xyzTarget); Vect3 dxu = new Vect3(), dxv = new Vect3(); Vect3 ddxu = new Vect3(), ddxv = new Vect3(), dduv = new Vect3(); Vect3 h = new Vect3(); Vect2 c = new Vect2(); Vect2 res = new Vect2(); Vect2 a = new Vect2(), b = new Vect2(); double det, r; Vect2 d = new Vect2(); int loop = 0, max_loops = 150; while (loop++ < max_loops) { xCvt(uv, ref x, ref dxu, ref dxv, ref ddxu, ref ddxv, ref dduv); h = x - xyzTarget; //h = BLAS.subtract(x, xyzTarget); dist = h.Magnitude; //e[0] = s; c[0] = h.Dot(dxu);// BLAS.dot(h, dxu); // error, dot product is 0 at pi/2 c[1] = h.Dot(dxv);// BLAS.dot(h, dxv); // error, dot product is 0 at pi/2 if (Math.Abs(c[0]) < tol && Math.Abs(c[1]) < tol) // error is less than the tolerance { xyzTarget.Set(x);// return point to caller return true; } a[0] = dxu.Norm + h.Dot(ddxu); a[1] = b[0] = dxu.Dot(dxv) + h.Dot(dduv); b[1] = dxv.Norm + h.Dot(ddxv); //a[0] = BLAS.dot(dxu, dxu) + BLAS.dot(h, ddxu); //a[1] = BLAS.dot(dxu, dxv) + BLAS.dot(h, dduv); //b[0] = a[1]; //b[1] = BLAS.dot(dxv, dxv) + BLAS.dot(h, ddxv); det = a.Cross(b); //det = BLAS.cross2d(a, b); d[0] = c.Cross(b) / det; d[1] = a.Cross(c) / det; //d[0] = BLAS.cross2d(c, b) / det; //d[1] = BLAS.cross2d(a, c) / det; c[0] = 0.01 > Math.Abs(d[0]) ? 1 : 0.01 / Math.Abs(d[0]); c[1] = 0.01 > Math.Abs(d[1]) ? 1 : 0.01 / Math.Abs(d[1]); //enforce maximum increment r = Math.Min(c[0], c[1]); //increment uv by scaled residuals //uv = BLAS.subtract(uv, BLAS.scale(d, r)); uv = uv - d * r; //logger.write_format_line("%.5g\t%.5g\t%.5g\t%.5g\t%.5g\t", x[ox], x[oy], e[ox], e[oy], dist); } //s = s0; return false; }
public static bool CrossPoint(IMouldCurve A, IMouldCurve B, ref Vect2 uv, ref Vect3 xyz, ref Vect2 sPos, int nRez) { //h(x) = 1st curve (this) //g(x) = 2nd curve //h(x) - g(x) = 0 // //therefore: //f(x) = h(x) - g(x) //Xn+1 = Xn - f(Xn)/f'(Xn); // move in s on each curve Vect2 uv1, uv2, uvtmp, duv1, duv2; uv1 = new Vect2(); uv2 = new Vect2(); uvtmp = new Vect2(); duv1 = new Vect2(); duv2 = new Vect2(); double length = 0; //const int NUMPTS = 101; const double ALI_EPSILON = 0.1e-11; const double TOLERANCE = 0.1e-8; // check endpoints first for (int i = 0; i < 2; i++) { for (int j = 0; j < 2; j++) { B.uVec(i, ref uv1, ref duv1); // evaluate s's to get distance between A.uVec(j, ref uv2, ref duv2); // evaluate s's to get distance between length = uv1.Distance(uv2); // get distance if (length < TOLERANCE) { // intersection found A.xVal(j, ref uv, ref xyz); return true; } } } List<Vect2> uas = new List<Vect2>(nRez); List<Vect2> ubs = new List<Vect2>(nRez); List<Vect3> xas = new List<Vect3>(nRez); List<Vect3> xbs = new List<Vect3>(nRez); int ia100, ib100, iNwt; Vect2 tmpU = new Vect2(); Vect3 tmpX = new Vect3(); for (ia100 = 0; ia100 < nRez; ia100++) { A.xVal(BLAS.interpolant(ia100, nRez), ref tmpU, ref tmpX); uas.Add(new Vect2(tmpU)); xas.Add(new Vect3(tmpX)); B.xVal(BLAS.interpolant(ia100, nRez), ref tmpU, ref tmpX); ubs.Add(new Vect2(tmpU)); xbs.Add(new Vect3(tmpX)); } double dx; double dus, dMin, ta, tb, td, ad, bd, r1, r2; ta = 0; tb = 0; Vect2 du, ua, ub, da, db; du = new Vect2(); ua = new Vect2(); ub = new Vect2(); da = new Vect2(); db = new Vect2(); dMin = 1e6; // initialize minimum distance squared for (ia100 = 0; ia100 < nRez; ia100++) { for (ib100 = 0; ib100 < nRez; ib100++) { du = uas[ia100] - ubs[ib100]; // calculate (u)-distance squared between permutation of 1/100 points dus = du.Norm; dx = xas[ia100].Distance(xbs[ib100]); // track the minimum distance if (dMin > dx) { dMin = dx; ta = BLAS.interpolant(ia100, nRez); tb = BLAS.interpolant(ib100, nRez); } } } Vect3 xa, xb; xa = new Vect3(); xb = new Vect3(); bool bLimit = true; // Newton-Raphson iteration from closest 1/100 points for (iNwt = 0; iNwt < 250; iNwt++) { // enforce end point limits if (bLimit) { ta = ta > 0 ? ta : 0; ta = ta < 1 ? ta : 1; tb = tb > 0 ? tb : 0; tb = tb < 1 ? tb : 1; } A.uVec(ta, ref ua, ref da); A.xVal(ta, ref ua, ref xa); B.uVec(tb, ref ub, ref db); B.xVal(tb, ref ub, ref xb); r1 = ua[0] - ub[0]; r2 = ua[1] - ub[1]; if (Math.Abs(r1) < ALI_EPSILON && Math.Abs(r2) < ALI_EPSILON) { // enforce end point limits if (bLimit) { if (ta < 0 && Math.Pow(ta, 2) > TOLERANCE) return false; // TR 29 Jan 09 ta = 0; if (ta > 1 && Math.Pow(1.0 - ta, 2) > TOLERANCE) return false; // TR 29 Jan 09 ta = 1; if (tb < 0 && Math.Pow(tb, 2) > TOLERANCE) return false; // TR 29 Jan 09 tb = 0; if (tb > 1 && Math.Pow(1.0 - tb, 2) > TOLERANCE) return false; // TR 29 Jan 09 tb = 1; } // chop off round off errors //*(pa) = ta; //*(pb) = tb; // which may effect the (u)-coordinates A.uVec(ta, ref ua, ref da); uv = new Vect2(ua); A.xVal(uv, ref xyz); // return with updated calling parameters //us[0] = ua[0]; //us[1] = ua[1]; sPos[0] = ta; sPos[1] = tb; return true; }//if( fabs( r1 ) < ALI_EPSILON && fabs( r2 ) < ALI_EPSILON ) td = da[1] * db[0] - da[0] * db[1]; if (Math.Abs(td) < .1e-9) { break; } ad = (db[0] * r2 - db[1] * r1) / td; bd = (da[0] * r2 - da[1] * r1) / td; td = Math.Max(Math.Abs(ad), Math.Abs(bd)); // enforce maximum increment if (td > .1) { ad *= .1 / td; bd *= .1 / td; } ta -= ad; tb -= bd; }//for( iNwt=0; iNwt<250; iNwt++ ) // no_intersection terminate in error return false; }
public static bool xClosest(IMouldCurve c, ref double s, ref Vect2 uv, ref Vect3 xyzTarget, ref double dist, double tol, bool bUseGuess) { Vect3 x = new Vect3(xyzTarget); Vect3 dx = new Vect3(), ddx = new Vect3(); Vect3 h = new Vect3(); Vect2 e = new Vect2(); double deds; //try at each 18th point to ensure global solution double s0 = s; double[] sGuesses;// = new double[] { 0, .125, .25, .375, .5, .625, .75, .875, 1 }; if (bUseGuess) sGuesses = new double[] { s }; else sGuesses = new double[] { 0, .125, .25, .375, .5, .625, .75, .875, 1 }; double sCur = -1, hCur = 1e9; for (int nGuess = 0; nGuess < sGuesses.Length; nGuess++) { s = sGuesses[nGuess];//starting guess int loop = 0, max_loops = 100; while (loop++ < max_loops) { c.xCvt(s, ref uv, ref x, ref dx, ref ddx); h = x - xyzTarget; dist = h.Magnitude; e[0] = s; e[1] = h.Dot(dx); // error, dot product is 0 at pi/2 if (Math.Abs(e[1]) < tol) // error is less than the tolerance { if (dist < hCur)//store best result { sCur = s; hCur = dist; break; } //xyzTarget.Set(x);// return point to caller //return true; } deds = dx.Norm + h.Dot(ddx); deds = e[1] / deds; // calculate a new s (enforce maximum increment) deds = 0.1 > Math.Abs(deds) ? deds : 0.1 * Math.Sign(deds); s = e[0] - deds; //logger.write_format_line("%.5g\t%.5g\t%.5g\t%.5g\t%.5g\t", x[ox], x[oy], e[ox], e[oy], dist); } } if (sCur != -1) //if successful return parameters to caller { c.xVal(sCur, ref uv, ref xyzTarget); dist = hCur; s = sCur; return true; } //s = s0; return false; }
public static Point3D[] GetEvenPathPoints(IMouldCurve c, int CNT) { double s; Vect2 uv = new Vect2(); Vect3 xyz = new Vect3(); Point3D[] d = new Point3D[CNT]; for (int i = 0; i < CNT; i++) { s = (double)i / (double)(CNT - 1); c.xVal(s, ref uv, ref xyz); Utilities.Vect3ToPoint3D(ref d[i], xyz); } return d; }
public static Point3D[] GetCloudPoints(MouldCurve c) { Point3D[] pnts; Vect2 uv = new Vect2(); Vect3 xyz = new Vect3(); pnts = new Point3D[c.FitPoints.Length]; double s; for (int i = 0; i < c.FitPoints.Length; i++) { s = c[i].S; c.xVal(s, ref uv, ref xyz); Utilities.Vect3ToPoint3D(ref pnts[i], xyz); } return pnts; }
public void xVal(double s, ref Vect2 uv, ref Vect3 xyz, ref Vect3 xyzComb) { Vect3 dx = new Vect3(), xnor = new Vect3(); //get the xyz and normal vector double h =0; //get the comb height and uv pos hVal(s, ref uv, ref h); //get the surface normal and xyz Surface.xNor(uv, ref xyz, ref xnor); //scale the normal to the comb height xnor.Magnitude = h; //sum for the comb point xyzComb = xyz + xnor; }
LinearPath CreateNormal(double s, ref Vect2 uv, ref Vect3 xyz, ref Vect3 xup) { LinearPath nor = new LinearPath(2); xVal(s, ref uv, ref xyz, ref xup); nor.Vertices[0] = Utilities.Vect3ToPoint3D(xyz); Vect3 xnor = xup - xyz; if (xnor.Magnitude > COMBMAX)//enforce maxmimum combheight { xnor.Magnitude = COMBMAX; xup = xyz + xnor;//ensure you passt he values back to the caller } nor.Vertices[1] = Utilities.Vect3ToPoint3D(xup); nor.EntityData = this; ///nor.GroupIndex = 0; return nor; }
public void xRad(Vect2 uv, ref Vect3 xyz, ref double k) { Vect3 dxu = new Vect3(), dxv = new Vect3(), ddxu = new Vect3(), ddxv = new Vect3(), dduv = new Vect3(), xnor = new Vect3(); xCvt(uv, ref xyz, ref dxu, ref dxv, ref ddxu, ref ddxv, ref dduv); xNor(uv, ref xyz, ref xnor); //calculate first fundamental form double E = dxu.Norm; double F = dxu.Dot(dxv); double G = dxv.Norm; //double E = BLAS.dot(dxu, dxu); //double F = BLAS.dot(dxu, dxv); //double G = BLAS.dot(dxv, dxv); double detI = E * G - F * F; //calculate second fundamental form double e = xnor.Dot(ddxu); double f = xnor.Dot(dduv); double g = xnor.Dot(ddxv); //double e = BLAS.dot(ddxu, xnor); //double f = BLAS.dot(dduv, xnor); //double g = BLAS.dot(ddxv, xnor); double detII = e * g - f * f; k = detII / detI; }
public GuideComb() { Label = "none"; uSplines = new Vect2[]{new Vect2(0, 0)}; }
public void xVal(Vect2 uv, ref Vect3 xyz) { double[,] basisU = new double[4, 4]; double[,] basisV = new double[4, 4]; int nS, nB, nU, nV, nVal; double[,] xz = new double[m_CofCur.GetLength(0), 3]; double[] st = new double[m_CofSur.GetLength(0)]; BsCil(0, uv[1], 0, out nS, ref basisU); for (int ix = 0; ix < 3; ix++) for (nB = 0, nVal = nS; nB < 4; nB++, nVal++) for (int i = 0; i < xz.GetLength(0); i++) xz[i, ix] += m_CofCur[i, ix, nVal] * basisU[0, nB]; BsCil(0, uv[0], 1, out nVal, ref basisU); BsCil(0, uv[1], 2, out nV, ref basisV); for (nB = 0; nB < 4; nB++, nV++) for (nU = nVal, nS = 0; nS < 4; nS++, nU++) for (int i = 0; i < st.Length; i++) st[i] += m_CofSur[i, nV, nU] * basisU[0, nS] * basisV[0, nB]; for (int ix = 0; ix < 3; ix++) { xyz[ix] = xz[0, ix]; for (int i = 0; i < st.Length; i++) xyz[ix] += st[i] * xz[i + 1, ix]; } }
public void xVal(Vect2 uv, ref Vect3 xyz) { if (IsOutside(uv)) Extension.xVal(uv, ref xyz); else Mould.xVal(uv, ref xyz); }
public override List<Entity> CreateEntities(bool bFitPoints, double TolAngle, out double[] sPos) { List<Entity> e = base.CreateEntities(bFitPoints, TolAngle, out sPos); if (sPos == null) return e; e.AddRange(CreateCombEntity(sPos, false)); Vect2 u = new Vect2(); Vect3 xyz = new Vect3(), xup = new Vect3(); foreach (double s in SComb) { e.Add(CreateNormal(s, ref u, ref xyz, ref xup)); } return e; }
public FixedPoint(double s, Vect2 uv) : this(s, uv[0], uv[1]) { }
/// <summary> /// fits the 1-D comb spline to a set of (s-pos, height) pairs /// </summary> /// <param name="combs">the array of points to fit to, minimum 5</param> //public void FitComb(Vect2[] combs) //{ // double[] s = new double[combs.Length]; // double[][] h = new double[][]{ new double[combs.Length] }; // for (int i = 0; i < combs.Length; i++) // { // s[i] = combs[i][0]; // h[0][i] = combs[i][1]; // } // m_sComb = s; // Comb.Fit(s, h); //} public void FitComb(Vect2[] combs) { if (combs != null) CombPnts = combs; else combs = CombPnts; List<double[]> x = new List<double[]>(); List<double> s = new List<double>(); for (int i = 0; i < combs.Length; i++) { s.Add(combs[i][0] ); x.Add(new double[] { combs[i][1] }); } m_sComb = s.ToArray(); Comb.Fit(s, x); }
public void xVec(Vect2 uv, ref Vect3 xyz, ref Vect3 dxu, ref Vect3 dxv) { double[,] basisU = new double[4, 4]; double[,] basisV = new double[4, 4]; int nS, nB, nU, nV, nVal; double[, ,] xz = new double[m_CofCur.GetLength(0), 2, 3]; double[,] st = new double[m_CofSur.GetLength(0), 3]; BsCil(1, uv[1], 0, out nS, ref basisU); for (int ix = 0; ix < 3; ix++) for (nB = 0, nVal = nS; nB < 4; nB++, nVal++) for (int i = 0; i < xz.GetLength(0); i++) { xz[i, 0, ix] += m_CofCur[i, ix, nVal] * basisU[0, nB]; xz[i, 1, ix] += m_CofCur[i, ix, nVal] * basisU[1, nB]; } BsCil(1, uv[0], 1, out nVal, ref basisU); BsCil(1, uv[1], 2, out nV, ref basisV); for (nB = 0; nB < 4; nB++, nV++) for (nU = nVal, nS = 0; nS < 4; nS++, nU++) for (int i = 0; i < st.GetLength(0); i++) { st[i, 0] += m_CofSur[i, nV, nU] * basisU[0, nS] * basisV[0, nB]; st[i, 1] += m_CofSur[i, nV, nU] * basisU[1, nS] * basisV[0, nB]; st[i, 2] += m_CofSur[i, nV, nU] * basisU[0, nS] * basisV[1, nB]; } for (int ix = 0; ix < 3; ix++) { xyz[ix] = xz[0, 0, ix]; dxu[ix] = 0; dxv[ix] = xz[0, 1, ix]; for (int i = 0; i < st.GetLength(0); i++) { xyz[ix] += st[i, 0] * xz[i + 1, 0, ix]; dxu[ix] += st[i, 1] * xz[i + 1, 0, ix]; dxv[ix] += st[i, 2] * xz[i + 1, 0, ix]; dxv[ix] += st[i, 0] * xz[i + 1, 1, ix]; } } }
public void xVec(Vect2 uv, ref Vect3 xyz, ref Vect3 dxu, ref Vect3 dxv) { if (IsOutside(uv)) Extension.xVec(uv, ref xyz, ref dxu, ref dxv); else Mould.xVec(uv, ref xyz, ref dxu, ref dxv); }