Génération simplifiée, avec détection des motifs produits.
This commit is contained in:
parent
9d8a85afd6
commit
2db9bb222a
6
Makefile
6
Makefile
|
@ -4,7 +4,7 @@ CCWARN=-Wall -Wextra -Werror
|
|||
# -flto (nécessite GCC 4.5) -m32 ou -m64
|
||||
CFLAGS=-O0 -I. $(CCWARN)
|
||||
|
||||
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
|
||||
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
|
||||
LIBS = -lm -lGL -lGLU -lSDL -lGLEW
|
||||
EXECUTABLE = city
|
||||
|
||||
|
@ -16,9 +16,9 @@ all: $(EXECUTABLE)
|
|||
clean:
|
||||
rm -f $(EXECUTABLE) all_includes.hh.d all_includes.hh.gch all.cpp
|
||||
|
||||
$(EXECUTABLE): $(OBJECTS:.o=.cpp) all_includes.hh.gch Makefile
|
||||
$(EXECUTABLE): $(SOURCES) all_includes.hh.gch Makefile
|
||||
@:> all.cpp
|
||||
@$(foreach FILE,$(OBJECTS:.o=.cpp),echo '#include "'"$(FILE)"'"' >> all.cpp;)
|
||||
@$(foreach FILE,$(SOURCES),echo '#include "'"$(FILE)"'"' >> all.cpp;)
|
||||
$(CXX) $(LIBS) $(CFLAGS) all.cpp -o $@
|
||||
@rm all.cpp
|
||||
|
||||
|
|
|
@ -15,19 +15,20 @@ class Chose;
|
|||
#include <GL/glu.h>
|
||||
#include <GL/gl.h>
|
||||
|
||||
#include "directions.hh"
|
||||
#include "vertex.hh"
|
||||
#include "segment.hh"
|
||||
#include "triangle.hh"
|
||||
#include "directions.hh"
|
||||
#include "quad.hh"
|
||||
|
||||
#include "hash.hh"
|
||||
#include "view.hh"
|
||||
|
||||
#include "rules/chose.hh"
|
||||
#include "rules/quad.hh"
|
||||
#include "rules/batiment.hh"
|
||||
#include "rules/carrefour.hh"
|
||||
#include "rules/route.hh"
|
||||
#include "rules/rectangleroutes.hh"
|
||||
#include "rules/quadroutes.hh"
|
||||
#include "rules/quadrilatere.hh"
|
||||
#include "rules/quadcroix.hh"
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,18 +1,26 @@
|
|||
#ifndef _DIRECTIONS_HH_
|
||||
#define _DIRECTIONS_HH_
|
||||
|
||||
typedef enum Cardinal {
|
||||
enum Cardinal {
|
||||
N = 0,
|
||||
E = 1,
|
||||
S = 2,
|
||||
W = 3
|
||||
} Cardinal;
|
||||
};
|
||||
|
||||
typedef enum Coin {
|
||||
inline Cardinal operator+(Cardinal c, int i) {
|
||||
return Cardinal((int(c) + int(i)) & 3);
|
||||
}
|
||||
|
||||
enum Coin {
|
||||
NE = 0,
|
||||
SE = 1,
|
||||
SW = 2,
|
||||
NW = 3
|
||||
} Coin;
|
||||
};
|
||||
|
||||
inline Coin operator+(Coin c, int i) {
|
||||
return Coin((int(c) + int(i)) & 3);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
10
main.cpp
10
main.cpp
|
@ -1,10 +1,14 @@
|
|||
#include "all_includes.hh"
|
||||
|
||||
// TODO : split bâtiment en faces, puis en triangles.
|
||||
// TODO : probabilités des différents types de bâtiments.
|
||||
// TODO : midpoint displacement sur les probabilités des différents types de bâtiments.
|
||||
// TODO : largeur des routes : ???
|
||||
|
||||
// Quadrilatere(corner[4])
|
||||
// -> croix de routes
|
||||
// -> bâtiment
|
||||
// -> bâtiment dans le "bout" le plus "étroit", et lignes dans une seule direction dans le reste.
|
||||
|
||||
void recursiveSubdivide(Chose* c) {
|
||||
if (c->subdivide()) {
|
||||
std::vector<Chose*>::iterator it;
|
||||
|
@ -21,8 +25,8 @@ int main() {
|
|||
Vertex ne(size, size, 0);
|
||||
Vertex se(size, 0, 0);
|
||||
Vertex sw(0, 0, 0);
|
||||
Vertex nw(0, size*1.3, 0);
|
||||
Chose* c = new QuadRoutes(ne,se,sw,nw);
|
||||
Vertex nw(0, size, 0);
|
||||
Chose* c = Quadrilatere::factory(ne,se,sw,nw);
|
||||
// c->subdivide();
|
||||
recursiveSubdivide(c);
|
||||
|
||||
|
|
16
quad.cpp
Normal file
16
quad.cpp
Normal file
|
@ -0,0 +1,16 @@
|
|||
#include "all_includes.hh"
|
||||
|
||||
Quad::Quad() {}
|
||||
|
||||
Quad::Quad(Vertex ne, Vertex se, Vertex sw, Vertex nw) {
|
||||
corner[NE] = ne;
|
||||
corner[SE] = se;
|
||||
corner[SW] = sw;
|
||||
corner[NW] = 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]);
|
||||
}
|
17
quad.hh
Normal file
17
quad.hh
Normal file
|
@ -0,0 +1,17 @@
|
|||
#ifndef _QUAD_HH_
|
||||
#define _QUAD_HH_
|
||||
|
||||
#include "all_includes.hh"
|
||||
|
||||
// Quad est un quadrilatère
|
||||
class Quad {
|
||||
public:
|
||||
Vertex corner[4];
|
||||
public:
|
||||
Quad();
|
||||
Quad(Vertex ne, Vertex se, Vertex sw, Vertex nw);
|
||||
void offset(/*Cardinal*/int side, int offset);
|
||||
};
|
||||
|
||||
|
||||
#endif
|
|
@ -1,31 +0,0 @@
|
|||
#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));
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
#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
|
27
rules/quadcroix.cpp
Normal file
27
rules/quadcroix.cpp
Normal file
|
@ -0,0 +1,27 @@
|
|||
#include "all_includes.hh"
|
||||
|
||||
QuadCroix::QuadCroix(Vertex ne, Vertex se, Vertex sw, Vertex nw) : Quadrilatere(ne, se, sw, nw) {
|
||||
}
|
||||
|
||||
bool QuadCroix::subdivide() {
|
||||
Vertex middle[4];
|
||||
Quad q[4];
|
||||
|
||||
Vertex cn = Segment(corner[NW], corner[NE]).randomPos(seed, -1, 25, 75);
|
||||
Vertex cs = Segment(corner[SE], corner[SW]).randomPos(seed, -2, 25, 75);
|
||||
Vertex c = Segment(cn, cs).randomPos(seed, -3, 25, 75);
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
middle[N+i] = Segment(corner[NW+i], corner[NE+i]).randomPos(seed, i, 25, 75);
|
||||
}
|
||||
for (int i = 0; i < 4; i++) {
|
||||
q[i] = Quad(corner[NE+i], middle[E+i], c, middle[N+i]);
|
||||
q[i].offset(W,-hrw); q[i].offset(S,-hrw);
|
||||
}
|
||||
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]));
|
||||
}
|
||||
return true;
|
||||
}
|
16
rules/quadcroix.hh
Normal file
16
rules/quadcroix.hh
Normal file
|
@ -0,0 +1,16 @@
|
|||
#ifndef _RULES_QUAD_CROIX_HH_
|
||||
#define _RULES_QUAD_CROIX_HH_
|
||||
|
||||
#include "all_includes.hh"
|
||||
|
||||
// Quad est un quadrilatère
|
||||
class QuadCroix : public Quadrilatere {
|
||||
private:
|
||||
static const int hrw = 250; // half road width : 2,50m.
|
||||
public:
|
||||
QuadCroix(Vertex ne, Vertex se, Vertex sw, Vertex nw);
|
||||
virtual bool subdivide();
|
||||
};
|
||||
|
||||
|
||||
#endif
|
32
rules/quadrilatere.cpp
Normal file
32
rules/quadrilatere.cpp
Normal file
|
@ -0,0 +1,32 @@
|
|||
#include "all_includes.hh"
|
||||
|
||||
Quadrilatere::Quadrilatere(Vertex ne, Vertex se, Vertex sw, Vertex nw) : Chose() {
|
||||
addEntropy(ne, se, sw, nw);
|
||||
corner[NE] = ne;
|
||||
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) {
|
||||
return new Batiment(ne, se, sw, nw);
|
||||
} else {
|
||||
return new QuadCroix(ne, se, sw, nw);
|
||||
}
|
||||
}
|
||||
|
||||
bool Quadrilatere::subdivide() {
|
||||
return false;
|
||||
}
|
||||
|
||||
void Quadrilatere::triangulation() {
|
||||
triangles.reserve(2);
|
||||
addTriangle(new Triangle(corner[NE], corner[NW], corner[SW], 0xc0, 0xc0, 0xc0));
|
||||
addTriangle(new Triangle(corner[SW], corner[SE], corner[NE], 0xc0, 0xc0, 0xc0));
|
||||
}
|
||||
|
17
rules/quadrilatere.hh
Normal file
17
rules/quadrilatere.hh
Normal file
|
@ -0,0 +1,17 @@
|
|||
#ifndef _RULES_QUADRILATERE_HH_
|
||||
#define _RULES_QUADRILATERE_HH_
|
||||
|
||||
#include "all_includes.hh"
|
||||
|
||||
// RectangleRoutes est un quadrilatère de routes avec des angles aux coins égaux à 90°.
|
||||
class Quadrilatere : public Chose {
|
||||
public:
|
||||
Vertex corner[4];
|
||||
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);
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,93 +0,0 @@
|
|||
#include "all_includes.hh"
|
||||
|
||||
const float QuadRoutes::cosMin = std::cos((90+maxAngleDelta)/180.f*3.14159);
|
||||
const float QuadRoutes::cosMax = std::cos((90-maxAngleDelta)/180.f*3.14159);
|
||||
|
||||
QuadRoutes::QuadRoutes(Vertex ne, Vertex se, Vertex sw, Vertex nw) : Chose(), ne(ne), se(se), sw(sw), nw(nw) {
|
||||
addEntropy(ne, se, sw, nw);
|
||||
triangulation();
|
||||
}
|
||||
|
||||
int QuadRoutes::width() { return std::abs(this->ne.x - this->sw.x); }
|
||||
|
||||
int QuadRoutes::height() { return std::abs(this->ne.y - this->sw.y); }
|
||||
|
||||
bool QuadRoutes::subdivide() {
|
||||
children.reserve(9);
|
||||
|
||||
// TODO : faire ces calculs sur des Vertex2d.
|
||||
|
||||
int slen = (se-sw).norm();
|
||||
int nlen = (ne-nw).norm();
|
||||
int minsnlen = std::min(slen,nlen);
|
||||
// constraint: min(slen, nlen) - maxdelta*2 ≥ minchildsize
|
||||
// constraint: maxdelta ≤ min(slen,nlen)/4
|
||||
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 - sxpos) / slen);
|
||||
Vertex n = (nw * nxpos / nlen) + (ne * (nlen - nxpos) / nlen);
|
||||
|
||||
int wlen = (nw-sw).norm();
|
||||
int elen = (ne-se).norm();
|
||||
int minwelen = std::min(wlen,elen);
|
||||
// constraint: min(wlen, elen) - maxdelta*2 ≥ minchildsize
|
||||
// constraint: maxdelta ≤ min(wlen,elen)/4
|
||||
int ymaxdelta = std::min(minwelen/4, (minwelen-minchildsize)/2);
|
||||
float wypos = wlen/2 + hashInRange(seed, 0, -ymaxdelta, ymaxdelta);
|
||||
float eypos = elen/2 + hashInRange(seed, 0, -ymaxdelta, ymaxdelta);
|
||||
Vertex w = (nw * wypos / wlen) + (sw * (wlen - wypos) / wlen);
|
||||
Vertex e = (ne * eypos / elen) + (se * (elen - eypos) / elen);
|
||||
|
||||
Vertex split = intersection(s,n,w,e);
|
||||
|
||||
std::cout << "n-split-e=" << cosAngle(n,split,e) << " minmax=" << cosMax << std::endl;
|
||||
|
||||
// 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(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);
|
||||
addTriangle(new Triangle(ne, nw, sw, 0xc0, 0xc0, 0xc0));
|
||||
addTriangle(new Triangle(sw, se, ne, 0xc0, 0xc0, 0xc0));
|
||||
}
|
||||
|
||||
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, se, sw, nw);
|
||||
}
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const QuadRoutes* r) {
|
||||
return os << *r;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const QuadRoutes& r) {
|
||||
return os << "QuadRoutes " << r.ne << "-" << r.sw;
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
#ifndef _RULES_QUADROUTES_HH_
|
||||
#define _RULES_QUADROUTES_HH_
|
||||
|
||||
#include "all_includes.hh"
|
||||
|
||||
// QuadRoutes est un quadrilatère de routes avec des angles aux coins entre 70° et 110°, et des côtés de longueur >= 10.
|
||||
class QuadRoutes : public Chose {
|
||||
public:
|
||||
Vertex ne;
|
||||
Vertex se;
|
||||
Vertex sw;
|
||||
Vertex nw;
|
||||
public:
|
||||
static const int hrw = 250; // half road width : 2,50m.
|
||||
static const int minchildsize = 1000;
|
||||
static const int minQuadSize = 2500;
|
||||
static const int maxAngleDelta = 20; // 90±20°
|
||||
static const float cosMin;
|
||||
static const float cosMax;
|
||||
public:
|
||||
QuadRoutes(Vertex ne, Vertex se, Vertex sw, Vertex nw);
|
||||
int width();
|
||||
int height();
|
||||
virtual bool subdivide();
|
||||
virtual void triangulation();
|
||||
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 se, Vertex sw, Vertex nw);
|
||||
};
|
||||
|
||||
|
||||
#endif
|
|
@ -1,71 +0,0 @@
|
|||
#include "all_includes.hh"
|
||||
|
||||
RectangleRoutes::RectangleRoutes(Vertex ne, Vertex sw) : Chose(), ne(ne), sw(sw) {
|
||||
addEntropy(ne, sw);
|
||||
triangulation();
|
||||
}
|
||||
|
||||
int RectangleRoutes::width() { return std::abs(this->ne.x - this->sw.x); }
|
||||
|
||||
int RectangleRoutes::height() { return std::abs(this->ne.y - this->sw.y); }
|
||||
|
||||
bool RectangleRoutes::subdivide() {
|
||||
children.reserve(9);
|
||||
int splitXMin = this->sw.x + std::max(4, this->width()*1/4);
|
||||
int splitXMax = this->ne.x - std::max(4, this->width()*1/4);
|
||||
int splitYMin = this->sw.y + std::max(4, this->height()*1/4);
|
||||
int splitYMax = this->ne.y - std::max(4, this->height()*1/4);
|
||||
Vertex split(
|
||||
hashInRange(this->seed, 0, splitXMin, splitXMax),
|
||||
hashInRange(this->seed, 1, splitYMin, splitYMax),
|
||||
0 // TODO
|
||||
);
|
||||
// TODO : addChild(…);
|
||||
addChild(new Carrefour(split + Vertex(1,1,0), split + Vertex(1,-1,0), split + Vertex(-1,-1,0), split + Vertex(-1,1,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(+1,0,0), split + Vertex(+1,+1,0), split + Vertex(-1,+1,0), roadEndN + Vertex(-1,0,0)); // N
|
||||
Route* re = new Route(roadEndE + Vertex(0,+1,0), roadEndE + Vertex(0,-1,0), split + Vertex(+1,-1,0), split + Vertex(+1,+1,0)); // E
|
||||
Route* rs = new Route(split + Vertex(+1,-1,0), roadEndS + Vertex(+1,0,0), roadEndS + Vertex(-1,0,0), split + Vertex(-1,-1,0)); // S
|
||||
Route* rw = new Route(split + Vertex(-1,+1,0), split + Vertex(-1,-1,0), roadEndW + Vertex(0,-1,0), roadEndW + Vertex(0,+1,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
|
||||
return true;
|
||||
}
|
||||
|
||||
void RectangleRoutes::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));
|
||||
}
|
||||
|
||||
Chose* RectangleRoutes::sub(Vertex ne, Vertex sw) {
|
||||
Segment rect = Segment(ne,sw);
|
||||
if (rect.width() < 10 || rect.height() < 10) {
|
||||
return new Batiment(ne, Vertex(ne.x, sw.y, 0), sw, Vertex(sw.x, ne.y, 0));
|
||||
} else {
|
||||
return new RectangleRoutes(ne, sw);
|
||||
}
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const RectangleRoutes* r) {
|
||||
return os << *r;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const RectangleRoutes& r) {
|
||||
return os << "RectangleRoutes " << r.ne << "-" << r.sw;
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
#ifndef _RULES_RECTANGLEROUTES_HH_
|
||||
#define _RULES_RECTANGLEROUTES_HH_
|
||||
|
||||
#include "all_includes.hh"
|
||||
|
||||
// RectangleRoutes est un quadrilatère de routes avec des angles aux coins égaux à 90°, et des côtés de longueur >= 10.
|
||||
class RectangleRoutes : public Chose {
|
||||
public:
|
||||
Vertex ne;
|
||||
Vertex sw;
|
||||
public:
|
||||
RectangleRoutes(Vertex ne, Vertex sw);
|
||||
int width();
|
||||
int height();
|
||||
virtual bool subdivide();
|
||||
virtual void triangulation();
|
||||
private:
|
||||
Chose* sub(Vertex ne, Vertex sw);
|
||||
public:
|
||||
friend std::ostream& operator<<(std::ostream& os, const RectangleRoutes& r);
|
||||
friend std::ostream& operator<<(std::ostream& os, const RectangleRoutes* r);
|
||||
};
|
||||
|
||||
|
||||
#endif
|
|
@ -13,3 +13,8 @@ int Segment::width() {
|
|||
int Segment::height() {
|
||||
return std::abs(u.y - v.y);
|
||||
}
|
||||
|
||||
Vertex Segment::randomPos(int seed, int n, int a, int b) {
|
||||
int pos = hashInRange(seed, n, a, b);
|
||||
return (u * pos + v * (100-pos)) / 100;
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ public:
|
|||
int length();
|
||||
int width();
|
||||
int height();
|
||||
Vertex randomPos(int seed, int n, int a, int b); // Renvoir un vertex sur le segment [u,v], à une position entre a% and b%.
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue
Block a user