Détection des angles des quadrilatères.

This commit is contained in:
Georges Dupéron 2011-12-11 15:49:27 +01:00
parent e73ea9b7ec
commit e3d4a50b4e
7 changed files with 57 additions and 22 deletions

View File

@ -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;
}

View File

@ -13,6 +13,8 @@ public:
void offset(/*Cardinal*/int side, int offset); void offset(/*Cardinal*/int side, int offset);
int minLength(); int minLength();
int maxLength(); int maxLength();
float minAngle();
float maxAngle();
}; };

View File

@ -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) { Chose* Quadrilatere::factory(int seed, int n, Vertex ne, Vertex se, Vertex sw, Vertex nw) {
int minLength = Quad(ne,se,sw,nw).minLength(); Quad q = Quad(ne,se,sw,nw);
if (minLength < 2500 && proba(seed, n, 1, 20)) { 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); return new QuadHerbe(ne, se, sw, nw);
} else if (minLength < 2500) { // + contrainte sur les angles } else if (minLength < 2500 && minAngle > 50/180.f*3.1415926535 && maxAngle < 130/180.f*3.1415926535) { // + contrainte sur les angles
// suffisemment petit pour un bâtiment
return new Batiment(ne, se, sw, nw); 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 // angles trop pointus
return NULL; return new QuadHerbe(0xff, ne, se, sw, nw);
} else if (2*std::min(Segment(nw,ne).length(), Segment(se,sw).length()) } 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())) { < 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). // 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 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())) { < 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). // 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 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); return new QuadCroix(ne, se, sw, nw);
} else { } else {
return new QuadHerbe(ne, se, sw, nw); return new QuadHerbe(ne, se, sw, nw);

View File

@ -1,8 +1,14 @@
#include "all_includes.hh" #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) { // Triangle "rapide", sert juste aux calculs de coordonnées. Devrait
// TODO : calcul de la normale. // être une superclasse de "triangle". Pour calculer le cosinus
normal = normalVector(v1,v2,v3); // 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) { 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"; 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); Vertexf normal = (v1 - v2)*(v2 - v3);
return normal / normal.norm(); return normal / normal.norm();
} }
float Triangle::cosAngle() {
return (v1-v2).cosAngle(v3-v2);
}
float Triangle::angle() {
return std::acos(cosAngle());
}
void Triangle::display() { void Triangle::display() {
// glDisable(GL_LIGHTING); // glDisable(GL_LIGHTING);
// glDisable(GL_TEXTURE_2D); // glDisable(GL_TEXTURE_2D);
@ -25,12 +39,12 @@ void Triangle::display() {
// glColor3ub(255,255,0); // glColor3ub(255,255,0);
// Vertex v = (v1 + v2 + v3) / 3; // Vertex v = (v1 + v2 + v3) / 3;
// glVertex3d(v.x,v.y,v.z); // 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( ); // glEnd( );
// glEnable(GL_LIGHTING); // glEnable(GL_LIGHTING);
View::setColor(r,g,b); View::setColor(r,g,b);
glNormal3d(normal.x,normal.y,normal.z); glNormal3d(vnormal.x,vnormal.y,vnormal.z);
// glBegin(GL_TRIANGLES); // glBegin(GL_TRIANGLES);
glVertex3d(v1.x,v1.y,v1.z); glVertex3d(v1.x,v1.y,v1.z);
glVertex3d(v2.x,v2.y,v2.z); glVertex3d(v2.x,v2.y,v2.z);

View File

@ -11,16 +11,19 @@ class Triangle {
unsigned char r; unsigned char r;
unsigned char g; unsigned char g;
unsigned char b; unsigned char b;
Vertexf normal; Vertexf vnormal;
public: public:
friend std::ostream& operator<<(std::ostream& os, const Triangle* t); friend std::ostream& operator<<(std::ostream& os, const Triangle* t);
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); 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(); void display();
private : private :
Vertexf normalVector(Vertex v1, Vertex v2, Vertex v3); Vertexf normal(Vertex v1, Vertex v2, Vertex v3);
}; };
#endif #endif

View File

@ -45,10 +45,6 @@ float Vertex::cosAngle(Vertex v) {
return ((double)(this->x*v.x + this->y*v.y)) / (((double)norm())*((double)v.norm())); 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); } Vertex::operator Vertexf() { return Vertexf(x,y,z); }
std::ostream& operator<<(std::ostream& os, const Vertex& v) { std::ostream& operator<<(std::ostream& os, const Vertex& v) {

View File

@ -18,7 +18,6 @@ class Vertex {
Vertex setNorm(int n); Vertex setNorm(int n);
Vertex perpendicular(); // Perpendiculaire 2D dans le sens contraire des aiguilles d'une montre. 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. 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); 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). friend Vertex intersection(Vertex a, Vertex b, Vertex c, Vertex d); // Intersection entre (a,b) et (c,d).