Example #1
0
        public static double[] AnglesCrossLine(Point centre, double r, Point pt1, Point pt2)
        {
            Point t = Funcs2D.PointToLine(pt1, pt2, centre);

            if (Funcs2D.IsEqual(t, centre))
            {
                double an = Funcs2D.LineAngle(pt1, pt2);
                return(new double[] { Funcs2D.PureRadianAngle(an + Math.PI), an });
            }
            double z = Funcs2D.Distance(centre, t);
            double a = Funcs2D.LineAngle(centre, t);

            if (z.IsGreater(r))
            {
                return(null);             // mimo
            }
            if (z.IsEqual(r))             // tecna
            {
                return(new double[] { a });
            }

            //secna
            double aa = Math.Acos(z / r);             // uhel pulky tetivy

            return(new double[] { Funcs2D.PureRadianAngle(a + aa), Funcs2D.PureRadianAngle(a - aa) });
        }
Example #2
0
        /// <summary>
        /// otestuje zda prislusny bot lezi na oblouku
        /// </summary>
        /// <param name="pt">testovany bod</param>
        /// <returns></returns>
        public bool IsPointOn(Point pt)
        {
            Circle2D?c = GetAngles(out double st, out double an);

            if (c == null)
            {
                return(false);
            }
            if (!Funcs2D.Distance(pt, c.Value.Center).IsEqual(Math.Abs(Radius)))
            {
                return(false);
            }
            st = Funcs2D.PureRadianAngle(st);
            double angle = Funcs2D.LineAngle(c.Value.Center, pt);

            if (an > 0)
            {
                an = st + an;
                return(angle.IsGreaterOrEqual(st) && angle.IsLesserOrEqual(an));
            }
            else
            {
                an = st + an;
                return(angle.IsGreaterOrEqual(an) && angle.IsLesserOrEqual(st));
            }
        }
Example #3
0
        /// <summary>
        /// kruznice urcena tremi body na obvodu
        /// </summary>
        /// <param name="pt1">prvni bod</param>
        /// <param name="pt2">druhy bod</param>
        /// <param name="pt3">treti bod</param>
        public Circle2D(Point pt1, Point pt2, Point pt3)
        {
            Radius = 0;
            Center = pt1;

            Point[]  p = new Point[2];
            Vector[] v = new Vector[2];

            p[0].X = (pt1.X + pt2.X) / 2;
            p[0].Y = (pt1.Y + pt2.Y) / 2;
            p[1].X = (pt2.X + pt3.X) / 2;
            p[1].Y = (pt2.Y + pt3.Y) / 2;

            v[0].X = pt2.Y - pt1.Y;
            v[0].Y = -(pt2.X - pt1.X);

            v[1].X = pt3.Y - pt2.Y;
            v[1].Y = -(pt3.X - pt2.X);

            TwoLine2D.CrossStatus st = TwoLine2D.CrossStatus.Infinite;
            if (TwoLine2D.CrossAbs(p[0], st, v[0], st, p[1], st, v[1], st, out Center))
            {
                Radius = Funcs2D.Distance(pt1, Center);
            }
        }
Example #4
0
        /// <summary>
        /// oblouk zadany stredem , pocatecnim bodem a vektorem ne kterem lezi kocovy bod
        /// </summary>
        /// <param name="center">stred</param>
        /// <param name="pt">pocatecni bod</param>
        /// <param name="vector">vektor na kterem lezi koncovy bod</param>
        /// <param name="shortangle">true = kratky oblouk (mezi nulou az 180 stupni), false = dlouhy oblouk (doplnek do 360 stupnu)</param>
        public Arc2D(Point center, Point pt, Vector vector, bool shortangle = true)
        {
            Radius = Funcs2D.Distance(center, pt);
            Begin  = pt;
            double a = Funcs2D.Radian(Vector.AngleBetween(new Vector(1, 0), vector));

            End = Circle2D.PointOn(center, Radius, a);
            if (!shortangle)
            {
                Radius *= -1;
            }
            a         = Vector.AngleBetween(pt.Minus(center), vector);
            Clockwise = !(a > 0 && shortangle || a < 0 && !shortangle);
        }
Example #5
0
        /// <summary>
        /// kruznice zadana dvema body na obvodu a polomerem
        /// , pokud je polomer mensi nez polovina vzdalenosti bodu, umisti se stred kruznice do stredoveho bodu tvoriciho obema ridicimi body
        /// , stred kruznice se umisti do poloroviny urcene ridicimi body, podle znamenka polomeru
        /// </summary>
        /// <param name="pt1">prvni bod na obvodu</param>
        /// <param name="pt2">druhy bod na ovodu</param>
        /// <param name="r">polomer</param>
        public Circle2D(Point pt1, Point pt2, double r)
        {
            double d = Funcs2D.Distance(pt1, pt2) / 2;

            if (Math.Abs(r) <= d)
            {
                Radius = d;
                Center = new Point((pt1.X + pt2.X) / 2, (pt1.Y + pt2.Y) / 2);
            }
            else
            {
                Radius = Math.Abs(r);
                double v = Math.Sqrt(Math.Pow(Radius, 2) - Math.Pow(d, 2));
                Center = Funcs2D.LineRelPtOffset(pt1, pt2, 0.5, r < 0 ? -v : v);
            }
        }
Example #6
0
        /// <summary>
        /// oblouk zadany stredem , pocatecnim bodem a uhlem
        /// </summary>
        /// <param name="center">stred</param>
        /// <param name="pt">pocatecni bod</param>
        /// <param name="angle">uhel v radianech  , smer podle znamenka ( - = clockwise)</param>
        public Arc2D(Point center, Point pt, double angle)
        {
            Radius = Funcs2D.Distance(center, pt);
            Begin  = pt;
            if (Math.Abs(angle) > Math.PI * 2)
            {
                angle = angle % (Math.PI * 2);
            }
            Clockwise = angle < 0;
            double a = Funcs2D.Radian(Vector.AngleBetween(new Vector(1, 0), pt.Minus(center)));

            a  += angle;
            End = Circle2D.PointOn(center, Radius, a);
            if (Math.Abs(angle) > Math.PI)
            {
                Radius *= -1;
            }
        }
Example #7
0
        /// <summary>
        /// oblouk tvoreny dvema po sobe jdoucimi useckami a polomerem
        /// takzvane zaobleni rohu
        /// pokud je polomer zaporny vytvori se tzv. vykousnuti  se stredem ve spolecnem bode
        /// objekt se nastavi na empty pokud jsou usecky rovnobezne nebo jedna z nich ma nulovou delku
        /// </summary>
        /// <param name="pt1">pocatecni bod prvni ridici usecky</param>
        /// <param name="pt2">spolecny bod ridicich usecek</param>
        /// <param name="pt3">konecny bod druhe ridici usecky</param>
        /// <param name="radius">polomer zaobleni, zaporny polomer provede vykousnuti</param>
        /// <param name="testPt">pokud se pocatecni nebo koncovy bod vypocita mimo usecku, objekt se nastavi na Empty</param>
        public Arc2D(Point pt1, Point pt2, Point pt3, double radius, bool testPt = false)
        {
            // zjistim smer offsetu
            double a = Vector.AngleBetween(pt2.Minus(pt1), pt3.Minus(pt2));

            if (a > 0)
            {
                a         = -Math.Abs(radius);
                Clockwise = false;
            }
            else
            {
                a         = Math.Abs(radius);
                Clockwise = true;
            }

            // vypocitam prusecik offsetovanych primek
            Point[] p1 = Funcs2D.LineOffset(pt1, pt2, a);
            Point[] p2 = Funcs2D.LineOffset(pt2, pt3, a);
            if (p1 == null || p2 == null || !TwoLine2D.CrossRel(p1[0], p1[1], p2[0], p2[1], out Point rr))
            {
                // tri body na jedne primce
                Begin  = pt1; End = pt3;
                Radius = 0;
                return;
            }
            if (radius > 0)
            {
                if (testPt)
                {
                    if (!TwoLine2D.TestRelOnLine(TwoLine2D.CrossStatus.And, rr.X) || !TwoLine2D.TestRelOnLine(TwoLine2D.CrossStatus.And, rr.Y))
                    {
                        // body jsou mimo usecky
                        Begin  = pt1; End = pt3;
                        Radius = 0;
                        return;
                    }
                }

                // koeficienty prenesu do puvodnich usecek a spocitam body
                Begin  = Funcs2D.PointOnLine(pt1, pt2, rr.X);
                End    = Funcs2D.PointOnLine(pt2, pt3, rr.Y);
                Radius = radius;
            }
            else
            {
                Radius = -radius;
                if (testPt)
                {
                    if (Funcs2D.Distance(pt1, pt2) < Radius || Funcs2D.Distance(pt2, pt3) < Radius)
                    {
                        // body jsou mimo usecky
                        Begin  = pt1; End = pt3;
                        Radius = 0;
                        return;
                    }
                }
                // bod na prvni primce ve vzdalenosti abs(radius) od spolecneho bodu
                Begin = Funcs2D.PointOnLineLen(pt2, pt1, Radius);
                // bod na druhe primce
                End       = Funcs2D.PointOnLineLen(pt2, pt3, Radius);
                Clockwise = !Clockwise;
            }
        }
Example #8
0
 /// <summary>
 /// kruznice zadana stredem a bodem na obvodu
 /// </summary>
 /// <param name="center">stred</param>
 /// <param name="pt">bod na obvodu</param>
 public Circle2D(Point center, Point pt)
 {
     Radius = Funcs2D.Distance(center, pt);
     Center = center;
 }