commit 5999f56cdc1495e8e2b418d05e2024cb95ca3496
parent 2db9bb222ae7e3981f40bd674bb55b09cfdcd827
Author: Georges Dupéron <jahvascriptmaniac+github@free.fr>
Date: Sun, 11 Dec 2011 12:34:51 +0100
Ajout de QuadHerbe et QuadRect.
Diffstat:
16 files changed, 131 insertions(+), 31 deletions(-)
diff --git a/Makefile b/Makefile
@@ -4,7 +4,7 @@ CCWARN=-Wall -Wextra -Werror
# -flto (nécessite GCC 4.5) -m32 ou -m64
CFLAGS=-O0 -I. $(CCWARN)
-SOURCES = main.cpp view.cpp hash.cpp vertex.cpp segment.cpp triangle.cpp quad.cpp rules/chose.cpp rules/quadrilatere.cpp rules/quadcroix.cpp rules/route.cpp rules/carrefour.cpp rules/batiment.cpp
+SOURCES = main.cpp view.cpp hash.cpp vertex.cpp segment.cpp triangle.cpp quad.cpp $(shell echo rules/*.cpp)
LIBS = -lm -lGL -lGLU -lSDL -lGLEW
EXECUTABLE = city
diff --git a/all_includes.hh b/all_includes.hh
@@ -30,5 +30,7 @@ class Chose;
#include "rules/route.hh"
#include "rules/quadrilatere.hh"
#include "rules/quadcroix.hh"
+#include "rules/quadrect.hh"
+#include "rules/quadherbe.hh"
#endif
diff --git a/hash.cpp b/hash.cpp
@@ -1,5 +1,14 @@
#include "all_includes.hh"
+int random_seed() {
+ static bool initialized = false;
+ if (!initialized) {
+ initialized = true;
+ srand(time(NULL));
+ }
+ return rand();
+}
+
// Ce hash donne des bons résultats sur tous les bits de l'entier
// généré (pas d'artefacts, répartition homogène des 0 et des 1).
unsigned int hash2(unsigned int a, unsigned int b) {
@@ -15,23 +24,10 @@ unsigned int hash2(unsigned int a, unsigned int b) {
return h;
}
-unsigned int hash3(unsigned int seed, int x, int y) {
- return hash2(seed,hash2(x, y));
-}
-
int hashInRange(int seed, int n, int a, int b) {
return (hash2(seed, n) % (b - a)) + a;
}
-int newSeed(int seed, int n) {
- return hash2(seed, n);
-}
-
-int random_seed() {
- static bool initialized = false;
- if (!initialized) {
- initialized = true;
- srand(time(NULL));
- }
- return rand();
+bool proba(int seed, int n, unsigned int a, unsigned int b) {
+ return ((hash2(seed, n) % b) < a);
}
diff --git a/hash.hh b/hash.hh
@@ -6,8 +6,7 @@
int random_seed();
unsigned int hash2(unsigned int a, unsigned int b);
-unsigned int hash3(unsigned int seed, int x, int y);
int hashInRange(int seed, int n, int a, int b); // Renvoie le n-ième nombre aléatoire dérivé de seed entre a et b.
-int newSeed(int seed, int n);
+bool proba(int seed, int n, unsigned int a, unsigned int b); // Renvoie vrai avec `a` fois sur `b`.
#endif
diff --git a/main.cpp b/main.cpp
@@ -26,7 +26,7 @@ int main() {
Vertex se(size, 0, 0);
Vertex sw(0, 0, 0);
Vertex nw(0, size, 0);
- Chose* c = Quadrilatere::factory(ne,se,sw,nw);
+ Chose* c = Quadrilatere::factory(Chose::initialSeed, 0, ne, se, sw, nw);
// c->subdivide();
recursiveSubdivide(c);
diff --git a/quad.cpp b/quad.cpp
@@ -14,3 +14,27 @@ void Quad::offset(/*Cardinal*/int side, int offset) {
corner[NE + side] = corner[NE + side] + voffset.projectOn(corner[NE + side]-corner[SE + side]);
corner[NW + side] = corner[NW + side] + voffset.projectOn(corner[NW + side]-corner[SW + side]);
}
+
+int Quad::minLength() {
+ return std::min(
+ std::min(
+ Segment(corner[NE],corner[SE]).length(),
+ Segment(corner[SE],corner[SW]).length()
+ ), std::min(
+ Segment(corner[SW],corner[NW]).length(),
+ Segment(corner[NW],corner[NE]).length()
+ )
+ );
+}
+
+int Quad::maxLength() {
+ return std::max(
+ std::max(
+ Segment(corner[NE],corner[SE]).length(),
+ Segment(corner[SE],corner[SW]).length()
+ ), std::max(
+ Segment(corner[SW],corner[NW]).length(),
+ Segment(corner[NW],corner[NE]).length()
+ )
+ );
+}
diff --git a/quad.hh b/quad.hh
@@ -11,6 +11,8 @@ public:
Quad();
Quad(Vertex ne, Vertex se, Vertex sw, Vertex nw);
void offset(/*Cardinal*/int side, int offset);
+ int minLength();
+ int maxLength();
};
diff --git a/rules/quadcroix.cpp b/rules/quadcroix.cpp
@@ -21,7 +21,7 @@ bool QuadCroix::subdivide() {
addChild(new Carrefour(q[0].corner[SW], q[1].corner[SW], q[2].corner[SW], q[3].corner[SW]));
for (int i = 0; i < 4; i++) {
addChild(new Route(q[NE+i].corner[NW], q[NE+i].corner[SW], q[NW+i].corner[SW], q[NW+i].corner[SE]));
- addChild(Quadrilatere::factory(q[i].corner[0], q[i].corner[1], q[i].corner[2], q[i].corner[3]));
+ addChild(Quadrilatere::factory(seed, 4+i, q[i].corner[0], q[i].corner[1], q[i].corner[2], q[i].corner[3]));
}
return true;
}
diff --git a/rules/quadcroix.hh b/rules/quadcroix.hh
@@ -12,5 +12,4 @@ public:
virtual bool subdivide();
};
-
#endif
diff --git a/rules/quadherbe.cpp b/rules/quadherbe.cpp
@@ -0,0 +1,15 @@
+#include "all_includes.hh"
+
+QuadHerbe::QuadHerbe(Vertex ne, Vertex se, Vertex sw, Vertex nw) : Quadrilatere(ne, se, sw, nw), red(0x11) {
+ triangulation();
+}
+
+QuadHerbe::QuadHerbe(int red, Vertex ne, Vertex se, Vertex sw, Vertex nw) : Quadrilatere(ne, se, sw, nw), red(red) {
+ triangulation();
+}
+
+void QuadHerbe::triangulation() {
+ triangles.reserve(2);
+ addTriangle(new Triangle(corner[NE], corner[NW], corner[SW], red, 0xaa, 0x22));
+ addTriangle(new Triangle(corner[SW], corner[SE], corner[NE], red, 0xaa, 0x22));
+}
diff --git a/rules/quadherbe.hh b/rules/quadherbe.hh
@@ -0,0 +1,17 @@
+#ifndef _RULES_QUAD_HERBE_HH_
+#define _RULES_QUAD_HERBE_HH_
+
+#include "all_includes.hh"
+
+// Quad est un quadrilatère
+class QuadHerbe : public Quadrilatere {
+private:
+ int red;
+public:
+ QuadHerbe(Vertex ne, Vertex se, Vertex sw, Vertex nw);
+ QuadHerbe(int red, Vertex ne, Vertex se, Vertex sw, Vertex nw);
+ virtual void triangulation();
+};
+
+
+#endif
diff --git a/rules/quadrect.cpp b/rules/quadrect.cpp
@@ -0,0 +1,19 @@
+#include "all_includes.hh"
+
+QuadRect::QuadRect(Vertex ne, Vertex se, Vertex sw, Vertex nw) : Quadrilatere(ne, se, sw, nw) {
+}
+
+bool QuadRect::subdivide() {
+ Vertex n = Segment(corner[NW], corner[NE]).randomPos(seed, 0, 33, 67);
+ Vertex s = Segment(corner[SE], corner[SW]).randomPos(seed, 1, 33, 67);
+
+ Quad qe = Quad(corner[NE], corner[SE], s, n);
+ Quad qw = Quad(corner[SW], corner[NW], n, s);
+ qe.offset(W,-hrw);
+ qw.offset(W,-hrw);
+
+ addChild(new Route(qe.corner[NW], qe.corner[SW], qw.corner[NW], qw.corner[SW]));
+ addChild(Quadrilatere::factory(seed, 2, qe.corner[0], qe.corner[1], qe.corner[2], qe.corner[3]));
+ addChild(Quadrilatere::factory(seed, 3, qw.corner[0], qw.corner[1], qw.corner[2], qw.corner[3]));
+ return true;
+}
diff --git a/rules/quadrect.hh b/rules/quadrect.hh
@@ -0,0 +1,15 @@
+#ifndef _RULES_QUAD_RECT_HH_
+#define _RULES_QUAD_RECT_HH_
+
+#include "all_includes.hh"
+
+// Quad est un quadrilatère
+class QuadRect : public Quadrilatere {
+private:
+ static const int hrw = 250; // half road width : 2,50m.
+public:
+ QuadRect(Vertex ne, Vertex se, Vertex sw, Vertex nw);
+ virtual bool subdivide();
+};
+
+#endif
diff --git a/rules/quadrilatere.cpp b/rules/quadrilatere.cpp
@@ -6,17 +6,30 @@ Quadrilatere::Quadrilatere(Vertex ne, Vertex se, Vertex sw, Vertex nw) : Chose()
corner[SE] = se;
corner[SW] = sw;
corner[NW] = nw;
- triangulation();
}
-Chose* Quadrilatere::factory(Vertex ne, Vertex se, Vertex sw, Vertex nw) {
- if (Segment(ne,se).length() < 2500 ||
- Segment(se,sw).length() < 2500 ||
- Segment(sw,nw).length() < 2500 ||
- Segment(nw,ne).length() < 2500) {
+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)) {
+ return new QuadHerbe(ne, se, sw, nw);
+ } else if (minLength < 2500) { // + contrainte sur les angles
+ // suffisemment petit pour un bâtiment
return new Batiment(ne, se, sw, nw);
- } else {
+ } else if (false) {
+ // angles trop pointus
+ return NULL;
+ } else if (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())
+ < 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é
return new QuadCroix(ne, se, sw, nw);
+ } else {
+ return new QuadHerbe(ne, se, sw, nw);
}
}
@@ -29,4 +42,3 @@ void Quadrilatere::triangulation() {
addTriangle(new Triangle(corner[NE], corner[NW], corner[SW], 0xc0, 0xc0, 0xc0));
addTriangle(new Triangle(corner[SW], corner[SE], corner[NE], 0xc0, 0xc0, 0xc0));
}
-
diff --git a/rules/quadrilatere.hh b/rules/quadrilatere.hh
@@ -11,7 +11,7 @@ public:
Quadrilatere(Vertex ne, Vertex se, Vertex sw, Vertex nw);
virtual bool subdivide();
virtual void triangulation();
- static Chose* factory(Vertex ne, Vertex se, Vertex sw, Vertex nw);
+ static Chose* factory(int seed, int n, Vertex ne, Vertex se, Vertex sw, Vertex nw);
};
#endif
diff --git a/view.cpp b/view.cpp
@@ -1,7 +1,7 @@
#include "all_includes.hh"
// camera(Camera(Vertexf(1000,1000,2000),45,100,1000,0.6)
-View::View(Chose* root) : root(root), camera(Camera(Vertexf(13126,19103,30539),90,179,1000,0.6)) {
+View::View(Chose* root) : root(root), camera(Camera(Vertexf(9600,10000,15300),0,179,1000,0.6)) {
initWindow();
mainLoop();
}