Пример #1
0
        /// <summary>
        /// Overrides <see cref="CADability.GeoObject.ISurfaceImpl.UDirection (GeoPoint2D)"/>
        /// </summary>
        /// <param name="uv"></param>
        /// <returns></returns>
        public override GeoVector UDirection(GeoPoint2D uv)
        {
            GeoVector v1 = firstCurve.DirectionAt(uv.x);
            GeoVector v2 = secondCurve.DirectionAt(uv.x);

            return((1.0 - uv.y) * v1 + uv.y * v2);
        }
Пример #2
0
        /// <summary>
        /// Overrides <see cref="CADability.GeoObject.ISurfaceImpl.UDirection (GeoPoint2D)"/>
        /// </summary>
        /// <param name="uv"></param>
        /// <returns></returns>
        public override GeoVector UDirection(GeoPoint2D uv)
        {
            double pos = (uv.x - curveStartParameter) / (curveEndParameter - curveStartParameter);

            // ausgehend davon, dass DirectionAt den Vektor gemäß änderung um 1 liefert
            // das ist oft nicht der Fall. Man muss also PointAtParam und DirectionAtParam implementieren
            return((curveEndParameter - curveStartParameter) * basisCurve.DirectionAt(pos));
        }
Пример #3
0
            public override GeoVector DirectionAt(double Position)
            {
                double    p  = startParam + (endParam - startParam) * Position;
                GeoVector d1 = firstCurve.DirectionAt(p);
                GeoVector d2 = secondCurve.DirectionAt(p);

                return((endParam - startParam) * ((1.0 - v) * d1 + v * d2));
            }
Пример #4
0
        internal static bool NewtonMinDist(ICurve curve1, ref double par1, ICurve curve2, ref double par2)
        {   // find the points on both curves where the connecting line of the two curves is perpendicular on both
            int numoutside = 0;

            while (numoutside < 3)
            {
                GeoPoint  s1 = curve1.PointAt(par1);
                GeoVector d1 = curve1.DirectionAt(par1);
                GeoPoint  s2 = curve2.PointAt(par2);
                GeoVector d2 = curve2.DirectionAt(par2);
                double    d  = Geometry.DistLL(s1, d1, s2, d2, out double pp1, out double pp2);
                par1 += pp1;
                par2 += pp2;
                if (curve1.IsClosed)
                {
                    if (par1 < 0)
                    {
                        par1 += 1;
                    }
                    if (par1 > 1)
                    {
                        par1 -= 1;
                    }
                }
                if (curve2.IsClosed)
                {
                    if (par2 < 0)
                    {
                        par2 += 1;
                    }
                    if (par2 > 1)
                    {
                        par2 -= 1;
                    }
                }
                if (par1 < -1e-6 || par1 > 1 + 1e-6 || par2 < -1e-6 || par2 > 1 + 1e-6)
                {
                    ++numoutside;
                }
                if (Math.Abs(pp1) < 1e-6 && Math.Abs(pp2) < 1e-6)
                {
                    return(true);
                }
            }
            return(false);
        }
Пример #5
0
        /// <summary>
        /// Returns true if curve1 and curve2 are overlapping curves. The overlapping intervalls for both curves are
        /// returned in <paramref name="from1"/>, <paramref name="to1"/>, <paramref name="from2"/> and <paramref name="to2"/>.
        /// </summary>
        /// <param name="curve1">First curve</param>
        /// <param name="curve2">Second curve</param>
        /// <param name="precision">Required precision</param>
        /// <param name="from1">Starting parameter for first curve</param>
        /// <param name="to1">Ending parameter for first curve</param>
        /// <param name="from2">Starting parameter for second curve</param>
        /// <param name="to2">Ending parameter for second curve</param>
        /// <returns></returns>
        public static bool Overlapping(ICurve curve1, ICurve curve2, double precision, out double from1, out double to1, out double from2, out double to2)
        {
            from1 = to1 = from2 = to2 = 0.0; // für den fals Fall
            List <double> c1 = new List <double>();
            List <double> c2 = new List <double>();
            double        u  = curve1.PositionOf(curve2.StartPoint);
            GeoPoint      p  = curve1.PointAt(u);

            if (u >= 0.0 && u <= 1.0 && (p | curve2.StartPoint) < precision)
            {
                c1.Add(u);
                c2.Add(0.0);
            }
            u = curve1.PositionOf(curve2.EndPoint);
            p = curve1.PointAt(u);
            if (u >= 0.0 && u <= 1.0 && (p | curve2.EndPoint) < precision)
            {
                c1.Add(u);
                c2.Add(1.0);
            }
            u = curve2.PositionOf(curve1.StartPoint);
            p = curve2.PointAt(u);
            if (u >= 0.0 && u <= 1.0 && (p | curve1.StartPoint) < precision)
            {
                c2.Add(u);
                c1.Add(0.0);
            }
            u = curve2.PositionOf(curve1.EndPoint);
            p = curve2.PointAt(u);
            if (u >= 0.0 && u <= 1.0 && (p | curve1.EndPoint) < precision)
            {
                c2.Add(u);
                c1.Add(1.0);
            }
            if (c1.Count < 2)
            {
                return(false);
            }
            if (c1.Count > 2)
            {     // eine Kurve liegt ganz in der anderen und Start oder Endpunkt sind gleich (oder identische Kurven)
                if (c1.Count == 4)
                { // nichts tun, die ersten beiden sind schon OK
                }
                else
                {     // also 3 Punkte, einer davon ist doppelt
                    if (c1[1] == 0.0 && c1[2] == 1.0)
                    { // die beiden letzten Abfragen haben gegriffen, den 1. Punkt wegwerfen
                        c1.RemoveAt(0);
                        c2.RemoveAt(0);
                    }
                    // ansonsten haben die beiden ersten Abfragen geegriffen, der 3. Punkt wird nicht verwednet
                }
            }
            // Dir Richtungen müssen gleich sein, jedoch ist das schwer mit precision in Einklang zu bringen
            // Hier jetzt die notwendigen Zwischenpunkte betrachten
            // bool intermediatePointChecked = false;
            double[] sp   = curve1.GetSavePositions();
            double   umin = Math.Min(c1[0], c1[1]);
            double   umax = Math.Max(c1[0], c1[1]);

            for (int i = 0; i < sp.Length; i++)
            {
                if (sp[i] > umin && sp[i] < umax)
                {
                    GeoPoint p1 = curve1.PointAt(sp[i]);
                    GeoPoint p2 = curve2.PointAt(curve2.PositionOf(p1));
                    if ((p1 | p2) > precision)
                    {
                        return(false);
                    }
                    //intermediatePointChecked = true;
                }
            }
            if (umax - umin < 1e-6)
            {
                // Sonderfall: nur Start/Endpunkte sind identisch. Es sollte nur dann true geliefert werden
                // wenn die Kurven dort tangential sind
                if (!Precision.SameDirection(curve1.DirectionAt(c1[0]), curve2.DirectionAt(c2[0]), false))
                {
                    return(false);
                }
                if (!Precision.SameDirection(curve1.DirectionAt(c1[1]), curve2.DirectionAt(c2[1]), false))
                {
                    return(false);
                }
            }
            sp   = curve2.GetSavePositions();
            umin = Math.Min(c2[0], c2[1]);
            umax = Math.Max(c2[0], c2[1]);
            for (int i = 0; i < sp.Length; i++)
            {
                if (sp[i] > umin && sp[i] < umax)
                {
                    GeoPoint p1 = curve2.PointAt(sp[i]);
                    GeoPoint p2 = curve1.PointAt(curve1.PositionOf(p1));
                    if ((p1 | p2) > precision)
                    {
                        return(false);
                    }
                    //intermediatePointChecked = true;
                }
            }
            {   // die mittelpunkte im Parameterbereich müssen auch im anderen Parameterbereich liegen
                GeoPoint p1  = curve1.PointAt((c1[0] + c1[1]) / 2.0);
                double   pos = curve2.PositionOf(p1);
                if (pos < 0.0 || pos > 1.0)
                {
                    return(false);                        // eigentlich sollte die strengere Bedingung gelten: im Intervall c2[0]..c2[1].
                }
                GeoPoint p2 = curve2.PointAt((c2[0] + c2[1]) / 2.0);
                pos = curve1.PositionOf(p2);
                if (pos < 0.0 || pos > 1.0)
                {
                    return(false);                        // eigentlich sollte die strengere Bedingung gelten: im Intervall c2[0]..c2[1].
                }
                // if ((p1 | p2) > precision) return false;
            }
            from1 = c1[0];
            to1   = c1[1];
            from2 = c2[0];
            to2   = c2[1];
            return(true);
        }
Пример #6
0
        private void selectDir()
        {
            GeoVector dirCurveMod = new GeoVector(0.0, 1.0, 1.0);

            switch (dirPointSelect)
            { // Startpunkt|Automatik|Endpunkt|Mittelpunkt|freier Punkt
            default:
                dirCurveMod = dirCurve.StartDirection;
                break;

            case 0:     // Startpunkt
                dirCurveMod = dirCurve.StartDirection;
                break;

            case 1:     // Automatik
                if (dirCurve.PositionOf(objectPoint) > 0.66)
                {
                    dirCurveMod = dirCurve.EndDirection;
                }
                else
                if (dirCurve.PositionOf(objectPoint) > 0.33)
                {
                    dirCurveMod = dirCurve.DirectionAt(0.5);
                }
                else
                {
                    dirCurveMod = dirCurve.StartDirection;
                }
                break;

            case 2:     // Endpunkt
                dirCurveMod = dirCurve.EndDirection;
                break;

            case 3:     // Mittelpunkt
                dirCurveMod = dirCurve.DirectionAt(0.5);
                break;

            case 4:     // freier Punkt
                dirCurveMod = dirCurve.DirectionAt(dirCurve.PositionOf(objectPoint));
                break;
            }
            Plane pl;

            if (dirCurve.GetPlanarState() == PlanarState.Planar)
            {
                pl = dirCurve.GetPlane();
            }
            else
            {
                pl = base.ActiveDrawingPlane;
            }
            for (int i = 0; i < (dirOffsetSelect); ++i)
            {
                dirCurveMod = dirCurveMod ^ pl.Normal;
            }
            using (Frame.Project.Undo.ContextFrame(this))
            {
                if (vectorProperty != null)
                {
                    vectorProperty.SetGeoVector(dirCurveMod);
                }
            }
            actualVector = dirCurveMod;
        }
Пример #7
0
 public override GeoVector DirectionAt(double Position)
 {
     return(fixedCurve.DirectionAt(Position));
     // Das stimt nicht, mit Maxima berechnen, braucht sicherlich 2. Ableitung der Fläche
 }