Пример #1
0
        /// <summary>
        /// Crea un arco de circunferencia indicando puntoInicial, puntoFinal, centro, radio y sentido de giro (cw).
        /// </summary>
        public static CircleArc2 NewArc(Point2d pt1, Point2d pt2, Point2d center, double radius, ArcDirection dir)
        {
            double angle1 = AngleUtils.Ensure0To2Pi(pt1.Sub(center).Angle, false);
            double angle2 = AngleUtils.Ensure0To2Pi(pt2.Sub(center).Angle, false);

            if (dir == ArcDirection.Clockwise)
            {
                if (angle2 > angle1)
                {
                    angle2 -= 2.0 * System.Math.PI;
                }
            }
            else if (angle2 < angle1)
            {
                angle2 += 2.0 * System.Math.PI;
            }
            if (angle2 > 2.0 * System.Math.PI)
            {
                angle1 -= 2.0 * System.Math.PI;
                angle2 -= 2.0 * System.Math.PI;
            }
            else if (angle2 < -2.0 * System.Math.PI)
            {
                angle1 += 2.0 * System.Math.PI;
                angle2 += 2.0 * System.Math.PI;
            }
            return(new CircleArc2(center, radius, angle1, angle2));
        }
Пример #2
0
        /// <summary>
        ///     Crea un arco de circunferencia indicando puntoInicial, puntoFinal, centro, radio y sentido de giro (cw).
        /// </summary>
        public static CircleArc2 NewArc(Vec2d pt1, Vec2d pt2, Vec2d center, double radius, bool cw)
        {
            double a1 = vecMath.Angle(pt1.Sub(center));
            double a2 = vecMath.Angle(pt2.Sub(center));

            a1 = AngleUtils.Ensure0To2Pi(a1);
            a2 = AngleUtils.Ensure0To2Pi(a2);

            if (cw)
            {
                if (a2 > a1)
                {
                    a2 -= 2 * SysMath.PI;
                }
            }
            else
            {
                if (a2 < a1)
                {
                    a2 += 2 * SysMath.PI;
                }
            }

            return(new CircleArc2(center, radius, a1, a2));
        }
Пример #3
0
        public void Test1()
        {
            const double error = 1e-8;

            // desarrollo, r, parametro, x, y, c, normal ¿o direccion?,
            for (int i = 0; i < this.testData1.Length;)
            {
                double l     = this.testData1[i++];
                double r     = this.testData1[i++];
                double a     = this.testData1[i++];
                double x     = this.testData1[i++];
                double y     = this.testData1[i++];
                double radio = this.testData1[i++];
                double tg    = this.testData1[i++];

                bool invertY = ((l < 0 && r > 0) || (l > 0 && r < 0));

                double x2, y2;
                ClothoUtils.Clotho(l, invertY, a, out x2, out y2);
                double radio2 = ClothoUtils.ClothoRadius(l, invertY, a);
                double tg2    = ClothoUtils.ClothoTangent(l, invertY, a);

                Assert.IsTrue(x.EpsilonEquals(x2, error));
                Assert.IsTrue(y.EpsilonEquals(y2, error));
                Assert.IsTrue((double.IsInfinity(radio) && double.IsInfinity(radio2)) || radio.EpsilonEquals(radio2, error));
                Assert.IsTrue(AngleUtils.Ensure0To2Pi(tg).EpsilonEquals(AngleUtils.Ensure0To2Pi(tg2), error));
            }
        }
Пример #4
0
        public void Test1()
        {
            double angle = Point2d.EvAngle(new Point2d(10, 10), new Point2d(0, 0), new Point2d(20, 0));

            angle = AngleUtils.Ensure0To2Pi(angle);
            Assert.IsTrue(angle.EpsilonEquals(Math.PI / 2));
        }
Пример #5
0
        public double Project(Point2d punto, out double d2)
        {
            DistPointCircleArc2 distance = new DistPointCircleArc2()
            {
                Point = punto,
                Arc   = this
            };

            // Se calcula el punto mas cercano.
            d2 = distance.CalcDistance2();

            double ca = distance.ClosestAngle;
            double ai = this.Angle1;
            double aa = this.AdvAngle;

            ai = AngleUtils.Ensure0To2Pi(ai);

            // Se comprueban los valores.
            Contract.Assert(ca.Between(0, 2 * SysMath.PI));
            Contract.Assert(ai.Between(0, 2 * SysMath.PI));
            Contract.Assert(aa.Between(-2 * SysMath.PI, 2 * SysMath.PI));

            if (aa >= 0)
            {
                if (ca < ai)
                {
                    ca += 2 * SysMath.PI;
                    Contract.Assert(ca >= ai);
                }
            }
            else
            {
                if (ca > ai)
                {
                    ca -= 2 * SysMath.PI;
                    Contract.Assert(ca <= ai);
                }
            }

            // Se calcula la estacion.
            return((ca - ai) / aa);
        }
Пример #6
0
        public double CalcDistance2()
        {
            // Se calcula la distancia al circulo.
            Circle2          circulo = new Circle2(this.Arc.Center, this.Arc.Radius);
            DistPointCircle2 dist    = new DistPointCircle2()
            {
                Point  = this.Point,
                Circle = circulo
            };
            double  d  = dist.CalcDistance();
            Point2d p  = dist.ClosestPoint;
            double  ca = AngleUtils.Ensure0To2Pi(dist.ClosestAngle); // [0, 2PI)

            // Se comprueba si el punto cae dentro del arco.
            double ai = this.Arc.Angle1;
            double aa = this.Arc.AdvAngle;

            if (AngleUtils.InArc(ai, aa, ca))
            {
                this.ClosestPoint = p;
                this.ClosestAngle = ca;
                return(d * d);
            }

            // Se prueban los extremos.
            double d2_0 = this.Arc.Point0.Distance2To(this.Point);
            double d2_1 = this.Arc.Point1.Distance2To(this.Point);

            if (d2_0 <= d2_1)
            {
                this.ClosestPoint = this.Arc.Point0;
                this.ClosestAngle = AngleUtils.Ensure0To2Pi(this.Arc.Angle1, true);
                return(d2_0);
            }
            else
            {
                this.ClosestPoint = this.Arc.Point1;
                this.ClosestAngle = AngleUtils.Ensure0To2Pi(this.Arc.Angle2, true);
                return(d2_1);
            }
        }
Пример #7
0
        public bool PointInCurve(Point2d p)
        {
            Vector2d vector2d = p - this.Center;

            if (!vector2d.Length.EpsilonEquals(this.Radius, 0.01))
            {
                return(false);
            }
            double num1 = AngleUtils.Ensure0To2Pi(vector2d.Angle, false);
            double num2 = AngleUtils.Ensure0To2Pi(this.Angle1, false);
            double num3 = this.Angle2 - this.Angle1;

            if (num3 > 0.0)
            {
                return(num1 >= num2 && num1 <= num2 + num3);
            }
            else
            {
                return(num1 >= num2 + num3 && num1 <= num2);
            }
        }
Пример #8
0
        /// <summary>
        ///     Arco que pasa por los puntos <c>pinicial</c>, <c>ppaso</c>, <c>pfinal</c>.
        /// </summary>
        /// <exception cref="PuntosAlineadosException">
        ///     Indica que los puntos estan
        ///     alineados.
        /// </exception>
        public static CircleArc2 ThreePoints(Vec2d p1, Vec2d pp, Vec2d p2)
        {
            Vec2d pcenter = GetCenter(p1, pp, p2);

            double radius = vecMath.Length(pcenter, p1);

            Vec2d  v1     = p1.Sub(pcenter);
            Vec2d  vp     = pp.Sub(pcenter);
            Vec2d  v2     = p2.Sub(pcenter);
            double alpha1 = vecMath.Angle(v1);
            double alphap = vecMath.Angle(vp);
            double alpha2 = vecMath.Angle(v2);

            { // Se prueba el sentido CCW, alpha1 < alphap < alpha2
                double a1 = alpha1;
                double ap = alphap;
                double a2 = alpha2;
                while (ap < a1)
                {
                    ap += 2 * SysMath.PI;
                }
                while (a2 < ap)
                {
                    a2 += 2 * SysMath.PI;
                }
                if (a2 - a1 > 2 * SysMath.PI)
                { // Se ha dado mas de una vuelta, solucion no valida.
                }
                else
                {
                    return(NewArcWithAdvance(pcenter, radius, AngleUtils.Ensure0To2Pi(a1), a2 - a1));
                }
            }

            { // Se prueba el sentido CW, alpha1 > alphap > alpha2
                double a1 = alpha1;
                double ap = alphap;
                double a2 = alpha2;
                while (ap > a1)
                {
                    ap -= 2 * SysMath.PI;
                }
                while (a2 > ap)
                {
                    a2 -= 2 * SysMath.PI;
                }
                if (a1 - a2 > 2 * SysMath.PI)
                { // Se ha dado mas de una vuelta, solucion no valida.
                }
                else
                {
                    return(NewArcWithAdvance(pcenter, radius, AngleUtils.Ensure0To2Pi(a1), a2 - a1));
                }
            }

            throw new Exception();

#if false
            double alpha2 = vecMath.Angle(v1, v2);

            alpha1 = AngleUtils.Ensure0To2Pi(alpha1);

            // Existen 2 soluciones que dependen de angulo de pp:
            //  si alpha2 > 0 : alpha2 y alpha2 - 2*PI
            //  si alpha2 < 0 : alpha2 y alpha2 + 2*PI

            if (alpha2 > 0)
            {
                double alpha3 = vecMath.Angle(pp);
            }
            else
            {
            }
            return(NewArcWithAdvance(pcenter, radius, alpha1, alpha2));
#endif
        }