This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
in204:tds:sujets:td1:part4 [2019/09/19 13:23] bmonsuez [Question n°1] |
in204:tds:sujets:td1:part4 [2022/11/18 10:49] (current) |
||
---|---|---|---|
Line 66: | Line 66: | ||
une l’intersection ainsi que le point d’intersection faux, dans le cas contraire. | une l’intersection ainsi que le point d’intersection faux, dans le cas contraire. | ||
+ | |||
<code cpp> | <code cpp> | ||
class Segment | class Segment | ||
Line 86: | Line 87: | ||
m_end(anotherSegment.m_end) | 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 98: | 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 120: | 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> | ||
+ | |||