/* Quadrilatere en 2D */ /* */ /* Auteur: Nicolas JANEY */ /* nicolas.janey@univ-fcomte.fr */ /* Novembre 2012 */ #include #include #include #include #include #include #include "Quadrilatere2D.h" #include "Position2D.h" #include "Segment2D.h" #include "TraceSegment.h" static void calculCoefficientsDroite(double *a,double *b,double *c,Position2D *q1,Position2D *q2); /* Constructeurs */ Quadrilatere2D::Quadrilatere2D(void) { q1 = new Position2D(1.0,1.0); q2 = new Position2D(-1.0,1.0); q3 = new Position2D(-1.0,-1.0); q4 = new Position2D(1.0,-1.0); update(); } Quadrilatere2D::Quadrilatere2D(Position2D *s1,Position2D *s2,Position2D *s3,Position2D *s4) { q1 = new Position2D(s1); q2 = new Position2D(s2); q3 = new Position2D(s3); q4 = new Position2D(s4); update(); } Quadrilatere2D::Quadrilatere2D(Quadrilatere2D *q) { q1 = new Position2D(q->q1); q2 = new Position2D(q->q2); q3 = new Position2D(q->q3); q4 = new Position2D(q->q4); update(); } /* Destructeur */ Quadrilatere2D::~Quadrilatere2D(void) { delete(q1); delete(q2); delete(q3); delete(q4); } /* Mise a jour de a, b et c en fonction */ /* de q1, q2, q3 et q4 */ void Quadrilatere2D::update(void) { calculCoefficientsDroite(&a[0],&b[0],&c[0],q1,q2); calculCoefficientsDroite(&a[1],&b[1],&c[1],q2,q3); calculCoefficientsDroite(&a[2],&b[2],&c[2],q3,q4); calculCoefficientsDroite(&a[3],&b[3],&c[3],q4,q1); } /* Dessin OpenGL */ void Quadrilatere2D::draw(int zoom) { trace(q1->c[0],q1->c[1],q2->c[0],q2->c[1],zoom); trace(q2->c[0],q2->c[1],q3->c[0],q3->c[1],zoom); trace(q3->c[0],q3->c[1],q4->c[0],q4->c[1],zoom); trace(q4->c[0],q4->c[1],q1->c[0],q1->c[1],zoom); } /* Dessin OpenGL */ void Quadrilatere2D::drawGL(void) { glBegin(GL_LINE_LOOP); glVertex2d(q1->c[0],q1->c[1]); glVertex2d(q2->c[0],q2->c[1]); glVertex2d(q3->c[0],q3->c[1]); glVertex2d(q4->c[0],q4->c[1]); glEnd(); } /* Zoom */ void Quadrilatere2D::zoom(float zoom) { q1->c[0] *= zoom; q1->c[1] *= zoom; q2->c[0] *= zoom; q2->c[1] *= zoom; q3->c[0] *= zoom; q3->c[1] *= zoom; q4->c[0] *= zoom; q4->c[1] *= zoom; } ////////////////////////////////////////////////// /* Affectation a une Position2D de la position */ /* de l'intersection entre un Segment2D */ /* et un cote du quadrilatere */ void Quadrilatere2D::affecteIntersection(Position2D *p, Segment2D *s, int cote) { double as = s->p1->c[1]-s->p2->c[1]; double bs = -(s->p1->c[0]-s->p2->c[0]); double cs = -(as*s->p1->c[0]+bs*s->p1->c[1]); double y = -(-a[cote]*cs+c[cote]*as)/(-a[cote]*bs+b[cote]*as); p->c[0] = ( as ) ? -(cs+bs*y)/as : -(c[cote]+b[cote]*y)/a[cote]; p->c[1] = y; } /* Determination de la position d'un point */ /* vis a vis d'un des 4 cotes */ /* du quadrilatere */ int Quadrilatere2D::position(Position2D *p,int cote) { return( p->c[0]*a[cote]+p->c[1]*b[cote]+c[cote] > 0.0001 ); } /* Code de Cohen-Sutherland d'une Position2D */ int Quadrilatere2D::code(Position2D *p) { int cd = 0; if ( position(p,0) ) cd += 1; if ( position(p,1) ) cd += 2; if ( position(p,2) ) cd += 4; if ( position(p,3) ) cd += 8; return(cd); } /* Clipping de Cohen-Sutherland vis a vis */ /* d'un quadrilatere suppose convexe */ int Quadrilatere2D::clip(Segment2D *s) { update(); int c1 = code(s->p1); int c2 = code(s->p2); while ( ( ( c1 != 0 ) || ( c2 != 0 ) ) && ( (c1&c2) == 0 ) ) { if ( c1 == 0 ) { { Position2D *aux = s->p1; s->p1 = s->p2; s->p2 = aux; } { int aux = c1; c1 = c2; c2 = aux; } } if ( (c1&1) != 0 ) { affecteIntersection(s->p1,s,0); } else if ( (c1&2) != 0 ) { affecteIntersection(s->p1,s,1); } else if ( (c1&4) != 0 ) { affecteIntersection(s->p1,s,2); } else { affecteIntersection(s->p1,s,3); } c1 = code(s->p1); } return(( c1 == 0 ) && ( c2 == 0 )); return(1); } ////////////////////////////////////////////////// static void calculCoefficientsDroite(double *a,double *b,double *c,Position2D *q1,Position2D *q2) { *a = q2->c[1]-q1->c[1]; *b = -(q2->c[0]-q1->c[0]); *c = -(*a*q1->c[0]+*b*q1->c[1]); }