www

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

quartier.cpp (8254B)


      1 #include "all_includes.hh"
      2 
      3 QuartierQuad::QuartierQuad(Quad _c) : Chose(), c(_c) {
      4 	addEntropy(c);
      5 }
      6 
      7 void QuartierQuad::getBoundingBoxPoints() {
      8 	addBBPoints(c, Dimensions::hauteurMaxBatiment);
      9 }
     10 
     11 void QuartierQuad::split() {
     12 	bool small = c.minLength() < 35 * 100;
     13 	bool big = (c.minLengthNS() > 100 * 100 || c.minLengthEW() > 100 * 100) && c.minLength() > 40*100 && c.maxLength() < 300*100;
     14 	bool isConcave = c.isConcave();
     15 	bool nearConcave = c.maxAngle() > Angle::d2r(160);
     16 	bool anglesOk = c.minAngle() > Angle::d2r(90-40) && c.maxAngle() < Angle::d2r(90+40);
     17 	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).
     18 	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).
     19 	bool bigPlace = c.maxLength() > Dimensions::maxRayonPlace * 4;
     20 	bool tooBigPlace = c.maxLength() > Dimensions::maxRayonPlace * 8;
     21 	if (isConcave)
     22 		concave();
     23 	else if (nearConcave)
     24 		angleAngle();
     25 	else if (big && anglesOk && proba(seed, -2, 0.25f))
     26 		longueRue();
     27 	else if (!small && !anglesOk && proba(seed, -3, 0.5f))
     28 		angleAngle();
     29 	else if (!small && !anglesOk)
     30 		angleCote();
     31 	else if (!small && (tooWideX || tooWideY))
     32 		rect();
     33 	else if (bigPlace && !tooBigPlace && proba(seed, -4, 0.4))
     34 		place();
     35 	else if (!small)
     36 		carre();
     37 	else
     38 		addChild(new BatimentQuad(c));
     39 }
     40 
     41 void QuartierQuad::triangulation() {
     42 	if (c.isConcave()) {
     43 		Quad q = c << c.concaveCorner();
     44 		triangulationConcave(Triangle(q[NE], q[SE], q[SW]));
     45 		triangulationConcave(Triangle(q[SW], q[NW], q[NE]));
     46 	} else {
     47 		Quad ci = c.insetNESW(Dimensions::largeurRoute + Dimensions::largeurTrottoir);
     48 		Quad cih = ci.offsetNormal(Dimensions::hauteurMaxBatiment);
     49 		addGPUFourQuads(c, ci, Couleurs::route);
     50 		addGPUQuad(cih, Couleurs::toit);
     51 		for (int i = 0; i < 4; i++)
     52 			addGPUQuad(Quad(ci[NE+i], ci[SE+i], cih[SE+i], cih[NE+i]), Couleurs::mur);
     53 	}
     54 }
     55 
     56 void QuartierQuad::triangulationConcave(Triangle t) {
     57 	// Même code que QuartierTri::triangulation.
     58 	Triangle ci = t.insetLTR(Dimensions::largeurRoute + Dimensions::largeurTrottoir);
     59 	Triangle cih = ci.offsetNormal(Dimensions::hauteurMaxBatiment);
     60 	addGPUThreeQuads(t, ci, Couleurs::route);
     61 	addGPUTriangle(cih, Couleurs::toit);
     62 	for (int i = 0; i < 3; i++)
     63 		addGPUQuad(Quad(ci[LEFT+i], ci[TOP+i], cih[TOP+i], cih[LEFT+i]), Couleurs::mur);
     64 }
     65 
     66 void QuartierQuad::concave() {
     67 	Quad q = c << c.concaveCorner();
     68 	addChild(new QuartierTri(Triangle(q[NE], q[SE], q[SW])));
     69 	addChild(new QuartierTri(Triangle(q[SW], q[NW], q[NE])));
     70 }
     71 
     72 void QuartierQuad::angleCote() {
     73 	Quad q = c << c.maxAngleCorner();
     74 	Vertex s = Segment(q[SE], q[SW]).randomPos(seed, 1, 0.4f, 0.6f);
     75 	Vertex w = Segment(q[SW], q[NW]).randomPos(seed, 0, 0.4f, 0.6f);
     76 	Triangle ts(q[SE], s, q[NE]);
     77 	Triangle tw(q[NE], w, q[NW]);
     78 	if (ts.minAngle() > tw.minAngle()) {
     79 		addChild(new QuartierTri(ts));
     80 		addChild(new QuartierQuad(Quad(q[NE], s, q[SW], q[NW])));
     81 	} else {
     82 		addChild(new QuartierTri(tw));
     83 		addChild(new QuartierQuad(Quad(q[NE], q[SE], q[SW], w)));
     84 	}
     85 }
     86 
     87 void QuartierQuad::angleAngle() {
     88 	Quad q = c << c.maxAngleCorner();
     89 	addChild(new QuartierTri(Triangle(q[NE], q[SE], q[SW])));
     90 	addChild(new QuartierTri(Triangle(q[SW], q[NW], q[NE])));
     91 }
     92 
     93 void QuartierQuad::rect() {
     94 	Quad q = c << c.maxLengthSide();
     95 	Vertex n = Segment(q[NW], q[NE]).randomPos(seed, 0, 1.f/3.f, 2.f/3.f);
     96 	Vertex s = Segment(q[SE], q[SW]).randomPos(seed, 1, 1.f/3.f, 2.f/3.f);
     97 
     98 	addChild(new QuartierQuad(Quad(q[NE], q[SE], s, n)));
     99 	addChild(new QuartierQuad(Quad(q[SW], q[NW], n, s)));
    100 }
    101 
    102 void QuartierQuad::carre() {
    103 	Vertex center = c.insetProportionnal(0.33f).randomPoint(seed, 0);
    104 	Vertex middle[4];
    105 	for (int i = 0; i < 4; i++)
    106 		middle[N+i] = Segment(c[NW+i], c[NE+i]).randomPos(seed, i + 1, 0.25f, 0.75f);
    107 
    108 	for (int i = 0; i < 4; i++)
    109 		addChild(new QuartierQuad(Quad(c[NE+i], middle[E+i], center, middle[N+i])));
    110 }
    111 
    112 void QuartierQuad::place() {
    113 	Vertex center = c.insetProportionnal(0.25f).randomPoint(seed, 0);
    114 	Vertex middle[4];
    115 	for (int i = 0; i < 4; i++)
    116 		middle[N+i] = Segment(c[NW+i], c[NE+i]).randomPos(seed, i + 1, 0.45f, 0.55f);
    117 
    118 	Vertex smallOcto[8];
    119 	Vertex interieur[8];
    120 	Vertex bigOcto[8];
    121 	float r = floatInRange(seed, 12345, Dimensions::minRayonPlace, Dimensions::maxRayonPlace);
    122 	float shift = std::tan(Angle::Pi/8.f) * r;
    123 	for (int i = 0; i < 4; i++) {
    124 		Quad q(c[NE+i], middle[E+i], center, middle[N+i]);
    125 		smallOcto[2*i]   = q.inset(W, shift).inset(S, r)[SW];
    126 		smallOcto[2*i+1] = q.inset(S, shift).inset(W, r)[SW];
    127 		bigOcto[2*i]     = q.inset(W, shift).inset(S, r)[NW];
    128 		bigOcto[2*i+1]   = q.inset(S, shift).inset(W, r)[SE];
    129 		Triangle t = Triangle(smallOcto[2*i+1], center, smallOcto[2*i]).inset(BASE, Dimensions::largeurRoute + Dimensions::largeurTrottoir);
    130 		interieur[2*i] = t[RIGHT];
    131 		interieur[2*i+1] = t[LEFT];
    132 	}
    133 
    134 	for (int i = 0; i < 4; i++) {
    135 		addChild(new QuartierQuad(Quad(bigOcto[2*i], smallOcto[2*i], smallOcto[((2*i-1) + 8) % 8], bigOcto[((2*i-1) + 8) % 8])));
    136 		addChild(new QuartierQuad(Quad(smallOcto[2*i+1], smallOcto[2*i], bigOcto[2*i], bigOcto[2*i+1])));
    137 		addChild(new QuartierTri(Triangle(bigOcto[2*i], c[NE+i], bigOcto[2*i+1])));
    138 	}
    139 	for (int i = 0; i < 8; i++) {
    140 		addChild(new RouteTrottoirQuad(Quad(smallOcto[i], smallOcto[(i+1)%8], interieur[(i+1)%8], interieur[i])));
    141 		addChild(new TerrainTri(Triangle(interieur[(i+1)%8], center, interieur[i])));
    142 	}
    143 }
    144 
    145 void QuartierQuad::longueRue() {
    146 	Quad q = c << c.maxLengthSide();
    147 	Vertex e = Segment(q[NE], q[SE]).randomPos(seed, 0, 1.f/3.f, 2.f/3.f);
    148 	Vertex w = Segment(q[SW], q[NW]).randomPos(seed, 1, 1.f/3.f, 2.f/3.f);
    149 	Quad qn = Quad(q[NE], e, w, q[NW]).inset(S, 7*100);
    150 	Quad qs = Quad(q[SW], w, e, q[SE]).inset(S, 7*100);
    151 
    152 	addChild(new QuartierQuad(qn));
    153 	addChild(new QuartierQuad(qs));
    154 	addChild(new BatimentQuad(Quad(qn[SE], qs[SW], qs[SE], qn[SW])));
    155 }
    156 
    157 QuartierTri::QuartierTri(Triangle _c) : Chose(), c(_c) {
    158 	addEntropy(c);
    159 }
    160 
    161 void QuartierTri::getBoundingBoxPoints() {
    162 	addBBPoints(c, Dimensions::hauteurMaxBatiment);
    163 }
    164 
    165 void QuartierTri::split() {
    166 	bool small = c.minLength() < 80 * 100;
    167 	bool big = c.maxLength() >= 150 * 100;
    168 	float minAngle = c.minAngle();
    169 	float maxAngle = c.maxAngle();
    170 	bool equilateral = maxAngle < Angle::d2r(60+15) && minAngle > Angle::d2r(60-15);
    171 	bool angleObtus = maxAngle > Angle::d2r(120);
    172 	bool angleAigu = minAngle < Angle::d2r(30);
    173 	bool anglesAcceptable = !angleAigu && !angleObtus;
    174 	if (!big && proba(seed, -1, 0.05f)) {
    175 		addChild(new BatimentTri(c));
    176 	} else if (big && anglesAcceptable) {
    177 		switch (hash2(seed, -2) % 3) {
    178 		case 0: centre(); break;
    179 		case 1: hauteur(); break;
    180 		case 2:
    181 		default: trapeze(); break;
    182 		}
    183 	} else if (!small && equilateral) {
    184 		centre();
    185 	} else if (!small && angleObtus) {
    186 		hauteur();
    187 	} else if (!small) {
    188 		trapeze();
    189 	} else {
    190 		addChild(new BatimentTri(c));
    191 	}
    192 }
    193 
    194 void QuartierTri::triangulation() {
    195 	Triangle ci = c.insetLTR(Dimensions::largeurRoute + Dimensions::largeurTrottoir);
    196 	Triangle cih = ci.offsetNormal(Dimensions::hauteurMaxBatiment);
    197 	addGPUThreeQuads(c, ci, Couleurs::route);
    198 	addGPUTriangle(cih, Couleurs::toit);
    199 	for (int i = 0; i < 3; i++)
    200 		addGPUQuad(Quad(ci[LEFT+i], ci[TOP+i], cih[TOP+i], cih[LEFT+i]), Couleurs::mur);
    201 }
    202 
    203 void QuartierTri::centre() {
    204 	Vertex center = c.insetProportionnal(0.3f).randomPoint(seed, 0);
    205 	Vertex edge[3];
    206 	for (int i = 0; i < 3; i++)
    207 		edge[LEFTSIDE+i] = Segment(c[LEFT+i], c[TOP+i]).randomPos(seed, i+1, 1.f/3.f, 2.f/3.f);
    208 
    209 	for (int i = 0; i < 3; i++)
    210 		addChild(new QuartierQuad(Quad(c[TOP+i], edge[RIGHTSIDE+i], center, edge[LEFTSIDE+i])));
    211 }
    212 
    213 void QuartierTri::hauteur() {
    214 	Triangle t = c << c.maxAngleCorner();
    215 	Vertex opposite = Segment(t[TOP], t[RIGHT]).randomPos(seed, 0, 1.f/3.f, 2.f/3.f);
    216 
    217 	addChild(new QuartierTri(Triangle(t[TOP], opposite, t[LEFT])));
    218 	addChild(new QuartierTri(Triangle(t[LEFT], opposite, t[RIGHT])));
    219 }
    220 
    221 void QuartierTri::trapeze() {
    222 	Triangle t = c << c.minAngleCorner();
    223 	Vertex left = Segment(t[LEFT], t[TOP]).randomPos(seed, 0, 1.f/3.f, 2.f/3.f);
    224 	Vertex base = Segment(t[RIGHT], t[LEFT]).randomPos(seed, 1, 1.f/3.f, 2.f/3.f);
    225 
    226 	addChild(new QuartierTri(Triangle(base, t[LEFT], left)));
    227 	addChild(new QuartierQuad(Quad(base, left, t[TOP], t[RIGHT])));
    228 }