User Tools

Site Tools


in204:tds:sujets:td1:part4

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
in204:tds:sujets:td1:part4 [2019/09/19 12:54]
bmonsuez [Question n°1]
in204:tds:sujets:td1:part4 [2022/11/18 10:49] (current)
Line 61: Line 61:
  
 <hidden Correction classe ''​Segment''>​ <hidden Correction classe ''​Segment''>​
-  * Une classe ''​Segment''​ constituée de deux extrémités sous la forme de ''​Point''​. ​Un segment est construit à l’aide de deux points ​et doit fournir ​les méthodes suivantes +La classe ''​Segment''​ constituée de deux extrémités sous la forme de ''​Point''​. ​Ces deux points ​sont définis par les champs ''​m_start''​ et ''​m_end''​. 
-    * une méthode pour tester si un point appartient au segment. + 
-    * une méthode qui teste l’intersection du segment avec un autre segment. Cette méthode retourne vrai s’il existe ​une l’intersection ainsi que le point d’intersection faux, dans le cas contraire.+Nous définissons [[in204:​cpp:​syntax:​class:​constructor:​copy|le constructeur de recopie]] ainsi que deux constructeurs spécialisés construisant ​un segment ​soit à partir des points extrémaux, soit au contraire à partir des abscisses et ordonnés des points extrémaux
 + 
 +une l’intersection ainsi que le point d’intersection faux, dans le cas contraire. 
 <code cpp> <code cpp>
 class Segment class Segment
 { {
 private: private:
-    Point m_Start+    Point m_start
-    Point m_End;+    Point m_end;
    
 public: public:
     Segment(const Point& theStart, const Point& theEnd): ​     Segment(const Point& theStart, const Point& theEnd): ​
-        ​m_Start(theStart), ​m_End(theEnd)+        ​m_start(theStart), ​m_end(theEnd)
     {}        {}   
-    Segment(const Point& theStartconst Point& theEnd): m_Start(theStart), m_End(theEnd)+    Segment(int startPointXint startPointY,​  
 +        int endPointX, int endPointY):  
 +        m_start(startPointX,​ startPointY),  
 +        m_end(endPointX, endPointY)
     {}        {}   
-     +    ​Segment(const Segment&​ anotherSegment): ​ 
-class +        ​m_start(anotherSegment.m_start),​  
 +        m_end(anotherSegment.m_end) 
 +    {}    
 +    bool contains(Point aPoint) 
 +    { 
 +        if(m_start.getX() == m_end.getX()) 
 +        { 
 +            if(aPoint.getX() != m_start.getX()) 
 +                return false; 
 + 
 +            if(m_start.getY() <= m_end.getY()) 
 +            { 
 +                if(aPoint.getY() < m_start.getY()  
 +                    || aPoint.getY() > m_end.getY()) 
 +                    return false; 
 +            } 
 +            else 
 +            { 
 +                if(aPoint.getY() > m_start.getY()  
 +                    || aPoint.getY() < m_end.getY()) 
 +                    return false; 
 +            } 
 +            return true;             
 +        } 
 +        double ratio =  
 +            (double)(m_start.getY() - m_end.getY()  
 +            / (double)(m_start.getX() - m_end.getX());​ 
 +        int pointY =  
 +            (int)floor(ratio * (aPoint.getX() - m_end.getX()) 
 +            + m_end.getY();​ 
 +        return pointY == aPoint.getY();​ 
 +    } 
 +    bool intersectsWith( 
 +      const Segment&​ anotherSegment,​  
 +      Point& theIntersectingPoint) 
 +    { 
 +        Droite line(m_start,​ m_end); 
 +        Droite anotherLine(anotherSegment.m_start,​ anotherSegment.m_end);​ 
 +         
 +        double intersectionX,​ intersectionY;​ 
 +        if(!line.intersectsWith( 
 +          anotherLine,​  
 +          intersectionX,​ intersectionY)) 
 +          return false; 
 + 
 +        theIntersectingPoint =  
 +          Point( 
 +              (int)round(intersectionX),​  
 +              (int)round(intersectionY));​ 
 +        return contains(theIntersectingPoint )  
 +            || anotherSegment.contains(theIntersectingPoint); ​   
 +    } 
 +};
 </​code>​ </​code>​
 +</​hidden>​
 +
 +<hidden Correction classe ''​Droite''>​
 +<code cpp>
 +class Droite
 +{
 +private:
 +    Point m_point;
 +    double m_angle;
 +
 +public:
 +    Droite(double anAngle, const Point& aPoint): ​
 +        m_point(aPoint), ​
 +        m_angle(anAngle)
 +    {}
 +    Droite(const Point& theStart, const Point& theEnd): ​
 +        m_point(theStart), ​
 +        m_angle(atan2(
 +            (double)(theEnd.getY() - theStart.getY())
 +            (double)(theEnd.getX() - theStart.getX())))
 +    {} 
 +    Droite(const Line& anotherLine):​
 +        m_point(anotherLine.m_point),​
 +        m_angle(anotherLine.m_angle)
 +    {}
 +    bool intersectsWith(const Line& anotherLine)
 +    {
 +        double intersectionX;​
 +        double intersectionY;​
 +        return intersectsWith(anotherLine,​
 +            intersectionX,​ intersectionY);​
 +    }
 +    bool intersectsWith(
 +        const Line& anotherLine,​
 +        double& theIntersectionX,​
 +        double& theIntersectionY)
 +    {
 +        if(m_point.getX()
 +            == anotherLine.m_point.getX() && ​
 +            m_point.getY() ​
 +            == anotherLine.m_point.getY())
 +            return true;
 +        if(m_angle == anotherLine.m_angle)
 +        {
 +            double angle = atan2(
 +                anotherLine.m_point.getY() - m_point.getY(),​
 +                anotherLine.m_point.getX() - m_point.getX());​
 +            if(angle != m_angle)
 +                return false; ​                         ​
 +        }
 +        return true;
 +    }
 +}
 + 
 +</​code>​
 +
 </​hidden>​ </​hidden>​
 ==== Question n° 2 ==== ==== Question n° 2 ====
  
 Ajouter à toutes ces classes des méthodes d’affichage pour le déboguage que l’on appellera ''​print''​. Ajouter à toutes ces classes des méthodes d’affichage pour le déboguage que l’on appellera ''​print''​.
 +
 +<hidden Correction>​
 +
 +<code cpp>
 +class Point
 +{
 +    // Ajouter la méthode suivante après les autres
 +    // méthodes.
 +public:
 +    void print() const
 +    {
 +        std::cout << "​("​ << m_x << ", " << m_y << "​)"; ​
 +    }
 +};
 +
 +class Segment
 +{
 +    // Ajouter la méthode suivante après les autres
 +    // méthodes.
 +public:
 +    void print() const
 +    {
 +        std::cout << "​[";​
 +        m_start.print();​
 +        std::cout << "​-";​
 +        m_end.print();​
 +        std::cout << "​]"; ​
 +    }
 +};
 +
 +class Droite
 +{
 +    // Ajouter la méthode suivante après les autres
 +    // méthodes.
 +public:
 +    void print() const
 +    {
 +        std::cout << "<";​
 +        m_point.print();​
 +        std::cout << ", " m_angle << ">"; ​
 +    }
 +};
 +
 +</​code>​
 +
 +</​hidden>​
 +
  
 ==== Question n° 3 ==== ==== Question n° 3 ====
Line 90: Line 251:
   * Ajouter une méthode rotate90() effectuant une rotation de 90 degrés à une droite.   * Ajouter une méthode rotate90() effectuant une rotation de 90 degrés à une droite.
   * Ajouter une méthode move(int x, int y) effectuant une translation à une droite.   * Ajouter une méthode move(int x, int y) effectuant une translation à une droite.
 +
 +
 +<hidden Correction>​
 +
 +Cette version correspond à des méthodes qui crée un nouvel objet qui est une copie de l'​objet courant et ne modifie par l'​objet courant.
 +
 +<code cpp>
 +...
 +
 +const double pi = 3.14;
 +
 +...
 +
 +class Droite
 +{
 +    // Code précédent de la classe.
 +    ...     
 +    ​
 +public:
 +    Droite rotate(double anAngle) const
 +    {
 +        return Droite(m_Point,​ m_angle + anAngle);
 +    }
 +    Droite rotate90(double anAngle) const
 +    {
 +        return rotate(m_Point,​ m_angle + 3.14/4);
 +    }
 +    Droite move(int x, int y) const
 +    {
 +        return Droite(
 +            Point(m_Point.getX() + x,
 +                  m_Point.GetY() + y),
 +            m_angle);
 +    }
 +    ...
 +};
 +</​code>​
 +
 +Une autre possibilité consiste à modifier l'​objet courant. C'est ce que fait le code suivant :
 +
 +<code cpp>
 +...
 +
 +const double pi = 3.14;
 +
 +...
 +
 +class Droite
 +{
 +    ... // Code précédent de la classe.
 +    ​
 +    ​
 +public:
 +    Droite& rotate(double anAngle)
 +    {
 +        m_angle += anAngle;
 +        return *this;
 +    }
 +    Droite& rotate90(double anAngle)
 +    {
 +        return Turn(m_Point,​ m_angle + pi/4);
 +    }
 +    Droite& move(int x, int y)
 +    {
 +        mPoint =
 +            Point(m_Point.getX() + x,
 +                  m_Point.GetY() + y);
 +        return *this;
 +    }
 +};
 +</​code>​
 +
 +Typiquement,​ nous retournons une référence à l'​objet que nous venons de modifier. Ceci permet d'​enchaîner les transformations comme suit :
 +
 +<code cpp>
 +    Droite droite(Point(0,​0),​ pi/8);
 +    ​
 +    droite.Move(2,​3).rotate(-pi/​8);​
 +        // Nous effectuons une droite et puis nous effectuons ​
 +        // une rotation.
 +</​code>​
 +
 +</​hidden>​
  
 ==== Question n° 4 ==== ==== Question n° 4 ====
Line 112: Line 356:
 } }
 </​code>​ </​code>​
 +
 +<hidden correction>​
 +
 +Il suffit d'​exécuter le code pour les classes réalisées et vérifier que les résultas sont conformes aux résultats attendus.
 +
 +</​hidden>​
 +
  
  
in204/tds/sujets/td1/part4.1568897681.txt.gz · Last modified: 2019/09/19 12:54 by bmonsuez