Beispiel #1
0
        public static EllipseArc2D Create(GeoPoint2D center, GeoVector2D majorAxis, GeoVector2D minorAxis, GeoPoint2D startPoint, GeoPoint2D endPoint, bool counterClock)
        {
            // bestimme die beiden Winkel
            GeoVector2D majAx;
            GeoVector2D minAx;
            GeoPoint2D  left, right, bottom, top;

            Geometry.PrincipalAxis(center, majorAxis, minorAxis, out majAx, out minAx, out left, out right, out bottom, out top, false);
            ModOp2D    toUnit = ModOp2D.Fit(new GeoPoint2D[] { center, center + majAx, center + minAx }, new GeoPoint2D[] { GeoPoint2D.Origin, GeoPoint2D.Origin + GeoVector2D.XAxis, GeoPoint2D.Origin + GeoVector2D.YAxis }, true);
            GeoPoint2D p      = toUnit * startPoint;
            double     sa     = p.ToVector().Angle.Radian;

            p = toUnit * endPoint;
            double ea = p.ToVector().Angle.Radian;
            double sw;

            if (counterClock)
            {
                sw = ea - sa;
                if (sw <= 0.0)
                {
                    sw += Math.PI * 2.0;            // geändert auf <= bzw. >=, da sonst aus Vollkreisen Leerkreise werden
                }
            }
            else
            {
                sw = ea - sa;
                if (sw >= 0.0)
                {
                    sw -= Math.PI * 2.0;
                }
            }
            return(new EllipseArc2D(center, majAx, minAx, sa, sw, left, right, bottom, top));
        }
Beispiel #2
0
 public override ICurve2D GetProjectedCurve(ICurve curve, double precision)
 {
     if (curve is Line line)
     {
         // this must be a line through the apex, otherwise there are no lines on the cone
         // if it is an extremely small line not through the apex, the result will also be a line, which
         // in reverse projection will give a very short ellipse
         return(new Line2D(PositionOf(line.StartPoint), PositionOf(line.EndPoint)));
     }
     else if (curve is Ellipse elli)
     {
         if (elli.IsCircle)
         {
             GeoPoint2D sp2d = PositionOf(elli.StartPoint);
             if (elli.IsArc)
             {
             }
             else
             {
                 Arc2D     a2d  = new Arc2D(GeoPoint2D.Origin, sp2d.ToVector().Length, sp2d, sp2d, true);
                 GeoVector sdir = a2d.StartDirection.x * UDirection(sp2d) + a2d.StartDirection.y * VDirection(sp2d);
                 if (sdir * elli.StartDirection < 0)
                 {
                     a2d.counterClock = false;
                 }
                 return(a2d);
             }
         }
         else
         {
             // this is a intersection with a plane.
             GeoPoint2D[] fp2d = new GeoPoint2D[5];
             double       n    = 5.0;
             if (elli.IsArc)
             {
                 n = 4.0;
             }
             for (int i = 0; i < 5; i++)
             {
                 fp2d[i] = PositionOf(elli.PointAt(i / n));
             }
             Ellipse2D elli2d = Ellipse2D.FromFivePoints(fp2d, !elli.IsArc); // returns both full ellipse and ellipse arc
             if (elli2d != null)
             {
                 return(elli2d);
             }
         }
     }
     return(base.GetProjectedCurve(curve, precision));
 }
        public override ICurve2D[] GetTangentCurves(GeoVector direction, double umin, double umax, double vmin, double vmax)
        {
            if (Precision.SameDirection(direction, zAxis, false))
            {
                return(new ICurve2D[] { });
            }
            GeoPoint2D  uv    = PositionOf(location + (direction ^ zAxis));
            GeoVector2D dir2d = uv.ToVector();

            dir2d.Length = xAxis.Length * 1.1;
            Line2D l2d = new Line2D(GeoPoint2D.Origin - dir2d, GeoPoint2D.Origin + dir2d);

            double[]        parts = Clip(l2d);
            List <ICurve2D> res   = new List <ICurve2D>(2);

            for (int i = 0; i < parts.Length; i += 2)
            {
                res.Add(l2d.Trim(parts[i], parts[i + 1]));
            }
            return(res.ToArray());
        }
Beispiel #4
0
        public override ICurve2D[] GetTangentCurves(GeoVector direction, double umin, double umax, double vmin, double vmax)
        {
            if (Precision.SameDirection(direction, zAxis, false))
            {
                return(new ICurve2D[0]);
            }
            GeoPoint2D  uv    = PositionOf(location + zAxis + (direction ^ zAxis));
            GeoVector2D dir2d = uv.ToVector();

            dir2d.Length = Math.Max(Math.Max(Math.Abs(umax), Math.Abs(umin)), Math.Max(Math.Abs(vmax), Math.Abs(vmin))) * 1.1;
            ClipRect   clr = new ClipRect(umin, umax, vmin, vmax);
            GeoPoint2D sp  = GeoPoint2D.Origin - dir2d;
            GeoPoint2D ep  = GeoPoint2D.Origin + dir2d;

            if (clr.ClipLine(ref sp, ref ep))
            {
                return new ICurve2D[] { new Line2D(sp, ep) }
            }
            ;
            else
            {
                return(new ICurve2D[0]);
            }
        }
Beispiel #5
0
        /// <summary>
        /// Overrides <see cref="CADability.Curve2D.GeneralCurve2D.Intersect (ICurve2D)"/>
        /// </summary>
        /// <param name="IntersectWith"></param>
        /// <returns></returns>
        public override GeoPoint2DWithParameter[] Intersect(ICurve2D IntersectWith)
        {       // gesucht sind alle Schnittpunkte, also auch in der Verlängerung!
            Line2D l2d = IntersectWith as Line2D;

            if (l2d != null)
            {
                GeoPoint2DWithParameter[] res = l2d.Intersect(this); // die Linie kanns
                // aber noch die Rollen vertauschen
                for (int i = 0; i < res.Length; ++i)
                {       // par1 und par2 vertauschen
                    double tmp = res[i].par1;
                    res[i].par1 = res[i].par2;
                    res[i].par2 = tmp;
                }
                return(res);
            }
            else if (IntersectWith is Circle2D) // geht auch für Arc2D
            {
                GeoPoint2D[] ip = Geometry.IntersectEC(center, majrad, minrad, majorAxis.Angle, (IntersectWith as Circle2D).Center, (IntersectWith as Circle2D).Radius);
                GeoPoint2DWithParameter[] res = new GeoPoint2DWithParameter[ip.Length];
                double error = 0.0;
                for (int i = 0; i < ip.Length; ++i)
                {
                    GeoPoint2D p0 = toUnitCircle * ip[i];
                    error      += Math.Abs(1.0 - p0.ToVector().Length);
                    error      += Math.Abs(1.0 - (ip[i] | (IntersectWith as Circle2D).Center) / (IntersectWith as Circle2D).Radius);
                    res[i].p    = ip[i];
                    res[i].par1 = PositionOf(ip[i]);
                    res[i].par2 = IntersectWith.PositionOf(ip[i]); // liefert auch für Arc2D den richtigen Wert
                }
                if (error < 1e-7)                                  // auf Radius 1 normierter fehler
                {                                                  // wenn nicht, dann unten mit dreiecksschnitten lösen
                    return(res);
                }
            }
            else if (IntersectWith is Ellipse2D) // geht auch für EllipseArc2D
            {
                Ellipse2D    elli             = (IntersectWith as Ellipse2D);
                Ellipse2D    ellinorm         = this.GetModified(elli.toUnitCircle) as Ellipse2D;
                GeoPoint2D[] ip               = Geometry.IntersectEC(ellinorm.center, ellinorm.majrad, ellinorm.minrad, ellinorm.majorAxis.Angle, elli.toUnitCircle * elli.center, 1.0);
                GeoPoint2DWithParameter[] res = new GeoPoint2DWithParameter[ip.Length];
                for (int i = 0; i < ip.Length; ++i)
                {
                    res[i].p    = elli.fromUnitCircle * ip[i];
                    res[i].par1 = PositionOf(res[i].p);
                    res[i].par2 = IntersectWith.PositionOf(res[i].p);
                }
                for (int i = 0; i < res.Length; i++)
                {
                    RefineIntersectionPoint(this, elli, ref res[i]);
                }
                if (((ellinorm.Center | GeoPoint2D.Origin) < Precision.eps) && res.Length == 0)
                {   // gleicher Mittelpunkt und keine Lösung, könnte zusammenhängender Bogen zweier identischen Ellipsen sein
                    bool       connected = false;
                    GeoPoint2D p         = GeoPoint2D.Origin;
                    double     par0      = 0.0;
                    double     par1      = 0.0;
                    if ((this.EndPoint | elli.StartPoint) < Precision.eps)
                    {
                        p         = this.EndPoint;
                        par0      = 1.0;
                        par1      = 0.0;
                        connected = true;
                    }
                    if ((this.EndPoint | elli.EndPoint) < Precision.eps)
                    {
                        p         = this.EndPoint;
                        par0      = 1.0;
                        par1      = 1.0;
                        connected = true;
                    }
                    if ((this.StartPoint | elli.StartPoint) < Precision.eps)
                    {
                        p         = this.StartPoint;
                        par0      = 0.0;
                        par1      = 0.0;
                        connected = true;
                    }
                    if ((this.StartPoint | elli.EndPoint) < Precision.eps)
                    {
                        p         = this.StartPoint;
                        par0      = 0.0;
                        par1      = 1.0;
                        connected = true;
                    }
                    if (connected)
                    {
                        res    = new GeoPoint2DWithParameter[1];
                        res[0] = new GeoPoint2DWithParameter(p, par0, par1);
                    }
                }
                return(res);
            }
            // auch wenn die Ellipsenschnittpunkte schlecht waren
            return(base.Intersect(IntersectWith));
        }