public bool uClosest(ref double s, ref Vect2 uvTarget, ref double dist, double tol) { Vect2 u = new Vect2(uvTarget); Vect2 du = new Vect2(); Vect2 ddu = new Vect2(); Vect2 h = new Vect2(); Vect2 e = new Vect2(); double dedx; double s0 = s; int loop = 0, max_loops = 100; while (loop++ < max_loops) { uCvt(s, ref u, ref du, ref ddu); h = u - uvTarget; dist = h.Magnitude; e[0] = s; e[1] = h.Dot(du); // error, dot product is 0 at pi/2 if (Math.Abs(e[1]) < tol) // error is less than the tolerance { uvTarget.Set(u);// return point to caller return true; } dedx = du.Norm + h.Dot(ddu); //dedx = BLAS.dot(dx, dx) + BLAS.dot(h, ddx); // calculate a new s s = e[0] - e[1] / dedx; //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; }
/// <summary> /// inserts additional points into the geo-point arrays to ensure a smooth, linear geo /// </summary> /// <param name="g">the curve object to spline</param> /// <param name="sFits">in: the initial set of geo-points s-positions, out: an interpolated set of geo-point s-pos</param> /// <param name="uFits">in: the initial set of geo-points u-positions, out: an interpolated set of geo-point u-pos</param> static void RefineGeo(MouldCurve g, ref double[] sFits, ref Vect2[] uFits) { int NumFits = sFits.Length; List<double> sPos = new List<double>(NumFits * 10); int uAdd, xAdd, sAdd; double s, dau; Vect2 uv = new Vect2();//, um = new Vect2(), up = new Vect2(); Vect2 dmu = new Vect2(), dpu = new Vect2(); Vect3 xyz = new Vect3(), dmx = new Vect3(), dpx = new Vect3(); sPos.Add(sFits[0]); for (int i = 1; i < NumFits; i++) { s = (sFits[i - 1] + sFits[i]) / 2.0; g.xVal(s, ref uv, ref xyz); dmu = uFits[i - 1] - uv; dpu = uFits[i] - uv; dau = Math.Acos(-(dmu.Dot(dpu)) / dmu.Magnitude / dpu.Magnitude); uAdd = (int)(dau / (Math.PI / 180.0) + 1); g.xVal(uFits[i - 1], ref dmx); g.xVal(uFits[i], ref dpx); dmx = dmx - xyz; dpx = dpx - xyz; dau = Math.Acos(-(dmx.Dot(dpx)) / dmx.Magnitude / dpx.Magnitude); xAdd = (int)(dau / (Math.PI / 180.0) + 1); sAdd = Math.Max(xAdd, uAdd); for (int iS = 1; iS <= sAdd; iS++) { s = BLAS.interpolate((double)iS / (double)sAdd, sFits[i], sFits[i - 1]); sPos.Add(s);//add evenly spaced s points } } uFits = new Vect2[sPos.Count]; sFits = new double[sPos.Count]; int iA = 0; foreach (double sA in sPos) { uFits[iA] = new Vect2(); g.uVal(sA, ref uFits[iA]); sFits[iA] = sA; iA++; } }
public bool SlidePoint(int index, PointF mouse, Transformer WorldToScreen) { //// get the mouse-coord x for the originally clicked fitpoint position Vect2 uv = new Vect2(); Vect3 xyz0 = new Vect3(); //xVal(FitPoints[index].UV, ref xyz0); //Point3D m0 = WorldToScreen(new Point3D(xyz0.Array)); //get the mouse-coord for the starting fixed point CurvePoint warp = FitPoints[index] as CurvePoint; warp.m_curve.xVal(warp.SCurve, ref uv, ref xyz0); Vect3 xyz = new Vect3(xyz0); Point3D x0 = WorldToScreen(new Point3D(xyz0.Array)); // small offset double delta_s = .005; // for (; xyz.Distance(xyz0) < 1e-4 && delta_s < 1; delta_s +=.05 )//ensure nonzero tangent // { warp.m_curve.xVal(warp.SCurve + delta_s, ref uv, ref xyz); // } //convert to mouse coords Point3D del = WorldToScreen(new Point3D(xyz.ToArray())); Vect2 dmds = new Vect2(del.X - x0.X, del.Y - x0.Y); //dmds -= new Vect2(x0.X, x0.Y);//get deltaxy/deltas Vect2 dm = new Vect2(mouse); dm -= new Vect2(x0.X, x0.Y);//get delta mouse //double reduce = Math.Max(dm.Magnitude, dmds.Magnitude); double dot = dmds.Dot(dm);//mouse.X * dmds.X + mouse.Y * dmds.Y; dot = dot / (dm.Magnitude * dmds.Magnitude); if (BLAS.is_equal(dot, 0, 1e-5))//dont move when perpendicular to the mouse return true; dot *= delta_s;// / dmds.Magnitude; //dot *= delta_s / reduce;// / dmds.Magnitude; // Utilities.LimitRange(-.005, ref dot, .005); warp.SCurve += dot; warp.SCurve = Utilities.LimitRange(-.2, warp.SCurve + dot, 1.2); //ReFit(); return true; }
public static Vect2 Rotate(Vect2 v, double rad) { Vect2 rot0 = new Vect2(Math.Cos(rad), -Math.Sign(rad)), rot1 = new Vect2(Math.Sign(rad), Math.Cos(rad)); return new Vect2(v.Dot(rot0), v.Dot(rot1)); }