Correction de Triangle::inset() . Amélioration des tailles des éléments générés.

This commit is contained in:
Georges Dupéron 2012-01-10 20:12:47 +01:00
parent 90a6202619
commit b1fd8eb299
11 changed files with 182 additions and 34 deletions

View File

@ -54,8 +54,9 @@ class Chose;
#include "rules/quartier/quartiertritrapeze.hh"
#include "rules/quartier/quartiertricentre.hh"
#include "rules/route/routetrottoirquad.hh"
#include "rules/route/routetrottoirtri.hh"
#include "rules/route/routequadchaussee.hh"
#include "rules/route/trottoirquadnormal.hh"
#include "rules/terrain/terrainquadherbe.hh"

View File

@ -12,10 +12,12 @@ Quad::Quad(Vertex ne, Vertex se, Vertex sw, Vertex nw) {
Quad Quad::inset(Cardinal side, float offset) const {
Quad q = (*this) << int(side);
Vertex offsetDirection = Triangle(q[NE], q[NW], q[NW] + q.normal()).normal();
float distE = offset / offsetDirection.cosAngle(q[SE] - q[NE]);
float distW = offset / offsetDirection.cosAngle(q[SW] - q[NW]);
q[NE] = q[NE] + (q[SE] - q[NE]).setNorm(distE);
q[NW] = q[NW] + (q[SW] - q[NW]).setNorm(distW);
Vertex e = q[SE] - q[NE];
Vertex w = q[SW] - q[NW];
float distE = offset / offsetDirection.cosAngle(e);
float distW = offset / offsetDirection.cosAngle(w);
q[NE] = q[NE] + e.setNorm(distE);
q[NW] = q[NW] + w.setNorm(distW);
return q >> int(side);
}

View File

@ -36,10 +36,16 @@ float Triangle::maxLength() const {
return std::max(std::max((c[LEFT] - c[TOP]).norm(), (c[TOP] - c[RIGHT]).norm()), (c[RIGHT] - c[LEFT]).norm());
}
Triangle Triangle::inset(CoteTriangle side, float offset) const {
Quad q = Quad(c[RIGHT + side], c[LEFT + side], c[TOP + side], c[RIGHT + side]);
q = q.inset(S, offset);
return (Triangle(q[SE], q[SW], q[NW]) >> side);
Triangle Triangle::inset(CoteTriangle side, float offset) const {
Triangle t = (*this) << int(side);
Vertex offsetDirection = Triangle(t[TOP], t[LEFT], t[LEFT] + t.normal()).normal();
Vertex rightside = t[RIGHT] - t[TOP];
Vertex base = t[RIGHT] - t[LEFT];
float distTR = offset / offsetDirection.cosAngle(rightside);
float distLR = offset / offsetDirection.cosAngle(base);
t[TOP] = t[TOP] + rightside.setNorm(distTR);
t[LEFT] = t[LEFT] + base.setNorm(distLR);
return t >> int(side);
}
Triangle Triangle::insetLTR(float offset) const {

View File

@ -13,19 +13,9 @@ bool BatimentQuad::split() {
if(proba(seed, 0, 1, 10)) {
addChild(new BatimentQuadMaisonPont(c,800));
} else {
float th = 20; // Terrain height.
Quad qtrottoir = c.insetNESW(250);
Quad qmaison = qtrottoir.insetNESW(140);
addChild(new BatimentQuadJardin(c));
for (int i = 0; i <4; i++) {
addChild(new RouteQuadChaussee(Quad(c[NE+i],c[SE+i],qtrottoir[SE+i],qtrottoir[NE+i])));
addChild(new TrottoirQuadNormal(Quad(qtrottoir[NE+i],qtrottoir[SE+i],qmaison[SE+i],qmaison[NE+i]),th));
}
Quad qhmaison = qmaison + Vertex(0,0,th);
addChild(new BatimentQuadJardin(qhmaison));
addChild(new BatimentQuadMaison(qhmaison.inset(N,400)));
addChild(new BatimentQuadMaison(c.inset(N,400)));
}
return true;
}

View File

@ -42,10 +42,9 @@ void BatimentTri::triangulation() {
float h = floatInRange(seed,1,minHeight,maxHeight);
// float htoit = hashInRange(seed,2,minHeight/2,maxHeight/2);
// addGPUOcto(c, c + Vertex(0,0,h + htoit), 0xFF, 0xFF, 0x00);
Triangle ch = c + Vertex(0,0,h);
addGPUTriangle(c[LEFT], c[TOP], c[RIGHT], 0xFF, 0xFF, 0x00);
addGPUTriangle(ch[LEFT], ch[TOP], ch[RIGHT], 0xFF, 0xFF, 0x00);
addGPUTriangle(c, 0xFF, 0xFF, 0x00);
addGPUTriangle(ch, 0xFF, 0xFF, 0x00);
for (int i = 0; i < 3; i++)
addGPUQuad(c[LEFT+i], c[TOP+i], ch[TOP+i], ch[LEFT+i], 0xFF, 0xFF, 0x00);
}

View File

@ -10,16 +10,16 @@ void QuartierQuad::getBoundingBoxPoints() {
}
Chose* QuartierQuad::factory(int seed, int n, Quad c) {
bool small = c.minLength() < 2500;
bool big = c.maxLength() >= 5000;
bool small = c.minLength() < 3500;
bool big = c.maxLength() >= 6000;
bool anglesAcceptable = c.minAngle() > Angle::d2r(90-60) && c.maxAngle() < Angle::d2r(90+60);
bool anglesOk = c.minAngle() > Angle::d2r(90-40) && c.maxAngle() < Angle::d2r(90+40);
bool tooWideX = c.minLengthEW() * 2 < c.maxLengthNS(); // trop allongé (côté E ou W deux fois plus petit que le côté N ou S).
bool tooWideY = c.minLengthNS() * 2 < c.maxLengthEW(); // trop allongé (côté N ou S deux fois plus petit que le côté E ou W).
if (!big && proba(seed, n, 1, 20)) {
return new TerrainQuadHerbe(c);
return new RouteTrottoirQuad(c);
} else if (small && anglesAcceptable) {
return new BatimentQuad(c);
return new RouteTrottoirQuad(c);
} else if (!small && !anglesOk) {
return new QuartierQuadAngle(c);
} else if (!small && tooWideY) {
@ -29,7 +29,7 @@ Chose* QuartierQuad::factory(int seed, int n, Quad c) {
} else if (!small) {
return new QuartierQuadCarre(c);
} else {
return new TerrainQuadHerbe(c);
return new RouteTrottoirQuad(c);
}
}

View File

@ -11,21 +11,27 @@ void QuartierTri::getBoundingBoxPoints() {
Chose* QuartierTri::factory(int seed, int n, Triangle c) {
bool small = c.minLength() < 2500;
bool big = c.maxLength() >= 5000;
bool big = c.maxLength() >= 6000;
bool verybig = c.maxLength() >= 20000;
if (small && !big) {
return new BatimentTri(c);
} else if (big) {
return new RouteTrottoirTri(c);
} else if (verybig) {
int choice = hash2(seed, n) % 3;
if (choice == 0) {
// TODO : condition : générer seulement si les 3 angles sont proches de 60°
return new QuartierTriCentre(c);
} else if (choice == 1) {
return new QuartierTriHauteur(c);
} else {
return new QuartierTriTrapeze(c);
}
} else if (big && c.maxAngle() < 75 && c.minAngle() > 45) {
return new QuartierTriCentre(c);
} else if (big && !small) {
return new QuartierTriHauteur(c);
} else if (big && !small) {
return new QuartierTriTrapeze(c);
} else {
return new BatimentTri(c);
return new RouteTrottoirTri(c);
}
}

View File

@ -0,0 +1,49 @@
#include "all_includes.hh"
RouteTrottoirQuad::RouteTrottoirQuad(Quad _c) : Chose(), c(_c) {
addEntropy(c);
}
bool RouteTrottoirQuad::split() {
float th = 20; // Terrain height.
Quad qtrottoir = c.insetNESW(250);
Quad qinterieur = qtrottoir.insetNESW(140);
for (int i = 0; i < 4; i++) {
addChild(new RouteQuadChaussee(Quad(c[NE+i],c[SE+i],qtrottoir[SE+i],qtrottoir[NE+i])));
addChild(new TrottoirQuadNormal(Quad(qtrottoir[NE+i],qtrottoir[SE+i],qinterieur[SE+i],qinterieur[NE+i]),th));
}
addChild(factory(seed, 0, qinterieur + Vertex(0,0,th)));
return true;
}
Chose* RouteTrottoirQuad::factory(int seed, int n, Quad c) {
bool small = c.minLength() < 2500;
bool big = c.maxLength() >= 5000;
bool anglesAcceptable = c.minAngle() > Angle::d2r(90-60) && c.maxAngle() < Angle::d2r(90+60);
//bool anglesOk = c.minAngle() > Angle::d2r(90-40) && c.maxAngle() < Angle::d2r(90+40);
//bool tooWideX = c.minLengthEW() * 2 < c.maxLengthNS(); // trop allongé (côté E ou W deux fois plus petit que le côté N ou S).
//bool tooWideY = c.minLengthNS() * 2 < c.maxLengthEW(); // trop allongé (côté N ou S deux fois plus petit que le côté E ou W).
if (!big && proba(seed, n, 1, 20)) {
return new TerrainQuadHerbe(c);
} else if (small && anglesAcceptable) {
return new BatimentQuad(c);
} else {
return new TerrainQuadHerbe(c);
}
}
void RouteTrottoirQuad::triangulation() {
float h = floatInRange(seed,1,minHeight,maxHeight);
float htoit = floatInRange(seed,2,minHeight/2,maxHeight/2);
addGPUOcto(c, c + Vertex(0,0,h + htoit), 0xFF, 0xFF, 0xFF);
}
void RouteTrottoirQuad::getBoundingBoxPoints() {
addBBPoints(c);
addBBPoints(c + Vertex(0,0,maxHeight + maxHeight/2)); // TODO
}

View File

@ -0,0 +1,21 @@
#ifndef _RULES_ROUTE_ROUTETROTTOIRQUAD_HH_
#define _RULES_ROUTE_ROUTETROTTOIRQUAD_HH_
#include "all_includes.hh"
class RouteTrottoirQuad : public Chose {
private :
Quad c;
public :
static const int minHeight = 400;
static const int maxHeight = 800;
public :
RouteTrottoirQuad(Quad _c);
virtual bool split();
virtual void triangulation();
virtual void getBoundingBoxPoints();
static Chose* factory(int seed, int n, Quad c); // TODO : est-ce une factory ou non, où la met-on…
};
#endif

View File

@ -0,0 +1,53 @@
#include "all_includes.hh"
RouteTrottoirTri::RouteTrottoirTri(Triangle _c) : Chose(), c(_c) {
addEntropy(c);
}
bool RouteTrottoirTri::split() {
float th = 20; // Terrain height.
Triangle ttrottoir = c.insetLTR(250);
Triangle tinterieur = ttrottoir.insetLTR(140);
for (int i = 0; i < 3; i++) {
addChild(new RouteQuadChaussee(Quad(c[LEFT+i],c[TOP+i],ttrottoir[TOP+i],ttrottoir[LEFT+i])));
addChild(new TrottoirQuadNormal(Quad(ttrottoir[LEFT+i],ttrottoir[TOP+i],tinterieur[TOP+i],tinterieur[LEFT+i]),th));
}
addChild(factory(seed, 0, tinterieur + Vertex(0,0,th)));
return true;
}
Chose* RouteTrottoirTri::factory(int seed, int n, Triangle c) {
bool small = c.minLength() < 2500;
bool big = c.maxLength() >= 5000;
//bool anglesAcceptable = c.minAngle() > Angle::d2r(90-60) && c.maxAngle() < Angle::d2r(90+60);
//bool anglesOk = c.minAngle() > Angle::d2r(90-40) && c.maxAngle() < Angle::d2r(90+40);
//bool tooWideX = c.minLengthEW() * 2 < c.maxLengthNS(); // trop allongé (côté E ou W deux fois plus petit que le côté N ou S).
//bool tooWideY = c.minLengthNS() * 2 < c.maxLengthEW(); // trop allongé (côté N ou S deux fois plus petit que le côté E ou W).
if (!big && proba(seed, n, 1, 20)) {
return new TerrainTriHerbe(c);
} else if (small && !big) {
return new BatimentTri(c);
} else {
return new TerrainTriHerbe(c);
}
}
void RouteTrottoirTri::triangulation() {
float h = floatInRange(seed,1,minHeight,maxHeight);
float htoit = floatInRange(seed,2,minHeight/2,maxHeight/2);
Triangle ch = c + Vertex(0,0,h + htoit);
addGPUTriangle(c, 0xFF, 0xFF, 0x00);
addGPUTriangle(ch, 0xFF, 0xFF, 0x00);
for (int i = 0; i < 3; i++)
addGPUQuad(c[LEFT+i], c[TOP+i], ch[TOP+i], ch[LEFT+i], 0xFF, 0xFF, 0x00);
}
void RouteTrottoirTri::getBoundingBoxPoints() {
addBBPoints(c);
addBBPoints(c + Vertex(0,0,maxHeight + maxHeight/2)); // TODO
}

View File

@ -0,0 +1,21 @@
#ifndef _RULES_ROUTE_ROUTETROTTOIRTRI_HH_
#define _RULES_ROUTE_ROUTETROTTOIRTRI_HH_
#include "all_includes.hh"
class RouteTrottoirTri : public Chose {
private :
Triangle c;
public :
static const int minHeight = 400;
static const int maxHeight = 800;
public :
RouteTrottoirTri(Triangle _c);
virtual bool split();
virtual void triangulation();
virtual void getBoundingBoxPoints();
static Chose* factory(int seed, int n, Triangle c); // TODO : est-ce une factory ou non, où la met-on…
};
#endif