www

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

commit fb381a976b84bdb7af5d5025fe91216552b87d92
parent 959a18833540426d14b8daa4e8e0004290dcdf85
Author: Yoann <yoann.b87@voila.fr>
Date:   Sun, 11 Dec 2011 14:09:37 +0100

Merge branch 'master' of https://github.com/jsmaniac/2011-m2s3-city-builder

Conflicts:
	view.cpp

Diffstat:
MMakefile | 2+-
Mall_includes.hh | 2++
Mhash.cpp | 26+++++++++++---------------
Mhash.hh | 3+--
Mmain.cpp | 2+-
Mquad.cpp | 24++++++++++++++++++++++++
Mquad.hh | 2++
Mrules/quadcroix.cpp | 2+-
Mrules/quadcroix.hh | 1-
Arules/quadherbe.cpp | 15+++++++++++++++
Arules/quadherbe.hh | 17+++++++++++++++++
Arules/quadrect.cpp | 19+++++++++++++++++++
Arules/quadrect.hh | 15+++++++++++++++
Mrules/quadrilatere.cpp | 28++++++++++++++++++++--------
Mrules/quadrilatere.hh | 2+-
Mview.cpp | 3+--
16 files changed, 131 insertions(+), 32 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,8 +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(1493,18122,2246),13,179,1000,0.6)) { +View::View(Chose* root) : root(root), camera(Camera(Vertexf(9600,10000,15300),0,179,1000,0.6)) { initWindow(); mainLoop(); }