www

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

commit d84338912130e13f747cf3a752e73256013012a8
parent 9036e2dea0b40eac2c4d07152ca076a692dd547f
Author: Georges Dupéron <jahvascriptmaniac+github@free.fr>
Date:   Sat,  3 Dec 2011 19:39:28 +0100

QuadRoutes marche, il faut juste pouvoir déplacer un peu les vertex NESW en gardant les contraintes d'angles valides.

Diffstat:
M.gitignore | 10+++-------
MMakefile | 26+++++++++++++-------------
MREADME.markdown | 4++--
Mall_includes.hh | 3+++
Mdirections.hh | 8++++----
Mmain.cpp | 3++-
Mrules/carrefour.cpp | 2+-
Arules/quad.cpp | 31+++++++++++++++++++++++++++++++
Arules/quad.hh | 22++++++++++++++++++++++
Mrules/quadroutes.cpp | 70++++++++++++++++++++++++++++++----------------------------------------
Mrules/quadroutes.hh | 2+-
Mrules/route.cpp | 4+---
Mvertex.cpp | 27++++++++++++++++++++++-----
Mvertex.hh | 3+++
Mview.cpp | 6++++--
15 files changed, 142 insertions(+), 79 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -1,8 +1,4 @@ -simple-terrain -display -roam -roads city -*.o -*.d -.*.d +all.cpp +all_includes.hh.d +all_includes.hh.gch diff --git a/Makefile b/Makefile @@ -2,27 +2,27 @@ CXX=g++ # -ansi -pedantic -Wconversion CCWARN=-Wall -Wextra -Werror # -flto (nécessite GCC 4.5) -m32 ou -m64 -CFLAGS=-O3 -g3 -I. $(CCWARN) +CFLAGS=-O0 -I. $(CCWARN) -OBJECTS = main.o view.o hash.o segment.o vertex.o triangle.o rules/chose.o rules/rectangleroutes.o rules/quadroutes.o rules/route.o rules/carrefour.o rules/batiment.o +OBJECTS = main.o view.o hash.o segment.o vertex.o triangle.o rules/chose.o rules/rectangleroutes.o rules/quad.o rules/quadroutes.o rules/route.o rules/carrefour.o rules/batiment.o LIBS = -lm -lGL -lGLU -lSDL -lGLEW EXECUTABLE = city -.PHONY: test -test: all - ./$(EXECUTABLE) - .PHONY: all all: $(EXECUTABLE) + ./$(EXECUTABLE) .PHONY: clean clean: - rm -f $(EXECUTABLE) $(OBJECTS) $(OBJECTS:.o=.d) - -$(EXECUTABLE): $(OBJECTS) - $(CXX) $(LIBS) $^ -o $@ + rm -f $(EXECUTABLE) all_includes.hh.d all_includes.hh.gch all.cpp --include $(OBJECTS:.o=.d) +$(EXECUTABLE): $(OBJECTS:.o=.cpp) all_includes.hh.gch Makefile + @:> all.cpp + @$(foreach FILE,$(OBJECTS:.o=.cpp),echo '#include "'"$(FILE)"'"' >> all.cpp;) + $(CXX) $(LIBS) $(CFLAGS) all.cpp -o $@ + @rm all.cpp -%.o: %.cpp Makefile - $(CXX) -MMD -MF $(@:.o=.d) -c $< $(CFLAGS) -o $@ +-include all_includes.hh.d +all_includes.hh.d: +all_includes.hh.gch: all_includes.hh Makefile + $(CXX) $(CFLAGS) -MMD -MF all_includes.hh.d all_includes.hh -o all_includes.hh.gch diff --git a/README.markdown b/README.markdown @@ -1,8 +1,8 @@ Minimal requirements ==================== -* imagemagick -* gcc +* g++ +* GNU make How to test this program ? ========================== diff --git a/all_includes.hh b/all_includes.hh @@ -1,6 +1,8 @@ #ifndef _ALL_INCLUDES_HH_ #define _ALL_INCLUDES_HH_ +typedef long long int64; + class Chose; #include <iostream> @@ -21,6 +23,7 @@ class Chose; #include "view.hh" #include "rules/chose.hh" +#include "rules/quad.hh" #include "rules/batiment.hh" #include "rules/carrefour.hh" #include "rules/route.hh" diff --git a/directions.hh b/directions.hh @@ -1,18 +1,18 @@ #ifndef _DIRECTIONS_HH_ #define _DIRECTIONS_HH_ -typedef enum Cardinaux { +typedef enum Cardinal { N = 0, E = 1, S = 2, W = 3 -} Cardinaux; +} Cardinal; -typedef enum Diagonales { +typedef enum Coin { NE = 0, SE = 1, SW = 2, NW = 3 -} Diagonales; +} Coin; #endif diff --git a/main.cpp b/main.cpp @@ -16,11 +16,12 @@ void recursiveSubdivide(Chose* c) { int main() { // Générer une tile de base + std::cout << "Initial seed = " << Chose::initialSeed << std::endl; int size = 20000; Vertex ne(size, size, 0); Vertex se(size, 0, 0); Vertex sw(0, 0, 0); - Vertex nw(0, size, 0); + Vertex nw(0, size*2, 0); Chose* c = new QuadRoutes(ne,se,sw,nw); // c->subdivide(); recursiveSubdivide(c); diff --git a/rules/carrefour.cpp b/rules/carrefour.cpp @@ -1,4 +1,4 @@ -#include "carrefour.hh" +#include "all_includes.hh" Carrefour::Carrefour(Vertex ne, Vertex se, Vertex sw, Vertex nw) : Chose(), ne(ne), se(se), sw(sw), nw(nw) { addEntropy(ne,se,sw,nw); diff --git a/rules/quad.cpp b/rules/quad.cpp @@ -0,0 +1,31 @@ +#include "all_includes.hh" + +Quad::Quad(Vertex ne, Vertex se, Vertex sw, Vertex nw) : Chose(), ne(ne), se(se), sw(sw), nw(nw) { + addEntropy(ne,se,sw,nw); + // triangulation(); +} + +Vertex& Quad::corner(Coin corner, int rotation) { + switch ((corner + rotation) & 3) { + case NE: return ne; + case SE: return se; + case SW: return sw; + default: return nw; + } +} + +void Quad::offset(/*Cardinal*/int side, int offset) { + Vertex voffset = (corner(NE,side)-corner(NW,side)).perpendicular().setNorm(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)); +} + +bool Quad::subdivide() { + return false; +} + +void Quad::triangulation() { + triangles.reserve(2); + addTriangle(new Triangle(ne, nw, sw, 0xc0, 0xc0, 0xc0)); + addTriangle(new Triangle(sw, se, ne, 0xc0, 0xc0, 0xc0)); +} diff --git a/rules/quad.hh b/rules/quad.hh @@ -0,0 +1,22 @@ +#ifndef _RULES_QUAD_HH_ +#define _RULES_QUAD_HH_ + +#include "all_includes.hh" + +// Quad est un quadrilatère +class Quad : public Chose { +public: + Vertex ne; + Vertex se; + Vertex sw; + Vertex nw; +public: + Quad(Vertex ne, Vertex se, Vertex sw, Vertex nw); + virtual bool subdivide(); + virtual void triangulation(); + void offset(/*Cardinal*/int side, int n); + Vertex& corner(Coin corner, int rotation); +}; + + +#endif diff --git a/rules/quadroutes.cpp b/rules/quadroutes.cpp @@ -22,7 +22,7 @@ bool QuadRoutes::subdivide() { int xmaxdelta = std::min(minsnlen/4, (minsnlen-minchildsize)/2); float sxpos = slen/2 + hashInRange(seed, 0, -xmaxdelta, xmaxdelta); float nxpos = nlen/2 + hashInRange(seed, 0, -xmaxdelta, xmaxdelta); - Vertex s = (sw * sxpos / slen) + (se * (slen - nxpos) / slen); + Vertex s = (sw * sxpos / slen) + (se * (slen - sxpos) / slen); Vertex n = (nw * nxpos / nlen) + (ne * (nlen - nxpos) / nlen); int wlen = (nw-sw).norm(); @@ -38,54 +38,44 @@ bool QuadRoutes::subdivide() { Vertex split = intersection(s,n,w,e); - // TODO : Pour offset les points des extrémités de la route w--split : - // Vertex offset = vecteur perpendiculaire w--split, de longueur hrw. - // Projeter `offset` sur split--n, et ajouter le résultat à split. - // Projeter `offset` sur w--nw, et ajouter le résultat à w. - - // Projeter u sur v : (u scalaire v) / v.norm(). - // scalaire(u,v) = u.norm() * v.norm() * cos(angle(u,v)) - // Donc projeter u sur v : u.norm() * cos(angle(u,v)) - // TODO : comment calculer l'angle(u,v) ? + // Créer 4 quad (qne, qse, qsw, qnw), puis : + Quad q[4] = { + Quad(ne, e, split, n), + Quad(se, s, split, e), + Quad(sw, w, split, s), + Quad(nw, n, split, w), + }; + for (int c = NE; c <= NW; ++c) { + q[c].offset(W,-hrw); q[c].offset(S,-hrw); + } - addChild(new Carrefour(split + Vertex(hrw,hrw,0), split + Vertex(hrw,-hrw,0), split + Vertex(-hrw,-hrw,0), split + Vertex(-hrw,hrw,0))); - // routes au NESW du carrefour - // TODO : la plupart des zéros en z sont faux… - Vertex roadEndN(split.x, this->ne.y, 0); - Vertex roadEndE(this->ne.x, split.y, 0); - Vertex roadEndS(split.x, this->sw.y, 0); - Vertex roadEndW(this->sw.x, split.y, 0); - // TODO : addChild(…); - Route* rn = new Route(roadEndN + Vertex(+hrw,0,0), split + Vertex(+hrw,+hrw,0), split + Vertex(-hrw,+hrw,0), roadEndN + Vertex(-hrw,0,0)); // N - Route* re = new Route(roadEndE + Vertex(0,+hrw,0), roadEndE + Vertex(0,-hrw,0), split + Vertex(+hrw,-hrw,0), split + Vertex(+hrw,+hrw,0)); // E - Route* rs = new Route(split + Vertex(+hrw,-hrw,0), roadEndS + Vertex(+hrw,0,0), roadEndS + Vertex(-hrw,0,0), split + Vertex(-hrw,-hrw,0)); // S - Route* rw = new Route(split + Vertex(-hrw,+hrw,0), split + Vertex(-hrw,-hrw,0), roadEndW + Vertex(0,-hrw,0), roadEndW + Vertex(0,+hrw,0)); // W - addChild(rn); - addChild(re); - addChild(rs); - addChild(rw); - // Sous-quartiers - addChild(sub(ne, re->nw)); // sous-quartier NE - addChild(sub(re->se, rs->se)); // sous-quartier SE - addChild(sub(rs->nw, sw)); // sous-quartier SW - addChild(sub(rn->nw, rw->nw)); // sous-quartier NW + addChild(new Carrefour(q[NE].sw, q[SE].sw, q[SW].sw, q[NW].sw)); + addChild(new Route(q[NW].se, q[NE].nw, q[NE].sw, q[NW].sw)); + addChild(new Route(q[NE].se, q[SE].nw, q[SE].sw, q[NE].sw)); + addChild(new Route(q[SE].se, q[SW].nw, q[SW].sw, q[SE].sw)); + addChild(new Route(q[SW].se, q[NW].nw, q[NW].sw, q[SW].sw)); + addChild(sub(q[NE].ne, q[NE].se, q[NE].sw, q[NE].nw)); + addChild(sub(q[SE].ne, q[SE].se, q[SE].sw, q[SE].nw)); + addChild(sub(q[SW].ne, q[SW].se, q[SW].sw, q[SW].nw)); + addChild(sub(q[NW].ne, q[NW].se, q[NW].sw, q[NW].nw)); + return true; } void QuadRoutes::triangulation() { triangles.reserve(2); - Vertex nw(this->sw.x, this->ne.y, 0); - Vertex se(this->ne.x, this->sw.y, 0); - addTriangle(new Triangle(this->ne, nw, this->sw, 0xc0, 0xc0, 0xc0)); - addTriangle(new Triangle(this->sw, se, this->ne, 0xc0, 0xc0, 0xc0)); + addTriangle(new Triangle(ne, nw, sw, 0xc0, 0xc0, 0xc0)); + addTriangle(new Triangle(sw, se, ne, 0xc0, 0xc0, 0xc0)); } -Chose* QuadRoutes::sub(Vertex ne, Vertex sw) { - Segment rect = Segment(ne,sw); - if (rect.width() < minQuadSize || rect.height() < minQuadSize) { - return new Batiment(ne, Vertex(ne.x, sw.y, 0), sw, Vertex(sw.x, ne.y, 0)); +Chose* QuadRoutes::sub(Vertex ne, Vertex se, Vertex sw, Vertex nw) { + if ((ne - se).norm() < minQuadSize || + (se - sw).norm() < minQuadSize || + (sw - nw).norm() < minQuadSize || + (nw - ne).norm() < minQuadSize) { + return new Batiment(ne, se, sw, nw); } else { - return new QuadRoutes(ne, Vertex(ne.x, sw.y, 0), sw, Vertex(sw.x, ne.y, 0)); + return new QuadRoutes(ne, se, sw, nw); } } diff --git a/rules/quadroutes.hh b/rules/quadroutes.hh @@ -23,7 +23,7 @@ public: friend std::ostream& operator<<(std::ostream& os, const QuadRoutes& r); friend std::ostream& operator<<(std::ostream& os, const QuadRoutes* r); private: - Chose* sub(Vertex ne, Vertex sw); + Chose* sub(Vertex ne, Vertex se, Vertex sw, Vertex nw); }; diff --git a/rules/route.cpp b/rules/route.cpp @@ -1,6 +1,4 @@ -#include "route.hh" -#include "../vertex.hh" -#include "../directions.hh" +#include "all_includes.hh" Route::Route(Vertex ne, Vertex se, Vertex sw, Vertex nw) : Chose(), ne(ne), se(se), sw(sw), nw(nw) { triangulation(); diff --git a/vertex.cpp b/vertex.cpp @@ -11,11 +11,11 @@ Vertex intersection(Vertex a, Vertex b, Vertex c, Vertex d) { // Note : si les deux lignes sont parallèles, on risque fort // d'avoir une division par zéro. // http://en.wikipedia.org/wiki/Line-line_intersection - long long x1 = a.x; long long y1 = a.y; - long long x2 = b.x; long long y2 = b.y; - long long x3 = c.x; long long y3 = c.y; - long long x4 = d.x; long long y4 = d.y; - long long denominator = ((x1-x2)*(y3-y4) - (y1-y2)*(x3-x4)); + int64 x1 = a.x; int64 y1 = a.y; + int64 x2 = b.x; int64 y2 = b.y; + int64 x3 = c.x; int64 y3 = c.y; + int64 x4 = d.x; int64 y4 = d.y; + int64 denominator = ((x1-x2)*(y3-y4) - (y1-y2)*(x3-x4)); return Vertex( ((x1*y2-y1*x2)*(x3-x4) - (x1-x2)*(x3*y4-y3*x4)) / denominator, ((x1*y2-y1*x2)*(y3-y4) - (y1-y2)*(x3*y4-y3*x4)) / denominator, @@ -23,6 +23,23 @@ Vertex intersection(Vertex a, Vertex b, Vertex c, Vertex d) { ); } +Vertex Vertex::projectOn(Vertex v) { + // http://www.developpez.net/forums/d202580/applications/developpement-2d-3d-jeux/contribuez/faq-mat-quat-ajout-calculs-vectoriels/ + int64 scalaire = this->x*v.x + this->y*v.y; + int64 normecarre = v.norm(); + normecarre *= normecarre; + return Vertex(((int64)v.x) * scalaire / normecarre, ((int64)v.y) * scalaire / normecarre, 0); +} + +Vertex Vertex::setNorm(int n) { + int64 current = norm(); + return Vertex((int64)x * (int64)n / current, (int64)y * (int64)n / current, 0); +} + +Vertex Vertex::perpendicular() { + return Vertex(-y, x, 0); +} + 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 @@ -14,6 +14,9 @@ class Vertex { Vertex(); Vertex(int x, int y, int z); float norm(); + Vertex projectOn(Vertex v); + Vertex setNorm(int n); + Vertex perpendicular(); // Perpendiculaire 2D dans le sens contraire des aiguilles d'une montre. 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). diff --git a/view.cpp b/view.cpp @@ -1,6 +1,7 @@ #include "all_includes.hh" -View::View(Chose* root) : root(root), camera(Camera(Vertexf(1000,1000,2000),45,100,1000,0.6)) { +// 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)) { initWindow(); mainLoop(); } @@ -27,7 +28,7 @@ void View::initWindow() { float MatSpec[4] = {0.0f, 0.0f, 0.0f, 1.0f}; float MatDif[4] = {0.5f, 0.5f, 0.5f, 1.0f}; - float MatAmb[4] = {0.4f, 0.4f, 0.4f, 1.0f}; + float MatAmb[4] = {0.3f, 0.3f, 0.6f, 1.0f}; float shininess = 128.0f; glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,MatSpec); @@ -157,6 +158,7 @@ void Camera::setCamera() { void Camera::mouseMotion(const SDL_MouseMotionEvent &event) { xAngle -= event.xrel*mouseSensitivity; yAngle += event.yrel*mouseSensitivity; + xAngle = std::fmod(xAngle + 360, 360); if(yAngle > 179) yAngle = 179; else if(yAngle < 1)