From e3d4a50b4eedfd4bf4ad8db442eb864c5e9de1c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Georges=20Dup=C3=A9ron?= Date: Sun, 11 Dec 2011 15:49:27 +0100 Subject: [PATCH] =?UTF-8?q?D=C3=A9tection=20des=20angles=20des=20quadrilat?= =?UTF-8?q?=C3=A8res.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- quad.cpp | 16 ++++++++++++++++ quad.hh | 2 ++ rules/quadrilatere.cpp | 23 ++++++++++++++--------- triangle.cpp | 26 ++++++++++++++++++++------ triangle.hh | 7 +++++-- vertex.cpp | 4 ---- vertex.hh | 1 - 7 files changed, 57 insertions(+), 22 deletions(-) diff --git a/quad.cpp b/quad.cpp index c7d585d..2d89012 100644 --- a/quad.cpp +++ b/quad.cpp @@ -38,3 +38,19 @@ int Quad::maxLength() { ) ); } + +float Quad::minAngle() { + float a = 370; // > 360. + for (int i = 0; i < 4; i++) { + a = std::min(a, Triangle(corner[NE+i], corner[SE+i], corner[SW+i]).angle()); + } + return a; +} + +float Quad::maxAngle() { + float a = 0; + for (int i = 0; i < 4; i++) { + a = std::max(a, Triangle(corner[NE+i], corner[SE+i], corner[SW+i]).angle()); + } + return a; +} diff --git a/quad.hh b/quad.hh index e868165..1759855 100644 --- a/quad.hh +++ b/quad.hh @@ -13,6 +13,8 @@ public: void offset(/*Cardinal*/int side, int offset); int minLength(); int maxLength(); + float minAngle(); + float maxAngle(); }; diff --git a/rules/quadrilatere.cpp b/rules/quadrilatere.cpp index d7119fd..a660f02 100644 --- a/rules/quadrilatere.cpp +++ b/rules/quadrilatere.cpp @@ -9,24 +9,29 @@ Quadrilatere::Quadrilatere(Vertex ne, Vertex se, Vertex sw, Vertex nw) : Chose() } Chose* Quadrilatere::factory(int seed, int n, Vertex ne, Vertex se, Vertex sw, Vertex nw) { - int minLength = Quad(ne,se,sw,nw).minLength(); - if (minLength < 2500 && proba(seed, n, 1, 20)) { + Quad q = Quad(ne,se,sw,nw); + int minLength = q.minLength(); + int maxLength = q.maxLength(); + float minAngle = q.minAngle(); + float maxAngle = q.maxAngle(); + if (minLength < 2500 && maxLength > 5000 && proba(seed, n, 1, 20)) { return new QuadHerbe(ne, se, sw, nw); - } else if (minLength < 2500) { // + contrainte sur les angles - // suffisemment petit pour un bâtiment + } else if (minLength < 2500 && minAngle > 50/180.f*3.1415926535 && maxAngle < 130/180.f*3.1415926535) { // + contrainte sur les angles return new Batiment(ne, se, sw, nw); - } else if (false) { + } else if (minAngle <= 50/180.f*3.1415926535 && maxAngle >= 130/180.f*3.1415926535) { // angles trop pointus - return NULL; - } else if (2*std::min(Segment(nw,ne).length(), Segment(se,sw).length()) + return new QuadHerbe(0xff, ne, se, sw, nw); + } else if (minLength > 2500 && + 2*std::min(Segment(nw,ne).length(), Segment(se,sw).length()) < std::max(Segment(ne,se).length(), Segment(sw,nw).length())) { // trop allongé (côté N ou S deux fois plus petit que le côté E ou W). return new QuadRect(nw, ne, se, sw); // TODO - } else if (2*std::min(Segment(ne,se).length(), Segment(sw,nw).length()) + } else if (minLength > 2500 && + 2*std::min(Segment(ne,se).length(), Segment(sw,nw).length()) < std::max(Segment(nw,ne).length(), Segment(se,sw).length())) { // trop allongé (côté E ou W deux fois plus petit que le côté N ou S). return new QuadRect(ne, se, sw, nw); // TODO - } else if (true) { // proche du carré + } else if (minLength > 2500) { return new QuadCroix(ne, se, sw, nw); } else { return new QuadHerbe(ne, se, sw, nw); diff --git a/triangle.cpp b/triangle.cpp index 92df43f..87026bf 100644 --- a/triangle.cpp +++ b/triangle.cpp @@ -1,8 +1,14 @@ #include "all_includes.hh" -Triangle::Triangle(Vertex v1, Vertex v2, Vertex v3, unsigned char r, unsigned char g, unsigned char b): v1(v1), v2(v2), v3(v3), r(r), g(g), b(b) { - // TODO : calcul de la normale. - normal = normalVector(v1,v2,v3); +// Triangle "rapide", sert juste aux calculs de coordonnées. Devrait +// être une superclasse de "triangle". Pour calculer le cosinus +// d'angles, on crée un objet triangle assez gros. C'est du +// gaspillage. +Triangle::Triangle(Vertex v1, Vertex v2, Vertex v3): v1(v1), v2(v2), v3(v3) { +} + +Triangle::Triangle(Vertex v1, Vertex v2, Vertex v3, unsigned char r, unsigned char g, unsigned char b) + : v1(v1), v2(v2), v3(v3), r(r), g(g), b(b), vnormal(normal(v1,v2,v3)) { } std::ostream& operator<<(std::ostream& os, const Triangle* t) { @@ -13,11 +19,19 @@ std::ostream& operator<<(std::ostream& os, const Triangle& t) { return os << "Triangle " << t.v1 << "--" << t.v2 << "--" << t.v3 << "-- cycle"; } -Vertexf Triangle::normalVector(Vertex v1, Vertex v2, Vertex v3) { +Vertexf Triangle::normal(Vertex v1, Vertex v2, Vertex v3) { Vertexf normal = (v1 - v2)*(v2 - v3); return normal / normal.norm(); } +float Triangle::cosAngle() { + return (v1-v2).cosAngle(v3-v2); +} + +float Triangle::angle() { + return std::acos(cosAngle()); +} + void Triangle::display() { // glDisable(GL_LIGHTING); // glDisable(GL_TEXTURE_2D); @@ -25,12 +39,12 @@ void Triangle::display() { // glColor3ub(255,255,0); // Vertex v = (v1 + v2 + v3) / 3; // glVertex3d(v.x,v.y,v.z); - // glVertex3d(v.x+normal.x*50,v.y+normal.y*50,v.z+normal.z*50); + // glVertex3d(v.x+vnormal.x*50,v.y+vnormal.y*50,v.z+vnormal.z*50); // glEnd( ); // glEnable(GL_LIGHTING); View::setColor(r,g,b); - glNormal3d(normal.x,normal.y,normal.z); + glNormal3d(vnormal.x,vnormal.y,vnormal.z); // glBegin(GL_TRIANGLES); glVertex3d(v1.x,v1.y,v1.z); glVertex3d(v2.x,v2.y,v2.z); diff --git a/triangle.hh b/triangle.hh index 54e4137..f4d7511 100644 --- a/triangle.hh +++ b/triangle.hh @@ -11,16 +11,19 @@ class Triangle { unsigned char r; unsigned char g; unsigned char b; - Vertexf normal; + Vertexf vnormal; public: friend std::ostream& operator<<(std::ostream& os, const Triangle* t); friend std::ostream& operator<<(std::ostream& os, const Triangle& t); + Triangle(Vertex v1, Vertex v2, Vertex v3); Triangle(Vertex v1, Vertex v2, Vertex v3, unsigned char r, unsigned char g, unsigned char b); + float cosAngle(); // cosinus de l'angle en v2. + float angle(); // angle en v2, en degrés. TODO : le calcul ne donne que des angles entre 0 et 180 ! void display(); private : - Vertexf normalVector(Vertex v1, Vertex v2, Vertex v3); + Vertexf normal(Vertex v1, Vertex v2, Vertex v3); }; #endif diff --git a/vertex.cpp b/vertex.cpp index 4723cd7..0ab77a0 100644 --- a/vertex.cpp +++ b/vertex.cpp @@ -45,10 +45,6 @@ float Vertex::cosAngle(Vertex v) { return ((double)(this->x*v.x + this->y*v.y)) / (((double)norm())*((double)v.norm())); } -float cosAngle(Vertex u, Vertex v, Vertex w) { - return (u-v).cosAngle(w-v); -} - Vertex::operator Vertexf() { return Vertexf(x,y,z); } std::ostream& operator<<(std::ostream& os, const Vertex& v) { diff --git a/vertex.hh b/vertex.hh index af8cd6f..1e26537 100644 --- a/vertex.hh +++ b/vertex.hh @@ -18,7 +18,6 @@ class Vertex { Vertex setNorm(int n); Vertex perpendicular(); // Perpendiculaire 2D dans le sens contraire des aiguilles d'une montre. float cosAngle(Vertex v); // cosinus de l'angle entre this et v. - friend float cosAngle(Vertex u, Vertex v, Vertex w); static Vertex fromSpherical(float r, float xAngle, float yAngle); friend Vertex intersection(Vertex a, Vertex b, Vertex c, Vertex d); // Intersection entre (a,b) et (c,d).