Esempio n. 1
0
        /// <summary>
        /// Overrides <see cref="CADability.GeoObject.ISurfaceImpl.UDirection (GeoPoint2D)"/>
        /// </summary>
        /// <param name="uv"></param>
        /// <returns></returns>
        public override GeoVector UDirection(GeoPoint2D uv)
        {
            /* Formula from maxima, syntax:
             * load(vect);
             * f(x,y) := depends([f1,f2,f3],[x,y]);
             * g(x,y) := f(x,y)+c*(diff(f(x,y),x)~diff(f(x,y),y))/((diff(f(x,y),x)~diff(f(x,y),y)).(diff(f(x,y),x)~diff(f(x,y),y)))^0.5;
             * Note: "." means scalarproduct, "~" is crossprodukt, note that x~y~z is x~(y~z) not (x~y)~z
             * diff(g(x,y),x);
             * stringout("file",%);
             * With appropriate substitution you get the formula below.
             */

            GeoVector du, dv, duu, dvv, duv;
            GeoPoint  loc;

            baseSurface.Derivation2At(uv, out loc, out du, out dv, out duu, out dvv, out duv);
            GeoVector crop;

            //CndHlp3D.GeoVector3D dbg = Helper.UDirection(uv.ToCndHlp());
            crop = (dv ^ (du ^ dv));
            //GeoVector dbg1 = -0.5 * offset * (duu * crop + (du * (dv ^ ((duu ^ dv) + (du ^ duv)))) + (du * (duv ^ (du ^ dv)))) / System.Math.Pow((du * crop), 1.5) * (du ^ dv);
            //GeoVector dgb2 = (offset / System.Math.Pow((du * crop), 0.5)) * ((duu ^ dv) + (du ^ duv));
            //GeoVector dgb4 = -0.5 * offset * (duu * crop + (du * (dv ^ ((duu ^ dv) + (du ^ duv)))) + (du * (duv ^ (du ^ dv)))) / System.Math.Pow((du * crop), 1.5) * (du ^ dv) + offset * ((duu ^ dv) + (du ^ duv)) / System.Math.Pow((du * crop), 0.5) + du;
            return(-0.5 * offset * (duu * crop + (du * (dv ^ ((duu ^ dv) + (du ^ duv)))) + (du * (duv ^ (du ^ dv)))) / System.Math.Pow((du * crop), 1.5) * (du ^ dv) + offset * ((duu ^ dv) + (du ^ duv)) / System.Math.Pow((du * crop), 0.5) + du);
        }
Esempio n. 2
0
 /// <summary>
 /// Find the (u,v)-position for the provided point on a surface. Using the NewtonMinimizer from MathNet. Faster than LevenbergMarquardtMinimizer. Surfaces need second derivatives.
 /// </summary>
 /// <param name="surface"></param>
 /// <param name="p3d"></param>
 /// <param name="res"></param>
 /// <param name="mindist"></param>
 /// <returns></returns>
 public static bool PositionOfMN(ISurface surface, GeoPoint p3d, ref GeoPoint2D res, out double mindist)
 {
     NewtonMinimizer    nm  = new NewtonMinimizer(1e-12, 30);
     IObjectiveFunction iof = ObjectiveFunction.GradientHessian(
         new Func <Vector <double>, Tuple <double, Vector <double>, Matrix <double> > >(delegate(Vector <double> vd)
     {
         GeoPoint2D uv = new GeoPoint2D(vd[0], vd[1]);
         surface.Derivation2At(uv, out GeoPoint loc, out GeoVector du, out GeoVector dv, out GeoVector duu, out GeoVector dvv, out GeoVector duv);
         double val = (p3d.x - loc.x) * (p3d.x - loc.x) + (p3d.y - loc.y) * (p3d.y - loc.y) + (p3d.z - loc.z) * (p3d.z - loc.z);
         double u   = -2 * du.x * (p3d.x - loc.x) - 2 * du.y * (p3d.y - loc.y) - 2 * du.z * (p3d.z - loc.z);
         double v   = -2 * dv.x * (p3d.x - loc.x) - 2 * dv.y * (p3d.y - loc.y) - 2 * dv.z * (p3d.z - loc.z);
         Vector <double> gradient = new DenseVector(new double[] { u, v });
         Matrix <double> hessian  = new DenseMatrix(2, 2);
         hessian[0, 0]            = -2 * duu.z * (p3d.z - loc.z) - 2 * duu.y * (p3d.y - loc.y) - 2 * duu.x * (p3d.x - loc.x) + 2 * du.z * du.z + 2 * du.y * du.y + 2 * du.x * du.x;
         hessian[1, 1]            = -2 * dvv.z * (p3d.z - loc.z) - 2 * dvv.y * (p3d.y - loc.y) - 2 * dvv.x * (p3d.x - loc.x) + 2 * dv.z * dv.z + 2 * dv.y * dv.y + 2 * dv.x * dv.x;
         hessian[0, 1]            = hessian[1, 0] = -2 * duv.z * (p3d.z - loc.z) - 2 * duv.y * (p3d.y - loc.y) - 2 * duv.x * (p3d.x - loc.x) + 2 * du.z * dv.z + 2 * du.y * dv.y + 2 * du.x * dv.x;
         return(new Tuple <double, Vector <double>, Matrix <double> >(val, gradient, hessian));
     }));
Esempio n. 3
0
        public override void Derivation2At(GeoPoint2D uv, out GeoPoint location, out GeoVector du, out GeoVector dv, out GeoVector duu, out GeoVector dvv, out GeoVector duv)
        {
            periodicSurface.Derivation2At(toPeriodic(uv), out GeoPoint ploc, out GeoVector pdu, out GeoVector pdv, out GeoVector pduu, out GeoVector pdvv, out GeoVector pduv);
            location = ploc;
            // toPeriodic
            // s := m00*atan2(v, u)+m01*sqrt(u^2 + v^2)+m02;
            // t := m10*atan2(v, u)+m11*sqrt(u^2 + v^2)+m12;
            // ds/du: (m01*u)/sqrt(v^2+u^2)-(m00*v)/(v^2+u^2)
            // ds/dv: (m01*v)/sqrt(v^2+u^2)+(m00*u)/(v^2+u^2)
            // dt/du: (m11*u)/sqrt(v^2+u^2)-(m10*v)/(v^2+u^2)
            // dt/dv: (m11*v)/sqrt(v^2+u^2)+(m10*u)/(v^2+u^2)
            // g(u,v): f(m00*atan2(v, u)+m01*sqrt(u^2 + v^2)+m02,m10*atan2(v, u)+m11*sqrt(u^2 + v^2)+m12) == f(s,t)
            // dg(u,v)/du: ds/du * df/ds + dt/du * df/dt;
            // dg(u,v)/dudu: ds/dudu * df/ds + ds/du* d(df/ds)/du    +    dt/dudu * df/dt + dt/du * d(df/dt)/du
            // == ds/dudu * df/ds + ds/du* (ds/du*(df/dsds) + dt/du*(df/dsdt)
            //  + dt/dudu * df/dt + dt/du * (ds/du*df/dtds) + dt/du*(df/dtdt))
            double l  = uv.x * uv.x + uv.y * uv.y;
            double sl = Math.Sqrt(l);

            double dsdu   = toPeriodicBounds[0, 1] * uv.x / sl - toPeriodicBounds[0, 0] * uv.y / l;
            double dsdv   = toPeriodicBounds[0, 1] * uv.y / sl + toPeriodicBounds[0, 0] * uv.x / l;
            double dsdudu = toPeriodicBounds[0, 1] / sl - (toPeriodicBounds[0, 1] * uv.x * uv.x) / exp32(l) + (2 * toPeriodicBounds[0, 0] * uv.x * uv.y) / (l * l);
            double dsdvdv = toPeriodicBounds[0, 1] / sl - (toPeriodicBounds[0, 1] * uv.y * uv.y) / exp32(l) + (2 * toPeriodicBounds[0, 0] * uv.x * uv.y) / (l * l);
            double dsdudv = -toPeriodicBounds[0, 0] / (l) - (toPeriodicBounds[0, 1] * uv.x * uv.y) / exp32(l) + (2 * toPeriodicBounds[0, 0] * uv.y * uv.y) / (l * l);

            double dtdu   = toPeriodicBounds[1, 1] * uv.x / sl - toPeriodicBounds[1, 0] * uv.y / l;
            double dtdv   = toPeriodicBounds[1, 1] * uv.y / sl + toPeriodicBounds[1, 0] * uv.x / l;
            double dtdudu = toPeriodicBounds[1, 1] / sl - (toPeriodicBounds[1, 1] * uv.x * uv.x) / exp32(l) + (2 * toPeriodicBounds[1, 0] * uv.x * uv.y) / (l * l);
            double dtdvdv = toPeriodicBounds[1, 1] / sl - (toPeriodicBounds[1, 1] * uv.y * uv.y) / exp32(l) + (2 * toPeriodicBounds[1, 0] * uv.x * uv.y) / (l * l);
            double dtdudv = -toPeriodicBounds[1, 0] / (l) - (toPeriodicBounds[1, 1] * uv.x * uv.y) / exp32(l) + (2 * toPeriodicBounds[1, 0] * uv.y * uv.y) / (l * l);

            du  = dsdu * pdu + dtdu * pdv;
            dv  = dsdv * pdu + dtdv * pdv;
            duu = dsdudu * pdu + dsdu * (dsdu * pduu + dtdu * pduv) + dtdudu * pdv + dtdu * (dsdu * pduv + dtdu * pdvv);
            dvv = dsdvdv * pdu + dsdv * (dsdv * pduu + dtdv * pduv) + dtdvdv * pdv + dtdv * (dsdv * pduv + dtdv * pdvv);
            duv = dsdudv * pdu + dsdu * (dsdv * pduu + dtdv * pduv) + dtdudv * pdv + dtdu * (dsdu * pduv + dtdu * pdvv);
        }
Esempio n. 4
0
 public void Derivation2At(GeoPoint2D uv, out GeoPoint location, out GeoVector du, out GeoVector dv, out GeoVector duu, out GeoVector dvv, out GeoVector duv)
 {
     original.Derivation2At(unscale * uv, out location, out du, out dv, out duu, out dvv, out duv); // du und dv noch skalieren?
 }