Пример #1
0
        protected virtual RealPoint ComputeBarycenter()
        {
            double    surface = Surface;
            RealPoint output  = null;

            if (this.Surface == 0)
            {
                output = new RealPoint(_sides[0].StartPoint);
            }
            else
            {
                output = new RealPoint();

                foreach (PolygonTriangle t in this.ToTriangles())
                {
                    RealPoint barycentreTriangle = t.Barycenter;
                    double    otherSurface       = t.Surface;

                    if (t.Surface > 0)
                    {
                        output.X += barycentreTriangle.X * otherSurface / surface;
                        output.Y += barycentreTriangle.Y * otherSurface / surface;
                    }
                }
            }

            return(output);
        }
Пример #2
0
        public Segment(RealPoint start, RealPoint end)
        {
            _startPoint = new RealPoint(start);
            _endPoint   = new RealPoint(end);

            SetLine(StartPoint, EndPoint);
        }
Пример #3
0
        /// <summary>
        /// Retourne une ligne qui est tournée de l'angle donné
        /// </summary>
        /// <param name="angle">Angle de rotation</param>
        /// <param name="rotationCenter">Centre de rotation, si null (0, 0) est utilisé</param>
        /// <returns>Droite tournée de l'angle donné</returns>
        public Line Rotation(AngleDelta angle, RealPoint rotationCenter = null)
        {
            RealPoint p1, p2;

            if (rotationCenter == null)
            {
                rotationCenter = Barycenter;
            }

            if (_c == 1)
            {
                p1 = new RealPoint(0, _a * 0 + _b);
                p2 = new RealPoint(1, _a * 1 + _b);

                p1 = p1.Rotation(angle, rotationCenter);
                p2 = p2.Rotation(angle, rotationCenter);
            }
            else
            {
                p1 = new RealPoint(_b, 0);
                p2 = new RealPoint(_b, 1);
            }

            return(new Line(p1, p2));
        }
Пример #4
0
        /// <summary>
        /// Retourne le plus petit cercle contenant tous les points et dont le centre est le barycentre des points
        /// </summary>
        /// <param name="pts">Liste des points à contenir</param>
        /// <returns>Cercle obtenu</returns>
        public static Circle GetContainingCircle(this IEnumerable <RealPoint> pts)
        {
            RealPoint center = pts.GetBarycenter();
            double    ray    = pts.Max(p => p.Distance(center));

            return(new Circle(center, ray));
        }
Пример #5
0
        /// <summary>
        /// Retourne un segment qui prolonge l'actuel en ajoutant un point.
        /// Le résultat est valide uniquement si le point ajouté se trouve sur la droite formée par le segment.
        /// </summary>
        /// <param name="pt">Point à ajouter au segment</param>
        /// <returns>Segment prolongé jusqu'au point donné</returns>
        public Segment Join(RealPoint pt)
        {
            Segment s1 = new Segment(_startPoint, pt);
            Segment s2 = new Segment(_endPoint, pt);

            Segment res;

            if (this.Contains(pt))
            {
                res = new Segment(this);
            }
            else if (s1.Contains(_endPoint))
            {
                res = s1;
            }
            else if (s2.Contains(_startPoint))
            {
                res = s2;
            }
            else
            {
                res = null;
            }

            return(res);
        }
Пример #6
0
        protected override RealPoint ComputeBarycenter()
        {
            RealPoint output = null;

            if (Points[0] == Points[1] && Points[0] == Points[2])
            {
                output = new RealPoint(Points[0]);
            }
            else if (Points[0] == Points[1])
            {
                output = new Segment(Points[0], Points[2]).Barycenter;
            }
            else if (Points[0] == Points[2])
            {
                output = new Segment(Points[1], Points[2]).Barycenter;
            }
            else if (Points[1] == Points[2])
            {
                output = new Segment(Points[0], Points[1]).Barycenter;
            }
            else
            {
                Line d1 = new Line(new Segment(Points[0], Points[1]).Barycenter, Points[2]);
                Line d2 = new Line(new Segment(Points[1], Points[2]).Barycenter, Points[0]);

                output = d1.GetCrossingPoints(d2)[0];
            }

            return(output);
        }
Пример #7
0
        /// <summary>
        /// Retourne un segment qui est tournée de l'angle donné
        /// </summary>
        /// <param name="angle">Angle de rotation</param>
        /// <param name="rotationCenter">Centre de rotation, si null (0, 0) est utilisé</param>
        /// <returns>Segment tourné de l'angle donné</returns>
        public new Segment Rotation(AngleDelta angle, RealPoint rotationCenter = null)
        {
            if (rotationCenter == null)
            {
                rotationCenter = Barycenter;
            }

            return(new Segment(_startPoint.Rotation(angle, rotationCenter), _endPoint.Rotation(angle, rotationCenter)));
        }
Пример #8
0
        /// <summary>
        /// Retourne un cercle qui est tourné de l'angle donné
        /// </summary>
        /// <param name="angle">Angle de rotation</param>
        /// <param name="rotationCenter">Centre de rotation, si null le barycentre est utilisé</param>
        /// <returns>Cercle tourné de l'angle donné</returns>
        public Circle Rotation(AngleDelta angle, RealPoint rotationCenter = null)
        {
            if (rotationCenter == null)
            {
                rotationCenter = Barycenter;
            }

            return(new Circle(_center.Rotation(angle, rotationCenter), _radius));
        }
Пример #9
0
        /// <summary>
        /// Construit un cercle depuis son centre et son rayon
        /// </summary>
        /// <param name="center">Point central du cercle</param>
        /// <param name="radius">Rayon du cercle</param>
        public Circle(RealPoint center, double radius)
        {
            if (radius < 0)
            {
                throw new ArgumentException("Radius must be >= 0");
            }

            _center = center;
            _radius = radius;
        }
Пример #10
0
        public Segment(Segment segment)
        {
            _startPoint = new RealPoint(segment.StartPoint);
            _endPoint   = new RealPoint(segment.EndPoint);

            _a = segment.A;
            _b = segment.B;
            _c = segment.C;
            SetLine(StartPoint, EndPoint);
        }
Пример #11
0
 /// <summary>
 /// Calcule l'équation de la droite passant par deux points
 /// </summary>
 /// <param name="p1">Premier point</param>
 /// <param name="p2">Deuxième point</param>
 protected void SetLine(RealPoint p1, RealPoint p2)
 {
     if (p2.X - p1.X == 0)
     {
         _a = 1;
         _b = -p1.X;
         _c = 0;
     }
     else
     {
         _a = (p2.Y - p1.Y) / (p2.X - p1.X);
         _b = -(_a * p1.X - p1.Y);
         _c = 1;
     }
 }
Пример #12
0
        /// <summary>
        /// Retourne un polygone qui est tourné de l'angle donné
        /// </summary>
        /// <param name="angle">Angle de rotation</param>
        /// <param name="rotationCenter">Centre de rotation, si null le barycentre est utilisé</param>
        /// <returns>Polygone tourné de l'angle donné</returns>
        public Polygon Rotation(AngleDelta angle, RealPoint rotationCenter = null)
        {
            if (rotationCenter == null)
            {
                rotationCenter = Barycenter;
            }

            Polygon output = new Polygon(Points.ConvertAll(p => p.Rotation(angle, rotationCenter)), false);

            if (_barycenter.Computed && _barycenter.Value == rotationCenter)
            {
                output._barycenter.Value = new RealPoint(_barycenter.Value);
            }

            return(output);
        }
Пример #13
0
        public static List <RealPoint> CircleAndCircle(Circle circle1, Circle circle2)
        {
            List <RealPoint> output = new List <RealPoint>();

            bool aligned = Math.Abs(circle2.Center.Y - circle1.Center.Y) < RealPoint.PRECISION;

            if (aligned)// Cercles non alignés horizontalement (on pivote pour les calculs, sinon division par 0)
            {
                circle2 = circle2.Rotation(90, circle1.Center);
            }

            RealPoint oc1 = new RealPoint(circle2.Center), oc2 = new RealPoint(circle1.Center);
            double    b = circle2.Radius, c = circle1.Radius;

            double a = (-(Math.Pow(oc1.X, 2)) - (Math.Pow(oc1.Y, 2)) + Math.Pow(oc2.X, 2) + Math.Pow(oc2.Y, 2) + Math.Pow(b, 2) - Math.Pow(c, 2)) / (2 * (oc2.Y - oc1.Y));
            double d = ((oc2.X - oc1.X) / (oc2.Y - oc1.Y));

            double A = Math.Pow(d, 2) + 1;
            double B = -2 * oc1.X + 2 * oc1.Y * d - 2 * a * d;
            double C = Math.Pow(oc1.X, 2) + Math.Pow(oc1.Y, 2) - 2 * oc1.Y * a + Math.Pow(a, 2) - Math.Pow(b, 2);

            double delta = Math.Pow(B, 2) - 4 * A * C;

            if (delta >= 0)
            {
                double x1 = (-B + Math.Sqrt(delta)) / (2 * A);
                double y1 = a - x1 * d;
                output.Add(new RealPoint(x1, y1));

                if (delta > 0)
                {
                    double x2 = (-B - Math.Sqrt(delta)) / (2 * A);
                    double y2 = a - x2 * d;
                    output.Add(new RealPoint(x2, y2));
                }
            }

            if (aligned)
            {
                output = output.ConvertAll(p => p.Rotation(-90, circle1.Center));
            }

            return(output);
        }
Пример #14
0
        /// <summary>
        /// Construit un rectangle à partir du point en haut à gauche, de la largeur et de la hauteur
        /// </summary>
        /// <param name="topLeft">Point en haut à gauche du rectangle</param>
        /// <param name="width">Largeur du rectangle</param>
        /// <param name="heigth">Hauteur du rectangle</param>
        public PolygonRectangle(RealPoint topLeft, double width, double heigth) : base()
        {
            List <Segment> rectSides = new List <Segment>();

            if (topLeft == null)
            {
                throw new ArgumentOutOfRangeException();
            }

            topLeft = new RealPoint(topLeft);

            if (width < 0)
            {
                topLeft.X += width;
                width      = -width;
            }
            if (heigth < 0)
            {
                topLeft.Y += heigth;
                heigth     = -heigth;
            }

            List <RealPoint> points = new List <RealPoint>
            {
                new RealPoint(topLeft.X, topLeft.Y),
                new RealPoint(topLeft.X + width, topLeft.Y),
                new RealPoint(topLeft.X + width, topLeft.Y + heigth),
                new RealPoint(topLeft.X, topLeft.Y + heigth)
            };

            for (int i = 1; i < points.Count; i++)
            {
                rectSides.Add(new Segment(points[i - 1], points[i]));
            }

            rectSides.Add(new Segment(points[points.Count - 1], points[0]));

            BuildPolygon(rectSides, false);
        }
Пример #15
0
        /// <summary>
        /// Retourne l'équation de la droite perpendiculaire à celle-ci et passant par un point donné
        /// </summary>
        /// <param name="point">Point contenu par la perpendiculaire recherchée</param>
        /// <returns>Equation de la droite perpendiculaire à celle-ci et passant par le point donné</returns>
        public Line GetPerpendicular(RealPoint point)
        {
            // Si je suis une droite verticale, je retourne l'horizontale qui passe par le point
            if (C == 0)
            {
                return(new Line(0, point.Y));
            }

            // Si je suis une droite horizontale, je retourne la verticale qui passe par le point
            else if (A == 0)
            {
                return(new Line(1, -point.X, 0));
            }

            // Si je suis une droite banale, je calcule
            else
            {
                double newA = -1 / _a;
                double newB = -newA * point.X + point.Y;

                return(new Line(newA, newB));
            }
        }
Пример #16
0
        /// <summary>
        /// Retourne le cercle correspondant le mieux aux points données.
        /// </summary>
        /// <param name="pts">Points dont on cherche un cercle approchant.</param>
        /// <returns>Cercle calculé</returns>
        public static Circle FitCircle(this List <RealPoint> pts)
        {
            double[,] m1 = new double[pts.Count, 3];
            double[] m2 = new double[pts.Count];

            for (int n = 0; n < pts.Count; n++)
            {
                m1[n, 0] = -2f * pts[n].X;
                m1[n, 1] = -2f * pts[n].Y;
                m1[n, 2] = 1;

                m2[n] = -(Math.Pow(pts[n].X, 2) + Math.Pow(pts[n].Y, 2));
            }

            double[,] m3 = Matrix.Transpose(m1);
            double[,] m4 = Matrix.Inverse3x3(Matrix.Multiply(m3, m1));
            double[] m5 = Matrix.Multiply(m3, m2);
            double[] m6 = Matrix.Multiply(m4, m5);

            RealPoint center = new RealPoint(m6[0], m6[1]);
            double    radius = Math.Sqrt(Math.Pow(center.X, 2) + Math.Pow(center.Y, 2) - m6[2]);

            return(new Circle(center, radius));
        }
Пример #17
0
 /// <summary>
 /// Retourne la projection hortogonale du point sur la droite.
 /// </summary>
 /// <param name="point">Point à projet sur la droite</param>
 /// <returns>Projection du point sur la droite</returns>
 public RealPoint GetProjection(RealPoint point)
 {
     return(GetCrossingPoints(GetPerpendicular(point))[0]);;
 }
Пример #18
0
 /// <summary>
 /// Construit un triangle à partir de ses 3 sommets
 /// </summary>
 /// <param name="p1">Sommet 1</param>
 /// <param name="p2">Sommet 2</param>
 /// <param name="p3">Sommet 3</param>
 public PolygonTriangle(RealPoint p1, RealPoint p2, RealPoint p3)
     : base(new List <RealPoint>() { p1, p2, p3 })
 {
     // L'interet du triangle c'est qu'il est simple de calculer son aire et son barycentre et qu'on s'en sert pour calculer ceux de polygones quelconques
 }
Пример #19
0
 /// <summary>
 /// Construit un cercle depuis un autre cercle
 /// </summary>
 /// <param name="circle">cercle à copier</param>
 public Circle(Circle circle)
 {
     _center = circle._center;
     _radius = circle._radius;
 }
Пример #20
0
 /// <summary>
 /// Construit la droite passant par deux points
 /// </summary>
 /// <param name="p1">Premier point</param>
 /// <param name="p2">Deuxième point</param>
 public Line(RealPoint p1, RealPoint p2)
 {
     SetLine(p1, p2);
 }
Пример #21
0
 /// <summary>
 /// Retourne une copie de la forme ayant subit une rotation
 /// </summary>
 /// <param name="shape">Forme à tourner</param>
 /// <param name="angle">Angle de rotation</param>
 /// <param name="rotationCenter">Centre de rotation. Si null alors le barycentre est utilisé.</param>
 /// <returns>Nouvelle forme ayant subit la rotation</returns>
 public static IShape Rotation(this IShape shape, AngleDelta angle, RealPoint rotationCenter = null)
 {
     return(((IShapeModifiable <IShape>)shape).Rotation(angle, rotationCenter));
 }